[Spice-devel] [PATCH spice-server 06/10] Move thread/dispatching handling to RedChannel
Frediano Ziglio
fziglio at redhat.com
Wed Mar 20 09:59:15 UTC 2019
Currently channel threading/handling is spread between RedQxl,
RedWorker and RedChannel.
Move more to RedChannel simplify RedQxl and RedWorker.
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
server/cursor-channel.c | 4 +-
server/cursor-channel.h | 4 +-
server/display-channel.c | 2 +
server/display-channel.h | 1 +
server/red-channel.c | 111 +++++++++++++++++++++++++++++--
server/red-qxl.c | 110 +-----------------------------
server/red-replay-qxl.c | 3 -
server/red-stream-device.c | 2 +-
server/red-worker.c | 133 ++++++++++---------------------------
server/red-worker.h | 46 ++-----------
10 files changed, 160 insertions(+), 256 deletions(-)
diff --git a/server/cursor-channel.c b/server/cursor-channel.c
index 4220084f..e8af01b0 100644
--- a/server/cursor-channel.c
+++ b/server/cursor-channel.c
@@ -228,7 +228,8 @@ static void cursor_channel_send_item(RedChannelClient *rcc, RedPipeItem *pipe_it
}
CursorChannel* cursor_channel_new(RedsState *server, int id,
- const SpiceCoreInterfaceInternal *core)
+ const SpiceCoreInterfaceInternal *core,
+ Dispatcher *dispatcher)
{
spice_debug("create cursor channel");
return g_object_new(TYPE_CURSOR_CHANNEL,
@@ -238,6 +239,7 @@ CursorChannel* cursor_channel_new(RedsState *server, int id,
"id", id,
"migration-flags", 0,
"handle-acks", TRUE,
+ "dispatcher", dispatcher,
NULL);
}
diff --git a/server/cursor-channel.h b/server/cursor-channel.h
index 603c2c0a..767325ea 100644
--- a/server/cursor-channel.h
+++ b/server/cursor-channel.h
@@ -21,6 +21,7 @@
#include "common-graphics-channel.h"
#include "red-parse-qxl.h"
+#include "dispatcher.h"
G_BEGIN_DECLS
@@ -57,7 +58,8 @@ GType cursor_channel_get_type(void) G_GNUC_CONST;
* CursorChannel thread.
*/
CursorChannel* cursor_channel_new(RedsState *server, int id,
- const SpiceCoreInterfaceInternal *core);
+ const SpiceCoreInterfaceInternal *core,
+ Dispatcher *dispatcher);
void cursor_channel_reset (CursorChannel *cursor);
void cursor_channel_do_init (CursorChannel *cursor);
diff --git a/server/display-channel.c b/server/display-channel.c
index e179abfd..cb052bfc 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -2227,6 +2227,7 @@ static SpiceCanvas *image_surfaces_get(SpiceImageSurfaces *surfaces, uint32_t su
DisplayChannel* display_channel_new(RedsState *reds,
QXLInstance *qxl,
const SpiceCoreInterfaceInternal *core,
+ Dispatcher *dispatcher,
int migrate, int stream_video,
GArray *video_codecs,
uint32_t n_surfaces)
@@ -2246,6 +2247,7 @@ DisplayChannel* display_channel_new(RedsState *reds,
"n-surfaces", n_surfaces,
"video-codecs", video_codecs,
"handle-acks", TRUE,
+ "dispatcher", dispatcher,
NULL);
if (display) {
display_channel_set_stream_video(display, stream_video);
diff --git a/server/display-channel.h b/server/display-channel.h
index 948018cf..f64da0bd 100644
--- a/server/display-channel.h
+++ b/server/display-channel.h
@@ -99,6 +99,7 @@ struct Drawable {
DisplayChannel* display_channel_new (RedsState *reds,
QXLInstance *qxl,
const SpiceCoreInterfaceInternal *core,
+ Dispatcher *dispatcher,
int migrate,
int stream_video,
GArray *video_codecs,
diff --git a/server/red-channel.c b/server/red-channel.c
index 1d88739e..8d05c971 100644
--- a/server/red-channel.c
+++ b/server/red-channel.c
@@ -70,6 +70,9 @@ struct RedChannelPrivate
uint32_t type;
uint32_t id;
+ /* "core" interface to register events.
+ * Can be thread specific.
+ */
SpiceCoreInterfaceInternal *core;
gboolean handle_acks;
@@ -90,12 +93,29 @@ struct RedChannelPrivate
// TODO: when different channel_clients are in different threads
// from Channel -> need to protect!
pthread_t thread_id;
+ Dispatcher *dispatcher;
RedsState *reds;
RedStatNode stat;
};
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(RedChannel, red_channel, G_TYPE_OBJECT)
+typedef struct RedMessageConnect {
+ RedChannel *channel;
+ RedClient *client;
+ RedStream *stream;
+ RedChannelCapabilities caps;
+ int migration;
+} RedMessageConnect;
+
+typedef struct RedMessageDisconnect {
+ RedChannelClient *rcc;
+} RedMessageDisconnect;
+
+typedef struct RedMessageMigrate {
+ RedChannelClient *rcc;
+} RedMessageMigrate;
+
enum {
PROP0,
PROP_SPICE_SERVER,
@@ -103,7 +123,8 @@ enum {
PROP_TYPE,
PROP_ID,
PROP_HANDLE_ACKS,
- PROP_MIGRATION_FLAGS
+ PROP_MIGRATION_FLAGS,
+ PROP_DISPATCHER,
};
static void
@@ -134,6 +155,9 @@ red_channel_get_property(GObject *object,
case PROP_MIGRATION_FLAGS:
g_value_set_uint(value, self->priv->migration_flags);
break;
+ case PROP_DISPATCHER:
+ g_value_set_object(value, self->priv->dispatcher);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
@@ -167,6 +191,12 @@ red_channel_set_property(GObject *object,
case PROP_MIGRATION_FLAGS:
self->priv->migration_flags = g_value_get_uint(value);
break;
+ case PROP_DISPATCHER:
+ if (self->priv->dispatcher) {
+ g_object_unref(self->priv->dispatcher);
+ }
+ self->priv->dispatcher = g_value_dup_object(value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
@@ -177,6 +207,7 @@ red_channel_finalize(GObject *object)
{
RedChannel *self = RED_CHANNEL(object);
+ g_clear_object(&self->priv->dispatcher);
red_channel_capabilities_reset(&self->priv->local_caps);
G_OBJECT_CLASS(red_channel_parent_class)->finalize(object);
@@ -279,6 +310,14 @@ red_channel_class_init(RedChannelClass *klass)
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
g_object_class_install_property(object_class, PROP_MIGRATION_FLAGS, spec);
+
+ spec = g_param_spec_object("dispatcher", "dispatcher",
+ "Dispatcher bound to channel thread",
+ TYPE_DISPATCHER,
+ G_PARAM_STATIC_STRINGS
+ | G_PARAM_READWRITE
+ | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property(object_class, PROP_DISPATCHER, spec);
}
static void
@@ -483,11 +522,40 @@ void red_channel_disconnect(RedChannel *channel)
red_channel_foreach_client(channel, red_channel_client_disconnect);
}
+static void handle_dispatcher_connect(void *opaque, void *payload)
+{
+ RedMessageConnect *msg = payload;
+ RedChannel *channel = msg->channel;
+
+ channel->priv->client_cbs.connect(channel, msg->client, msg->stream,
+ msg->migration, &msg->caps);
+ g_object_unref(msg->client);
+ red_channel_capabilities_reset(&msg->caps);
+}
+
void red_channel_connect(RedChannel *channel, RedClient *client,
RedStream *stream, int migration,
RedChannelCapabilities *caps)
{
- channel->priv->client_cbs.connect(channel, client, stream, migration, caps);
+ if (channel->priv->dispatcher == NULL ||
+ pthread_equal(pthread_self(), channel->priv->thread_id)) {
+ channel->priv->client_cbs.connect(channel, client, stream, migration, caps);
+ return;
+ }
+
+ RedMessageConnect payload = {0,};
+ Dispatcher *dispatcher = channel->priv->dispatcher;
+
+ // get a reference potentially the main channel can be destroyed in
+ // the main thread causing RedClient to be destroyed before using it
+ payload.channel = channel;
+ payload.client = g_object_ref(client);
+ payload.stream = stream;
+ payload.migration = migration;
+ red_channel_capabilities_init(&payload.caps, caps);
+
+ dispatcher_send_message_generic(dispatcher, handle_dispatcher_connect,
+ &payload, sizeof(payload), false);
}
GList *red_channel_get_clients(RedChannel *channel)
@@ -690,12 +758,47 @@ const RedChannelCapabilities* red_channel_get_local_capabilities(RedChannel *sel
return &self->priv->local_caps;
}
+static void handle_dispatcher_migrate(void *opaque, void *payload)
+{
+ RedMessageMigrate *msg = payload;
+ RedChannel *channel = red_channel_client_get_channel(msg->rcc);
+
+ channel->priv->client_cbs.migrate(msg->rcc);
+ g_object_unref(msg->rcc);
+}
+
void red_channel_migrate_client(RedChannel *channel, RedChannelClient *rcc)
{
- channel->priv->client_cbs.migrate(rcc);
+ if (channel->priv->dispatcher == NULL ||
+ pthread_equal(pthread_self(), channel->priv->thread_id)) {
+ channel->priv->client_cbs.migrate(rcc);
+ return;
+ }
+
+ RedMessageMigrate payload = { .rcc = g_object_ref(rcc) };
+ dispatcher_send_message_generic(channel->priv->dispatcher, handle_dispatcher_migrate,
+ &payload, sizeof(payload), false);
+}
+
+static void handle_dispatcher_disconnect(void *opaque, void *payload)
+{
+ RedMessageDisconnect *msg = payload;
+ RedChannel *channel = red_channel_client_get_channel(msg->rcc);
+
+ channel->priv->client_cbs.disconnect(msg->rcc);
}
void red_channel_disconnect_client(RedChannel *channel, RedChannelClient *rcc)
{
- channel->priv->client_cbs.disconnect(rcc);
+ if (channel->priv->dispatcher == NULL ||
+ pthread_equal(pthread_self(), channel->priv->thread_id)) {
+ channel->priv->client_cbs.disconnect(rcc);
+ return;
+ }
+
+ // TODO: we turned it to be sync, due to client_destroy . Should we support async? - for this we will need ref count
+ // for channels
+ RedMessageDisconnect payload = { .rcc = rcc };
+ dispatcher_send_message_generic(channel->priv->dispatcher, handle_dispatcher_disconnect,
+ &payload, sizeof(payload), true);
}
diff --git a/server/red-qxl.c b/server/red-qxl.c
index 0dd26b22..af2c7ed5 100644
--- a/server/red-qxl.c
+++ b/server/red-qxl.c
@@ -75,102 +75,6 @@ int red_qxl_check_qxl_version(QXLInstance *qxl, int major, int minor)
((qxl_major == major) && (qxl_minor >= minor)));
}
-static void red_qxl_set_display_peer(RedChannel *channel, RedClient *client,
- RedStream *stream, int migration,
- RedChannelCapabilities *caps)
-{
- RedWorkerMessageDisplayConnect payload = {0,};
- Dispatcher *dispatcher;
-
- spice_debug("%s", "");
- dispatcher = (Dispatcher *)g_object_get_data(G_OBJECT(channel), "dispatcher");
- // get a reference potentially the main channel can be destroyed in
- // the main thread causing RedClient to be destroyed before using it
- payload.client = g_object_ref(client);
- payload.stream = stream;
- payload.migration = migration;
- red_channel_capabilities_init(&payload.caps, caps);
-
- dispatcher_send_message(dispatcher,
- RED_WORKER_MESSAGE_DISPLAY_CONNECT,
- &payload);
-}
-
-static void red_qxl_disconnect_display_peer(RedChannelClient *rcc)
-{
- RedWorkerMessageDisplayDisconnect payload;
- Dispatcher *dispatcher;
- RedChannel *channel = red_channel_client_get_channel(rcc);
-
- dispatcher = (Dispatcher *)g_object_get_data(G_OBJECT(channel), "dispatcher");
-
- payload.rcc = rcc;
-
- // TODO: we turned it to be sync, due to client_destroy . Should we support async? - for this we will need ref count
- // for channels
- dispatcher_send_message(dispatcher,
- RED_WORKER_MESSAGE_DISPLAY_DISCONNECT,
- &payload);
-}
-
-static void red_qxl_display_migrate(RedChannelClient *rcc)
-{
- RedWorkerMessageDisplayMigrate payload;
- Dispatcher *dispatcher;
- RedChannel *channel = red_channel_client_get_channel(rcc);
-
- dispatcher = (Dispatcher *)g_object_get_data(G_OBJECT(channel), "dispatcher");
- payload.rcc = g_object_ref(rcc);
- dispatcher_send_message(dispatcher,
- RED_WORKER_MESSAGE_DISPLAY_MIGRATE,
- &payload);
-}
-
-static void red_qxl_set_cursor_peer(RedChannel *channel, RedClient *client, RedStream *stream,
- int migration,
- RedChannelCapabilities *caps)
-{
- RedWorkerMessageCursorConnect payload = {0,};
- Dispatcher *dispatcher = (Dispatcher *)g_object_get_data(G_OBJECT(channel), "dispatcher");
- // get a reference potentially the main channel can be destroyed in
- // the main thread causing RedClient to be destroyed before using it
- payload.client = g_object_ref(client);
- payload.stream = stream;
- payload.migration = migration;
- red_channel_capabilities_init(&payload.caps, caps);
-
- dispatcher_send_message(dispatcher,
- RED_WORKER_MESSAGE_CURSOR_CONNECT,
- &payload);
-}
-
-static void red_qxl_disconnect_cursor_peer(RedChannelClient *rcc)
-{
- RedWorkerMessageCursorDisconnect payload;
- Dispatcher *dispatcher;
- RedChannel *channel = red_channel_client_get_channel(rcc);
-
- dispatcher = (Dispatcher *)g_object_get_data(G_OBJECT(channel), "dispatcher");
- payload.rcc = rcc;
-
- dispatcher_send_message(dispatcher,
- RED_WORKER_MESSAGE_CURSOR_DISCONNECT,
- &payload);
-}
-
-static void red_qxl_cursor_migrate(RedChannelClient *rcc)
-{
- RedWorkerMessageCursorMigrate payload;
- Dispatcher *dispatcher;
- RedChannel *channel = red_channel_client_get_channel(rcc);
-
- dispatcher = (Dispatcher *)g_object_get_data(G_OBJECT(channel), "dispatcher");
- payload.rcc = g_object_ref(rcc);
- dispatcher_send_message(dispatcher,
- RED_WORKER_MESSAGE_CURSOR_MIGRATE,
- &payload);
-}
-
static void red_qxl_update_area(QXLState *qxl_state, uint32_t surface_id,
QXLRect *qxl_area, QXLRect *qxl_dirty_rects,
uint32_t num_dirty_rects, uint32_t clear_dirty_region)
@@ -914,8 +818,6 @@ size_t red_qxl_get_monitors_count(const QXLInstance *qxl)
void red_qxl_init(RedsState *reds, QXLInstance *qxl)
{
QXLState *qxl_state;
- ClientCbs client_cursor_cbs = { NULL, };
- ClientCbs client_display_cbs = { NULL, };
spice_return_if_fail(qxl != NULL);
@@ -948,17 +850,7 @@ void red_qxl_init(RedsState *reds, QXLInstance *qxl)
qxl_state->max_monitors = UINT_MAX;
qxl->st = qxl_state;
- // TODO: move to their respective channel files
- client_cursor_cbs.connect = red_qxl_set_cursor_peer;
- client_cursor_cbs.disconnect = red_qxl_disconnect_cursor_peer;
- client_cursor_cbs.migrate = red_qxl_cursor_migrate;
-
- client_display_cbs.connect = red_qxl_set_display_peer;
- client_display_cbs.disconnect = red_qxl_disconnect_display_peer;
- client_display_cbs.migrate = red_qxl_display_migrate;
-
- qxl_state->worker = red_worker_new(qxl, &client_cursor_cbs,
- &client_display_cbs);
+ qxl_state->worker = red_worker_new(qxl);
red_worker_run(qxl_state->worker);
}
diff --git a/server/red-replay-qxl.c b/server/red-replay-qxl.c
index 4884e97e..8124c1fd 100644
--- a/server/red-replay-qxl.c
+++ b/server/red-replay-qxl.c
@@ -1283,9 +1283,6 @@ static void replay_handle_dev_input(QXLWorker *worker, SpiceReplay *replay,
break;
case RED_WORKER_MESSAGE_UPDATE:
// XXX do anything? we record the correct bitmaps already.
- case RED_WORKER_MESSAGE_DISPLAY_CONNECT:
- // we want to ignore this one - it is sent on client connection, we
- // shall have our own clients
case RED_WORKER_MESSAGE_WAKEUP:
// safe to ignore
break;
diff --git a/server/red-stream-device.c b/server/red-stream-device.c
index 78a8c908..cf5a6e9a 100644
--- a/server/red-stream-device.c
+++ b/server/red-stream-device.c
@@ -696,7 +696,7 @@ stream_device_create_channel(StreamDevice *dev)
StreamChannel *stream_channel = stream_channel_new(reds, id);
- CursorChannel *cursor_channel = cursor_channel_new(reds, id, core);
+ CursorChannel *cursor_channel = cursor_channel_new(reds, id, core, NULL);
ClientCbs client_cbs = { NULL, };
client_cbs.connect = (channel_client_connect_proc) cursor_channel_connect;
client_cbs.migrate = cursor_channel_client_migrate;
diff --git a/server/red-worker.c b/server/red-worker.c
index 3cb12b9c..07329b17 100644
--- a/server/red-worker.c
+++ b/server/red-worker.c
@@ -694,20 +694,22 @@ static void handle_dev_create_primary_surface_async(void *opaque, void *payload)
red_qxl_async_complete(worker->qxl, msg->base.cookie);
}
-static void handle_dev_display_connect(void *opaque, void *payload)
+static void
+handle_dev_display_connect(RedChannel *channel, RedClient *client,
+ RedStream *stream, int migration,
+ RedChannelCapabilities *caps)
{
- RedWorkerMessageDisplayConnect *msg = payload;
- RedWorker *worker = opaque;
- DisplayChannel *display = worker->display_channel;
+ DisplayChannel *display = DISPLAY_CHANNEL(channel);
DisplayChannelClient *dcc;
+ RedWorker *worker = g_object_get_data(G_OBJECT(channel), "worker");
spice_debug("connect new client");
- spice_return_if_fail(display);
- dcc = dcc_new(display, msg->client, msg->stream, msg->migration, &msg->caps,
- worker->image_compression, worker->jpeg_state, worker->zlib_glz_state);
- g_object_unref(msg->client);
- red_channel_capabilities_reset(&msg->caps);
+ // FIXME not sure how safe is reading directly from reds
+ SpiceServer *reds = red_channel_get_server(channel);
+ dcc = dcc_new(display, client, stream, migration, caps,
+ spice_server_get_image_compression(reds), reds_get_jpeg_state(reds),
+ reds_get_zlib_glz_state(reds));
if (!dcc) {
return;
}
@@ -716,30 +718,21 @@ static void handle_dev_display_connect(void *opaque, void *payload)
dcc_start(dcc);
}
-static void handle_dev_display_disconnect(void *opaque, void *payload)
+static void
+handle_dev_display_disconnect(RedChannelClient *rcc)
{
- RedWorkerMessageDisplayDisconnect *msg = payload;
- RedChannelClient *rcc = msg->rcc;
- RedWorker *worker = opaque;
-
- spice_debug("disconnect display client");
- spice_assert(rcc);
+ RedChannel *channel = red_channel_client_get_channel(rcc);
+ RedWorker *worker = g_object_get_data(G_OBJECT(channel), "worker");
guest_set_client_capabilities(worker);
red_channel_client_disconnect(rcc);
}
-static void handle_dev_display_migrate(void *opaque, void *payload)
+static void handle_dev_display_migrate(RedChannelClient *rcc)
{
- RedWorkerMessageDisplayMigrate *msg = payload;
- RedWorker *worker = opaque;
-
- RedChannelClient *rcc = msg->rcc;
- spice_debug("migrate display client");
- spice_assert(rcc);
- red_migrate_display(worker->display_channel, rcc);
- g_object_unref(rcc);
+ DisplayChannel *display = DISPLAY_CHANNEL(red_channel_client_get_channel(rcc));
+ red_migrate_display(display, rcc);
}
static inline uint32_t qxl_monitors_config_size(uint32_t heads)
@@ -791,40 +784,6 @@ async_complete:
red_qxl_async_complete(worker->qxl, msg->base.cookie);
}
-/* TODO: special, perhaps use another dispatcher? */
-static void handle_dev_cursor_connect(void *opaque, void *payload)
-{
- RedWorkerMessageCursorConnect *msg = payload;
- RedWorker *worker = opaque;
-
- spice_debug("cursor connect");
- cursor_channel_connect(worker->cursor_channel,
- msg->client, msg->stream, msg->migration,
- &msg->caps);
- g_object_unref(msg->client);
- red_channel_capabilities_reset(&msg->caps);
-}
-
-static void handle_dev_cursor_disconnect(void *opaque, void *payload)
-{
- RedWorkerMessageCursorDisconnect *msg = payload;
- RedChannelClient *rcc = msg->rcc;
-
- spice_debug("disconnect cursor client");
- spice_return_if_fail(rcc);
- red_channel_client_disconnect(rcc);
-}
-
-static void handle_dev_cursor_migrate(void *opaque, void *payload)
-{
- RedWorkerMessageCursorMigrate *msg = payload;
- RedChannelClient *rcc = msg->rcc;
-
- spice_debug("migrate cursor client");
- cursor_channel_client_migrate(rcc);
- g_object_unref(rcc);
-}
-
static void handle_dev_set_compression(void *opaque, void *payload)
{
RedWorkerMessageSetCompression *msg = payload;
@@ -998,36 +957,6 @@ static void worker_dispatcher_record(void *opaque, uint32_t message_type, void *
static void register_callbacks(Dispatcher *dispatcher)
{
/* TODO: register cursor & display specific msg in respective channel files */
- dispatcher_register_handler(dispatcher,
- RED_WORKER_MESSAGE_DISPLAY_CONNECT,
- handle_dev_display_connect,
- sizeof(RedWorkerMessageDisplayConnect),
- false);
- dispatcher_register_handler(dispatcher,
- RED_WORKER_MESSAGE_DISPLAY_DISCONNECT,
- handle_dev_display_disconnect,
- sizeof(RedWorkerMessageDisplayDisconnect),
- true);
- dispatcher_register_handler(dispatcher,
- RED_WORKER_MESSAGE_DISPLAY_MIGRATE,
- handle_dev_display_migrate,
- sizeof(RedWorkerMessageDisplayMigrate),
- false);
- dispatcher_register_handler(dispatcher,
- RED_WORKER_MESSAGE_CURSOR_CONNECT,
- handle_dev_cursor_connect,
- sizeof(RedWorkerMessageCursorConnect),
- false);
- dispatcher_register_handler(dispatcher,
- RED_WORKER_MESSAGE_CURSOR_DISCONNECT,
- handle_dev_cursor_disconnect,
- sizeof(RedWorkerMessageCursorDisconnect),
- true);
- dispatcher_register_handler(dispatcher,
- RED_WORKER_MESSAGE_CURSOR_MIGRATE,
- handle_dev_cursor_migrate,
- sizeof(RedWorkerMessageCursorMigrate),
- false);
dispatcher_register_handler(dispatcher,
RED_WORKER_MESSAGE_UPDATE,
handle_dev_update,
@@ -1259,9 +1188,7 @@ static GSourceFuncs worker_source_funcs = {
.dispatch = worker_source_dispatch,
};
-RedWorker* red_worker_new(QXLInstance *qxl,
- const ClientCbs *client_cursor_cbs,
- const ClientCbs *client_display_cbs)
+RedWorker* red_worker_new(QXLInstance *qxl)
{
QXLDevInitInfo init_info;
RedWorker *worker;
@@ -1317,21 +1244,31 @@ RedWorker* red_worker_new(QXLInstance *qxl,
worker->event_timeout = INF_EVENT_WAIT;
worker->cursor_channel = cursor_channel_new(reds, qxl->id,
- &worker->core);
+ &worker->core, dispatcher);
channel = RED_CHANNEL(worker->cursor_channel);
red_channel_init_stat_node(channel, &worker->stat, "cursor_channel");
- red_channel_register_client_cbs(channel, client_cursor_cbs);
- g_object_set_data(G_OBJECT(channel), "dispatcher", dispatcher);
+
+ ClientCbs client_cursor_cbs = { NULL, };
+ client_cursor_cbs.connect = (channel_client_connect_proc) cursor_channel_connect;
+ client_cursor_cbs.disconnect = NULL;
+ client_cursor_cbs.migrate = cursor_channel_client_migrate;
+ red_channel_register_client_cbs(channel, &client_cursor_cbs);
// TODO: handle seamless migration. Temp, setting migrate to FALSE
- worker->display_channel = display_channel_new(reds, qxl, &worker->core, FALSE,
+ worker->display_channel = display_channel_new(reds, qxl, &worker->core, dispatcher,
+ FALSE,
reds_get_streaming_video(reds),
reds_get_video_codecs(reds),
init_info.n_surfaces);
channel = RED_CHANNEL(worker->display_channel);
red_channel_init_stat_node(channel, &worker->stat, "display_channel");
- red_channel_register_client_cbs(channel, client_display_cbs);
- g_object_set_data(G_OBJECT(channel), "dispatcher", dispatcher);
+ g_object_set_data(G_OBJECT(channel), "worker", worker);
+
+ ClientCbs client_display_cbs = { NULL, };
+ client_display_cbs.connect = handle_dev_display_connect;
+ client_display_cbs.disconnect = handle_dev_display_disconnect;
+ client_display_cbs.migrate = handle_dev_display_migrate;
+ red_channel_register_client_cbs(channel, &client_display_cbs);
return worker;
}
diff --git a/server/red-worker.h b/server/red-worker.h
index 767329da..3d2841ba 100644
--- a/server/red-worker.h
+++ b/server/red-worker.h
@@ -28,9 +28,7 @@
typedef struct RedWorker RedWorker;
-RedWorker* red_worker_new(QXLInstance *qxl,
- const ClientCbs *client_cursor_cbs,
- const ClientCbs *client_display_cbs);
+RedWorker* red_worker_new(QXLInstance *qxl);
bool red_worker_run(RedWorker *worker);
void red_worker_free(RedWorker *worker);
@@ -51,14 +49,14 @@ enum {
RED_WORKER_MESSAGE_OOM,
RED_WORKER_MESSAGE_READY, /* unused */
- RED_WORKER_MESSAGE_DISPLAY_CONNECT,
- RED_WORKER_MESSAGE_DISPLAY_DISCONNECT,
- RED_WORKER_MESSAGE_DISPLAY_MIGRATE,
+ RED_WORKER_MESSAGE_DISPLAY_CONNECT_DEPRECATED,
+ RED_WORKER_MESSAGE_DISPLAY_DISCONNECT_DEPRECATED,
+ RED_WORKER_MESSAGE_DISPLAY_MIGRATE_DEPRECATED,
RED_WORKER_MESSAGE_START,
RED_WORKER_MESSAGE_STOP,
- RED_WORKER_MESSAGE_CURSOR_CONNECT,
- RED_WORKER_MESSAGE_CURSOR_DISCONNECT,
- RED_WORKER_MESSAGE_CURSOR_MIGRATE,
+ RED_WORKER_MESSAGE_CURSOR_CONNECT_DEPRECATED,
+ RED_WORKER_MESSAGE_CURSOR_DISCONNECT_DEPRECATED,
+ RED_WORKER_MESSAGE_CURSOR_MIGRATE_DEPRECATED,
RED_WORKER_MESSAGE_SET_COMPRESSION,
RED_WORKER_MESSAGE_SET_STREAMING_VIDEO,
RED_WORKER_MESSAGE_SET_MOUSE_MODE,
@@ -97,36 +95,6 @@ enum {
RED_WORKER_MESSAGE_COUNT // LAST
};
-typedef struct RedWorkerMessageDisplayConnect {
- RedClient * client;
- RedStream * stream;
- RedChannelCapabilities caps; // red_worker should reset
- int migration;
-} RedWorkerMessageDisplayConnect;
-
-typedef struct RedWorkerMessageDisplayDisconnect {
- RedChannelClient *rcc;
-} RedWorkerMessageDisplayDisconnect;
-
-typedef struct RedWorkerMessageDisplayMigrate {
- RedChannelClient *rcc;
-} RedWorkerMessageDisplayMigrate;
-
-typedef struct RedWorkerMessageCursorConnect {
- RedClient *client;
- RedStream *stream;
- int migration;
- RedChannelCapabilities caps; // red_worker should reset
-} RedWorkerMessageCursorConnect;
-
-typedef struct RedWorkerMessageCursorDisconnect {
- RedChannelClient *rcc;
-} RedWorkerMessageCursorDisconnect;
-
-typedef struct RedWorkerMessageCursorMigrate {
- RedChannelClient *rcc;
-} RedWorkerMessageCursorMigrate;
-
typedef struct RedWorkerMessageUpdate {
uint32_t surface_id;
QXLRect * qxl_area;
--
2.20.1
More information about the Spice-devel
mailing list