Я пытаюсь понять систему опроса glib. Как я понимаю, опрос - это метод отслеживания файловых дескрипторов событий. Функция os_host_main_loop_wait
выполняется в al oop. Вы можете видеть, что он вызывает glib_pollfds_fill
, qemu_poll_ns
и glib_pollfds_poll
. Я пытаюсь понять, что делает l oop, вызывая каждую из этих функций.
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;
}
Так что, как я понимаю, g_poll
опрашивает массив файловых дескрипторов с тайм-аутом. Что это означает? Это означает, что он ожидает тайм-аут. Если что-то происходит (например, в fd есть данные для чтения), я не знаю, что это делает.
Затем glib_pollfds_poll
вызывает g_main_context_check
, а затем g_main_context_dispatch
.
Согласно документации glib, g_main_context_check
делает следующее:
Передает результаты опроса обратно на главный l oop.
Что это значит?
Затем g_main_context_dispatch
отправляет все источники
, что я также не знаю, что это значит.
Весь источник можно основать здесь: https://github.com/qemu/qemu/blob/14e5526b51910efd62cd31cd95b49baca975c83f/util/main-loop.c