Weston
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事件進行處理的循環,上圖解釋了該循環的代碼流程