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
发送所有来源
,我也不知道这是什么意思
可在此处找到整个源代码: