redworker笔记
1)redworker由dispatcher(Red_dispatcher.c)以线程的形式启动
2)red_worker_main流程
-
SPICE_GNUC_NORETURN void *red_worker_main(void *arg)
-
{
-
RedWorker *worker = spice_malloc(sizeof(RedWorker));
-
-
spice_info("begin");
-
spice_assert(MAX_PIPE_SIZE > WIDE_CLIENT_ACK_WINDOW &&
-
MAX_PIPE_SIZE > NARROW_CLIENT_ACK_WINDOW); //ensure wakeup by ack message
-
-
#if defined(RED_WORKER_STAT) || defined(COMPRESS_STAT)
-
if (pthread_getcpuclockid(pthread_self(), &clock_id)) {
-
spice_error("pthread_getcpuclockid failed");
-
}
-
#endif
-
-
//初始化worker,设置回调,内存池初始化,cache初始化等
-
red_init(worker, (WorkerInitData *)arg);
-
//初始化解压器
-
red_init_quic(worker);
-
red_init_lz(worker);
-
red_init_jpeg(worker);
-
red_init_zlib(worker);
-
worker->event_timeout = INF_EVENT_WAIT;
-
//进入循环,POLL处理事件
-
for (;;) {
-
int i, num_events;
-
-
worker->event_timeout = MIN(red_get_streams_timout(worker), worker->event_timeout);
-
num_events = poll(worker->poll_fds, MAX_EVENT_SOURCES, worker->event_timeout);
-
red_handle_streams_timout(worker);
-
-
if (worker->display_channel) {
-
/* during migration, in the dest, the display channel can be initialized
-
while the global lz data not since migrate data msg hasn't been
-
received yet */
-
red_channel_apply_clients(&worker->display_channel->common.base,
-
red_display_cc_free_glz_drawables);
-
}
-
-
worker->event_timeout = INF_EVENT_WAIT;
-
if (num_events == -1) {
-
if (errno != EINTR) {
-
spice_error("poll failed, %s", strerror(errno));
-
}
-
}
-
-
for (i = 0; i < MAX_EVENT_SOURCES; i++) {
-
/* The watch may have been removed by the watch-func from
-
another fd (ie a disconnect through the dispatcher),
-
in this case watch_func is NULL. */
-
if (worker->poll_fds[i].revents && worker->watches[i].watch_func) {
-
int events = 0;
-
if (worker->poll_fds[i].revents & POLLIN) {
-
events |= SPICE_WATCH_EVENT_READ;
-
}
-
if (worker->poll_fds[i].revents & POLLOUT) {
-
events |= SPICE_WATCH_EVENT_WRITE;
-
}
-
//dispatcher 交互
-
worker->watches[i].watch_func(worker->poll_fds[i].fd, events,
-
worker->watches[i].watch_func_opaque);
-
}
-
}
-
-
/* Clear the poll_fd for any removed watches, see the comment in
-
watch_remove for why we don't do this there. */
-
for (i = 0; i < MAX_EVENT_SOURCES; i++) {
-
if (!worker->watches[i].watch_func) {
-
worker->poll_fds[i].fd = -1;
-
}
-
}
-
-
//QXL Device 交互
-
if (worker->running) {
-
int ring_is_empty;
-
red_process_cursor(worker, MAX_PIPE_SIZE, &ring_is_empty);
-
red_process_commands(worker, MAX_PIPE_SIZE, &ring_is_empty);
-
}
-
red_push(worker);
-
}
-
abort();
-
}
参考:spice_for_newbies.pdf
阅读(531) | 评论(0) | 转发(0) |