red_worker: add RED_WORKER_MESSAGE_CLOSE_WORKER message

Allows to close worker thread.
This will be used to destroy cleanly CursorChannel and
DisplayChannel.
CursorChannel and DisplayChannel are run in a different
thread. However deregistration of channels and different
steps of destruction should be done in the same thread
so this make possible to join again the 2 threads to
avoid race conditions.
For the moment there is no correct cleanup.

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Pavel Grunt <pgrunt@redhat.com>
This commit is contained in:
Frediano Ziglio 2016-11-17 17:29:51 +00:00
parent bb74d7ad47
commit afa3144de5
2 changed files with 22 additions and 2 deletions

View File

@ -116,6 +116,9 @@ enum {
RED_WORKER_MESSAGE_GL_DRAW_ASYNC,
RED_WORKER_MESSAGE_SET_VIDEO_CODECS,
/* close worker thread */
RED_WORKER_MESSAGE_CLOSE_WORKER,
RED_WORKER_MESSAGE_COUNT // LAST
};
@ -291,6 +294,9 @@ typedef struct RedWorkerMessageDriverUnload {
typedef struct RedWorkerMessageGlScanout {
} RedWorkerMessageGlScanout;
typedef struct RedWorkerMessageClose {
} RedWorkerMessageClose;
enum {
RED_DISPATCHER_PENDING_WAKEUP,
RED_DISPATCHER_PENDING_OOM,

View File

@ -85,6 +85,7 @@ struct RedWorker {
int driver_cap_monitors_config;
RedRecord *record;
GMainLoop *loop;
};
static int display_is_connected(RedWorker *worker)
@ -971,6 +972,12 @@ void handle_dev_gl_draw_async(void *opaque, void *payload)
display_channel_gl_draw(worker->display_channel, draw);
}
static void handle_dev_close(void *opaque, void *payload)
{
RedWorker *worker = opaque;
g_main_loop_quit(worker->loop);
}
static int loadvm_command(RedWorker *worker, QXLCommandExt *ext)
{
RedCursorCmd *cursor_cmd;
@ -1222,6 +1229,11 @@ static void register_callbacks(Dispatcher *dispatcher)
handle_dev_gl_draw_async,
sizeof(SpiceMsgDisplayGlDraw),
DISPATCHER_NONE);
dispatcher_register_handler(dispatcher,
RED_WORKER_MESSAGE_CLOSE_WORKER,
handle_dev_close,
sizeof(RedWorkerMessageClose),
DISPATCHER_NONE);
}
@ -1381,7 +1393,7 @@ RedWorker* red_worker_new(QXLInstance *qxl,
return worker;
}
SPICE_GNUC_NORETURN static void *red_worker_main(void *arg)
static void *red_worker_main(void *arg)
{
RedWorker *worker = arg;
@ -1393,11 +1405,13 @@ SPICE_GNUC_NORETURN static void *red_worker_main(void *arg)
red_channel_reset_thread_id(RED_CHANNEL(worker->display_channel));
GMainLoop *loop = g_main_loop_new(worker->core.main_context, FALSE);
worker->loop = loop;
g_main_loop_run(loop);
g_main_loop_unref(loop);
worker->loop = NULL;
/* FIXME: free worker, and join threads */
exit(0);
return NULL;
}
bool red_worker_run(RedWorker *worker)