C 理解文件描述符的Glib轮询系统

C 理解文件描述符的Glib轮询系统,c,asynchronous,glib,polling,C,Asynchronous,Glib,Polling,我在试着理解油嘴滑舌的投票系统。据我所知,轮询是一种监视文件描述符事件的技术。函数os\u host\u main\u loop\u wait在循环中运行。您可以看到它调用了glib\u pollfds\u fill、qemu\u poll\n和glib\u pollfds\u poll。我试图通过调用这些函数来理解这个循环的作用 static GArray *gpollfds; static void glib_pollfds_fill(int64_t *cur_timeout) {

我在试着理解油嘴滑舌的投票系统。据我所知,轮询是一种监视文件描述符事件的技术。函数
os\u host\u main\u loop\u wait
在循环中运行。您可以看到它调用了
glib\u pollfds\u fill
qemu\u poll\n
glib\u pollfds\u poll
。我试图通过调用这些函数来理解这个循环的作用

static GArray *gpollfds;

static void glib_pollfds_fill(int64_t *cur_timeout)
{
    GMainContext *context = g_main_context_default();
    int timeout = 0;
    int64_t timeout_ns;
    int n;

    g_main_context_prepare(context, &max_priority);

    glib_pollfds_idx = gpollfds->len;
    n = glib_n_poll_fds;
    do {
        GPollFD *pfds;
        glib_n_poll_fds = n;
        g_array_set_size(gpollfds, glib_pollfds_idx + glib_n_poll_fds);
        //Gets current index's address on gpollfds array
        pfds = &g_array_index(gpollfds, GPollFD, glib_pollfds_idx);
        //Fills gpollfds's each element (pfds) with the file descriptor to be polled
        n = g_main_context_query(context, max_priority, &timeout, pfds,
                                 glib_n_poll_fds);
        //g_main_context_query returns the number of records actually stored in fds , or, 
        //if more than n_fds records need to be stored, the number of records that need to be stored.
    } while (n != glib_n_poll_fds);

    if (timeout < 0) {
        timeout_ns = -1;
    } else {
        timeout_ns = (int64_t)timeout * (int64_t)SCALE_MS;
    }

    *cur_timeout = qemu_soonest_timeout(timeout_ns, *cur_timeout);
}
static void glib_pollfds_poll(void)
{
    GMainContext *context = g_main_context_default();
    GPollFD *pfds = &g_array_index(gpollfds, GPollFD, glib_pollfds_idx);

    if (g_main_context_check(context, max_priority, pfds, glib_n_poll_fds)) {
        g_main_context_dispatch(context);
    }
}
static int os_host_main_loop_wait(int64_t timeout)
{
    GMainContext *context = g_main_context_default();
    int ret;

    g_main_context_acquire(context);

    glib_pollfds_fill(&timeout);

    qemu_mutex_unlock_iothread();
    replay_mutex_unlock();

    ret = qemu_poll_ns((GPollFD *)gpollfds->data, gpollfds->len, timeout); //RESOLVES TO: g_poll(fds, nfds, qemu_timeout_ns_to_ms(timeout));

    replay_mutex_lock();
    qemu_mutex_lock_iothread();

    glib_pollfds_poll(); 

    g_main_context_release(context);

    return ret;
}
staticgarray*gpollfds;
静态无效glib_pollfds_fill(int64_t*cur_超时)
{
GMainContext*context=g_main_context_default();
int超时=0;
int64超时;
int n;
g_主上下文准备(上下文和最大优先级);
glib_pollfds_idx=gpollfds->len;
n=能说会道的投票;
做{
GPollFD*pfds;
能说会道的民意测验=n;
g_数组_集合_大小(gpollfds、glib_pollfds_idx+glib_n_poll_fds);
//获取gpollfds数组上当前索引的地址
pfds=&g_数组索引(gpollfds、GPollFD、glib_pollfds\u idx);
//用要轮询的文件描述符填充gpollfds的每个元素(pfds)
n=g_main_context_查询(上下文、最大优先级和超时、PFD、,
油嘴滑舌的人;
//g_main_context_查询返回实际存储在fds中的记录数,或者,
//如果需要存储多个n_fds记录,则为需要存储的记录数。
}而(n!=glib_n_poll_fds);
如果(超时<0){
超时时间=1;
}否则{
timeout\u ns=(int64\u t)timeout*(int64\u t)SCALE\u MS;
}
*cur\u timeout=qemu\u最快超时(timeout\u ns,*cur\u timeout);
}
静态void glib_pollfds_poll(void)
{
GMainContext*context=g_main_context_default();
GPollFD*pfds=&g_数组_索引(gpollfds,GPollFD,glib_pollfds_idx);
if(g_主上下文检查(上下文、最大优先级、PFD、glib_n_poll_fds)){
g_主_上下文_调度(上下文);
}
}
静态int os_主机_主循环_等待(int64超时)
{
GMainContext*context=g_main_context_default();
int ret;
g_main_context_acquire(上下文);
glib_pollfds_fill(&超时);
qemu_mutex_unlock_iothread();
重播互斥锁解锁();
ret=qemu poll_ns((GPollFD*)gpollfds->data,gpollfds->len,timeout);//解析为:g_poll(fds,nfds,qemu timeout_ns到ms(timeout));
重播互斥锁();
qemu_mutex_lock_iothread();
油嘴滑舌;
g_主上下文发布(上下文);
返回ret;
}
因此,据我所知,
g_poll
在超时的情况下轮询文件描述符数组。这意味着什么?这意味着它等待超时。如果发生了什么事情(例如,fd中有数据要读取),我不知道它会做什么

然后
glib_pollfds_poll
调用
g_main_context_check
然后
g_main_context_dispatch

根据glib的文档,
g\u main\u context\u check
所做的是:

将轮询结果传回主循环

这意味着什么

然后
g\u main\u context\u dispatch

发送所有来源

,我也不知道这是什么意思

可在此处找到整个源代码: