【架构分析】Weston Inside - 基础数据结构详解

Weston

Weston是Wayland compositor的参考实现,广泛应用与AGL和GENIVI 车机Linux系统,各个版本的weston代码可以在 https://github.com/wayland-project/weston 找到,架构设计分析可以参考文章 https://blog.csdn.net/fyh2003/article/details/49253713,本文旨在分析它的核心数据结构,帮助理解和看懂它的源代码

 

核心数据结构

Wayland 核心数据结构

 

#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 示意图

如上图所示,wl_container_of的作用是根据ptr指针找出包含它的父结构的指针

 

wl_list_for_each

 

有了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 list

wl_signal通过成员listener_list形成链表,wl_signal_emit通过wl_list_for_each_safe遍历整个链表中的wl_listener数据结构,调用注册到wl_signal上的notify函数

 

wl_event_loop_add 流程图

 

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的代码流程

 

wl_display_run 消息循环

 

weston主线程就是一个不断从Loop中获取event事件进行处理的循环,上图解释了该循环的代码流程

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值