diff options
author | Marc-André Lureau <marcandre.lureau@gmail.com> | 2013-09-02 18:56:41 +0200 |
---|---|---|
committer | Jonathon Jongsma <jjongsma@redhat.com> | 2015-01-09 14:21:13 -0600 |
commit | 46bc457b713cda1949ace322066d09bd8ecd33ce (patch) | |
tree | 72f1727a4067bf5ee744d79f2f87b7b8ec295ebf | |
parent | 1c7ba6a0036d051a67d76bc48703a53b5414fce6 (diff) | |
download | spice-46bc457b713cda1949ace322066d09bd8ecd33ce.tar.gz spice-46bc457b713cda1949ace322066d09bd8ecd33ce.tar.xz spice-46bc457b713cda1949ace322066d09bd8ecd33ce.zip |
server: remove worker thread creation from dispatcher
-rw-r--r-- | server/dispatcher.c | 12 | ||||
-rw-r--r-- | server/dispatcher.h | 2 | ||||
-rw-r--r-- | server/red_dispatcher.c | 21 | ||||
-rw-r--r-- | server/red_dispatcher.h | 5 | ||||
-rw-r--r-- | server/red_worker.c | 41 | ||||
-rw-r--r-- | server/red_worker.h | 5 | ||||
-rw-r--r-- | server/spice_server_utils.h | 1 |
7 files changed, 56 insertions, 31 deletions
diff --git a/server/dispatcher.c b/server/dispatcher.c index e0fda1d4..220f6e4f 100644 --- a/server/dispatcher.c +++ b/server/dispatcher.c @@ -200,6 +200,18 @@ unlock: pthread_mutex_unlock(&dispatcher->lock); } +uint32_t dispatcher_read_message(Dispatcher *dispatcher) +{ + uint32_t message; + + spice_return_val_if_fail(dispatcher, 0); + spice_return_val_if_fail(dispatcher->send_fd != -1, 0); + + xread(dispatcher->send_fd, &message, sizeof(message)); + + return message; +} + void dispatcher_register_async_done_callback( Dispatcher *dispatcher, dispatcher_handle_async_done handler) diff --git a/server/dispatcher.h b/server/dispatcher.h index edf6babe..4d413414 100644 --- a/server/dispatcher.h +++ b/server/dispatcher.h @@ -2,6 +2,7 @@ #define DISPATCHER_H #include <spice.h> +#include "spice_server_utils.h" typedef struct Dispatcher Dispatcher; @@ -43,6 +44,7 @@ struct Dispatcher { */ void dispatcher_send_message(Dispatcher *dispatcher, uint32_t message_type, void *payload); +uint32_t dispatcher_read_message(Dispatcher *dispatcher); /* * dispatcher_init diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c index f792afb2..9966f4d5 100644 --- a/server/red_dispatcher.c +++ b/server/red_dispatcher.c @@ -56,7 +56,6 @@ struct RedDispatcher { QXLWorker base; QXLInstance *qxl; Dispatcher dispatcher; - pthread_t worker_thread; uint32_t pending; int primary_active; int x_res; @@ -1066,14 +1065,10 @@ static RedChannel *red_dispatcher_cursor_channel_create(RedDispatcher *dispatche void red_dispatcher_init(QXLInstance *qxl) { RedDispatcher *red_dispatcher; - RedWorkerMessage message; WorkerInitData init_data; QXLDevInitInfo init_info; - int r; RedChannel *display_channel; RedChannel *cursor_channel; - sigset_t thread_sig_mask; - sigset_t curr_sig_mask; ClientCbs client_cbs = { NULL, }; spice_return_if_fail(qxl->st->dispatcher == NULL); @@ -1131,19 +1126,9 @@ void red_dispatcher_init(QXLInstance *qxl) num_active_workers = 1; - sigfillset(&thread_sig_mask); - sigdelset(&thread_sig_mask, SIGILL); - sigdelset(&thread_sig_mask, SIGFPE); - sigdelset(&thread_sig_mask, SIGSEGV); - pthread_sigmask(SIG_SETMASK, &thread_sig_mask, &curr_sig_mask); - if ((r = pthread_create(&red_dispatcher->worker_thread, NULL, red_worker_main, &init_data))) { - spice_error("create thread failed %d", r); - } - pthread_sigmask(SIG_SETMASK, &curr_sig_mask, NULL); - - read_message(red_dispatcher->dispatcher.send_fd, &message); - spice_assert(message == RED_WORKER_MESSAGE_READY); - + // TODO: reference and free + RedWorker *worker = red_worker_new(&init_data); + red_worker_run(worker); display_channel = red_dispatcher_display_channel_create(red_dispatcher); if (display_channel) { diff --git a/server/red_dispatcher.h b/server/red_dispatcher.h index fa75277a..43d556a1 100644 --- a/server/red_dispatcher.h +++ b/server/red_dispatcher.h @@ -50,11 +50,6 @@ static inline void write_message(int fd, RedWorkerMessage *message) xwrite(fd, message, sizeof(RedWorkerMessage)); } -static inline void read_message(int fd, RedWorkerMessage *message) -{ - xread(fd, message, sizeof(RedWorkerMessage)); -} - enum { RED_WORKER_MESSAGE_NOP, RED_WORKER_MESSAGE_UPDATE, diff --git a/server/red_worker.c b/server/red_worker.c index 566df12b..cf52777b 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -926,6 +926,7 @@ typedef struct ItemTrace { #define NUM_CURSORS 100 typedef struct RedWorker { + pthread_t thread; GMainContext *main_context; DisplayChannel *display_channel; CursorChannel *cursor_channel; @@ -12295,7 +12296,7 @@ static GSourceFuncs worker_source_funcs = { .dispatch = worker_source_dispatch, }; -static RedWorker* red_worker_new(WorkerInitData *init_data) +RedWorker* red_worker_new(WorkerInitData *init_data) { RedWorker *worker = spice_new0(RedWorker, 1); RedWorkerMessage message; @@ -12313,10 +12314,7 @@ static RedWorker* red_worker_new(WorkerInitData *init_data) if (worker->record_fd == NULL) { spice_error("failed to open recording file %s\n", record_filename); } - if (pthread_getcpuclockid(pthread_self(), &worker->record_clock_id)) { - spice_error("pthread_getcpuclockid failed"); - } - if (fwrite(header, sizeof(header), 1, worker->record_fd) != 1) { + if (fwrite(header, sizeof(header), 1, worker->record_fd) != 1) { spice_error("failed to write replay header"); } } @@ -12395,19 +12393,23 @@ static RedWorker* red_worker_new(WorkerInitData *init_data) return worker; } -SPICE_GNUC_NORETURN void *red_worker_main(void *arg) +SPICE_GNUC_NORETURN static void *red_worker_main(void *arg) { - RedWorker *worker = red_worker_new(arg); + RedWorker *worker = arg; spice_info("begin"); spice_assert(MAX_PIPE_SIZE > WIDE_CLIENT_ACK_WINDOW && MAX_PIPE_SIZE > NARROW_CLIENT_ACK_WINDOW); //ensure wakeup by ack message + // TODO: call once unconditionnally #if defined(RED_WORKER_STAT) || defined(COMPRESS_STAT) if (pthread_getcpuclockid(pthread_self(), &clock_id)) { spice_error("pthread_getcpuclockid failed"); } #endif + if (pthread_getcpuclockid(pthread_self(), &worker->record_clock_id)) { + spice_error("pthread_getcpuclockid failed"); + } GMainLoop *loop = g_main_loop_new(worker->main_context, FALSE); g_main_loop_run(loop); @@ -12416,3 +12418,28 @@ SPICE_GNUC_NORETURN void *red_worker_main(void *arg) /* FIXME: free worker, and join threads */ abort(); } + +bool red_worker_run(RedWorker *worker) +{ + uint32_t message; + sigset_t thread_sig_mask; + sigset_t curr_sig_mask; + int r; + + spice_return_val_if_fail(worker, FALSE); + spice_return_val_if_fail(!worker->thread, FALSE); + + sigfillset(&thread_sig_mask); + sigdelset(&thread_sig_mask, SIGILL); + sigdelset(&thread_sig_mask, SIGFPE); + sigdelset(&thread_sig_mask, SIGSEGV); + pthread_sigmask(SIG_SETMASK, &thread_sig_mask, &curr_sig_mask); + if ((r = pthread_create(&worker->thread, NULL, red_worker_main, worker))) { + spice_error("create thread failed %d", r); + } + pthread_sigmask(SIG_SETMASK, &curr_sig_mask, NULL); + + message = dispatcher_read_message(red_dispatcher_get_dispatcher(worker->red_dispatcher)); + + return message == RED_WORKER_MESSAGE_READY; +} diff --git a/server/red_worker.h b/server/red_worker.h index a01f6412..763cc617 100644 --- a/server/red_worker.h +++ b/server/red_worker.h @@ -38,6 +38,8 @@ enum { RED_RENDERER_LAST }; +typedef struct RedWorker RedWorker; + typedef struct WorkerInitData { struct QXLInstance *qxl; int id; @@ -57,6 +59,7 @@ typedef struct WorkerInitData { RedDispatcher *red_dispatcher; } WorkerInitData; -void *red_worker_main(void *arg); +RedWorker* red_worker_new(WorkerInitData *init_data); +bool red_worker_run(RedWorker *worker); #endif diff --git a/server/spice_server_utils.h b/server/spice_server_utils.h index 3f53ca82..939069b1 100644 --- a/server/spice_server_utils.h +++ b/server/spice_server_utils.h @@ -4,6 +4,7 @@ #include <unistd.h> #include <errno.h> #include <string.h> +#include <stdbool.h> #include "common/log.h" static inline void set_bit(int index, uint32_t *addr) |