Weston是Wayland compositor的参考实现,广泛应用与AGL和GENIVI 车机Linux系统,各个版本的weston代码可以在 https://github.com/wayland-project/weston 找到,架构设计分析可以参考文章 https://blog.csdn.net/fyh2003/article/details/49253713,本文旨在分析它的核心数据结构,帮助理解和看懂它的源代码
#ifdef __GNUC__
#define wl_container_of(ptr, sample, member) \
(__typeof__(sample))((char *)(ptr) - \
((char *)&(sample)->member - (char *)(sample)))
#else
#define wl_container_of(ptr, sample, member) \
(void *)((char *)(ptr) - \
((char *)&(sample)->member - (char *)(sample)))
#endif
#define wl_list_for_each(pos, head, member) \
for (pos = 0, pos = wl_container_of((head)->next, pos, member); \
&pos->member != (head); \
pos = wl_container_of(pos->member.next, pos, member))
#define wl_list_for_each_safe(pos, tmp, head, member) \
for (pos = 0, tmp = 0, \
pos = wl_container_of((head)->next, pos, member), \
tmp = wl_container_of((pos)->member.next, tmp, member); \
&pos->member != (head); \
pos = tmp, \
tmp = wl_container_of(pos->member.next, tmp, member))
如上图所示,wl_container_of的作用是根据ptr指针找出包含它的父结构的指针
有了wl_container_of的基础就很容易理解wl_list_for_each的实现了,通过head->next指针找到它的父结构指针pos,然后通过pos->member->next指针循环遍历整个list上的__typeof__(pos)数据结构实例;wl_list_for_each_safe通过增加一个tmp指针防止越界作为wl_list_for_each的safe版本实现
WL_EXPORT void
wl_list_init(struct wl_list *list)
{
list->prev = list;
list->next = list;
}
WL_EXPORT void
wl_list_insert(struct wl_list *list, struct wl_list *elm)
{
elm->prev = list;
elm->next = list->next;
list->next = elm;
elm->next->prev = elm;
}
WL_EXPORT void
wl_list_remove(struct wl_list *elm)
{
elm->prev->next = elm->next;
elm->next->prev = elm->prev;
elm->next = NULL;
elm->prev = NULL;
}
wl_list_init wl_list_insert wl_list_remove 是对wl_list做双向链表的操作,大学C语音数据结构的基础内容
static inline void
wl_signal_add(struct wl_signal *signal, struct wl_listener *listener)
{
wl_list_insert(signal->listener_list.prev, &listener->link);
}
static inline struct wl_listener *
wl_signal_get(struct wl_signal *signal, void *notify)
{
struct wl_listener *l;
wl_list_for_each(l, &signal->listener_list, link)
if (l->notify == notify)
return l;
return NULL;
}
static inline void
wl_signal_emit(struct wl_signal *signal, void *data)
{
struct wl_listener *l, *next;
wl_list_for_each_safe(l, next, &signal->listener_list, link)
l->notify(l, data);
}
wl_signal通过成员listener_list形成链表,wl_signal_emit通过wl_list_for_each_safe遍历整个链表中的wl_listener数据结构,调用注册到wl_signal上的notify函数
wl_event_loop是weston的核心事件循环loop结构,wl_event_source是加入该loop等待weston处理的事件可以再细分为wl_event_source_fd wl_event_source_timer wl_event_source_signal 等事件,上图展示了如果将wl_event_source_xxx 事件加入事件循环loop的代码流程
weston主线程就是一个不断从Loop中获取event事件进行处理的循环,上图解释了该循环的代码流程