diff --git a/server/reds-private.h b/server/reds-private.h index adc48ba5..920edc5c 100644 --- a/server/reds-private.h +++ b/server/reds-private.h @@ -117,6 +117,7 @@ struct RedsState { RedStatFile *stat_file; #endif int allow_multiple_clients; + bool late_initialization_done; /* Intermediate state for on going monitors config message from a single * client, being passed to the guest */ diff --git a/server/reds.c b/server/reds.c index 9660476c..73c9ec20 100644 --- a/server/reds.c +++ b/server/reds.c @@ -1734,6 +1734,26 @@ static RedClient *reds_get_client(RedsState *reds) return reds->clients->data; } +/* Performs late initializations steps. + * This should be called when a client connects */ +static void reds_late_initialization(RedsState *reds) +{ + RedCharDevice *dev; + + // do only once + if (reds->late_initialization_done) { + return; + } + + // create stream channels for streaming devices + GLIST_FOREACH(reds->char_devices, RedCharDevice, dev) { + if (IS_STREAM_DEVICE(dev)) { + stream_device_create_channel(STREAM_DEVICE(dev)); + } + } + reds->late_initialization_done = true; +} + static void red_channel_capabilities_init_from_link_message(RedChannelCapabilities *caps, const SpiceLinkMess *link_mess) @@ -1769,6 +1789,8 @@ static void reds_handle_main_link(RedsState *reds, RedLinkInfo *link) spice_debug("trace"); spice_assert(reds->main_channel); + reds_late_initialization(reds); + link_mess = link->link_mess; if (!reds->allow_multiple_clients) { reds_disconnect(reds); diff --git a/server/stream-device.c b/server/stream-device.c index fd73e784..6cf29d37 100644 --- a/server/stream-device.c +++ b/server/stream-device.c @@ -538,8 +538,8 @@ stream_device_finalize(GObject *object) dev->msg_pos = 0; } -static void -allocate_channels(StreamDevice *dev) +void +stream_device_create_channel(StreamDevice *dev) { if (dev->stream_channel) { return; @@ -600,7 +600,7 @@ stream_device_port_event(RedCharDevice *char_dev, uint8_t event) // reset device and channel on close/open dev->opened = (event == SPICE_PORT_EVENT_OPENED); if (dev->opened) { - allocate_channels(dev); + stream_device_create_channel(dev); } dev->hdr_pos = 0; dev->msg_pos = 0; diff --git a/server/stream-device.h b/server/stream-device.h index eff6e870..f0a5b5c1 100644 --- a/server/stream-device.h +++ b/server/stream-device.h @@ -43,6 +43,11 @@ typedef struct StreamDeviceClass StreamDeviceClass; GType stream_device_get_type(void) G_GNUC_CONST; StreamDevice *stream_device_connect(RedsState *reds, SpiceCharDeviceInstance *sin); +/* Create channel for the streaming device. + * If the channel already exists the function does nothing. + */ +void stream_device_create_channel(StreamDevice *dev); + G_END_DECLS #endif /* STREAM_DEVICE_H */