summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@gmail.com>2013-09-02 18:56:41 +0200
committerJonathon Jongsma <jjongsma@redhat.com>2015-01-09 14:21:13 -0600
commit46bc457b713cda1949ace322066d09bd8ecd33ce (patch)
tree72f1727a4067bf5ee744d79f2f87b7b8ec295ebf
parent1c7ba6a0036d051a67d76bc48703a53b5414fce6 (diff)
downloadspice-46bc457b713cda1949ace322066d09bd8ecd33ce.tar.gz
spice-46bc457b713cda1949ace322066d09bd8ecd33ce.tar.xz
spice-46bc457b713cda1949ace322066d09bd8ecd33ce.zip
server: remove worker thread creation from dispatcher
-rw-r--r--server/dispatcher.c12
-rw-r--r--server/dispatcher.h2
-rw-r--r--server/red_dispatcher.c21
-rw-r--r--server/red_dispatcher.h5
-rw-r--r--server/red_worker.c41
-rw-r--r--server/red_worker.h5
-rw-r--r--server/spice_server_utils.h1
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)