ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

walyand学习笔记(九) wl_dispaly_dispatch线程安全分析

2022-02-20 16:02:52  阅读:484  来源: 互联网

标签:read wl dispatch event queue walyand display


wayland中有几个概念不太好理解,主要是围绕着wl_display_dispatch容易产生很多问题 。翻了翻源码,发现dispatch等函数基本上都是围绕着

struct wl_event_queue来进行的。

 在最早的wl_display_connect中,调用了wl_display_connect_fd;

 

 对应了struct wl_display的两个queue;

 

 对于wl_display_dispatch

WL_EXPORT int
wl_display_dispatch(struct wl_display *display)
{
    return wl_display_dispatch_queue(display, &display->default_queue);
}

然后就进入了本文的核心内容,分析一下wl_display_dispatch_queue,先贴上源码:

WL_EXPORT int
wl_display_dispatch_queue(struct wl_display *display,
              struct wl_event_queue *queue)
{
    int ret;

    if (wl_display_prepare_read_queue(display, queue) == -1)
        return wl_display_dispatch_queue_pending(display, queue);

    while (true) {
        ret = wl_display_flush(display);

        if (ret != -1 || errno != EAGAIN)
            break;

        if (wl_display_poll(display, POLLOUT) == -1) {
            wl_display_cancel_read(display);
            return -1;
        }
    }

    /* Don't stop if flushing hits an EPIPE; continue so we can read any
     * protocol error that may have triggered it. */
    if (ret < 0 && errno != EPIPE) {
        wl_display_cancel_read(display);
        return -1;
    }

    if (wl_display_poll(display, POLLIN) == -1) {
        wl_display_cancel_read(display);
        return -1;
    }

    if (wl_display_read_events(display) == -1)
        return -1;

    return wl_display_dispatch_queue_pending(display, queue);
}

 

结合下面的表格来理解这块函数的真正用意:

函数名 作用 注解
wl_display_dispatch 在display的default queue上,读取server的event,如果没有 event会阻塞在此处,直到收到event为止  线程安全
wl_display_dispatch_queue  同上,不过是可以指定一个新的event queue,而非在default queue上  
wl_display_dispatch_queue_pending  把当前pending在in queue(ring buffer)中的events 处理掉,并返回dispatch的event个数

如果没有pending的events, 会立即返回

wl_display_flush  将当前pending在out queue中的cmds全部发送给server  
wl_display_roundtrip_queue  通过wl_display_sync,告知server端,处理完所有request后,通知到client的回调,这个回调是定义在wayland-client.c中的sync_listener, server在sync ack后,这个函数才会返回  
wl_display_roundtrip  同上,只是在display的default queue上dispatch和等待ack  
wl_display_prepare_read_queue  判断指定的event queue中是否是empty,若是返回0,同时使内部的reader_counter++,否则返回-1并且设置errno为EAGAIN  
wl_display_prepare_read  同上,只是在default queue上去prepare_read_queue  
wl_display_cancel_read  会使display结构体内部维护的一个引用计数reader_counter--  
wl_display_read_events

 需要在prepare_read返回0后使用,该函数会使内部的reader_counter--,当某个线程调用该函数后,使reader_counter减为0,则触发真正的从缓冲区中读取数据,并唤醒其它阻塞在condition_wait的线程;

其它调用该函数但是没有使reader_counter减为0的调用者将进入condition_wait的状态,等待被某个wl_display_read_events或者wl_display_cancel_read来唤醒

 
     

 

 综合下来,我的理解就是:

wl_display_dispatch在wl_prepare_read 和 poll 以及 wl_display_read_events 的配合下,可以实现线程安全,即使在多线程中,也不会因为多次调用这个函数而出现问题

 

标签:read,wl,dispatch,event,queue,walyand,display
来源: https://www.cnblogs.com/Arnold-Zhang/p/15915635.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有