mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-26 14:41:25 +00:00
Remove global main_dispatcher variable
Requires changing a bunch of internal API to take MainDispatcher arguments, etc. The main dispatcher object is now owned by RedsState, since that is the object that previously created (initialized) it. Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
This commit is contained in:
parent
bc5c07a881
commit
2a18e874a2
@ -178,8 +178,9 @@ int main_channel_is_connected(MainChannel *main_chan)
|
||||
*/
|
||||
static void main_channel_client_on_disconnect(RedChannelClient *rcc)
|
||||
{
|
||||
RedsState *reds = red_channel_get_server(rcc->channel);
|
||||
spice_printerr("rcc=%p", rcc);
|
||||
main_dispatcher_client_disconnect(rcc->client);
|
||||
main_dispatcher_client_disconnect(reds_get_main_dispatcher(reds), rcc->client);
|
||||
}
|
||||
|
||||
RedClient *main_channel_get_client_by_link_id(MainChannel *main_chan, uint32_t connection_id)
|
||||
|
||||
@ -47,12 +47,11 @@
|
||||
* seperate from self because it may send an ack or do other work in the future.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
struct MainDispatcher {
|
||||
Dispatcher base;
|
||||
SpiceCoreInterfaceInternal *core;
|
||||
} MainDispatcher;
|
||||
|
||||
MainDispatcher main_dispatcher;
|
||||
RedsState *reds;
|
||||
};
|
||||
|
||||
enum {
|
||||
MAIN_DISPATCHER_CHANNEL_EVENT = 0,
|
||||
@ -82,33 +81,35 @@ typedef struct MainDispatcherClientDisconnectMessage {
|
||||
} MainDispatcherClientDisconnectMessage;
|
||||
|
||||
/* channel_event - calls core->channel_event, must be done in main thread */
|
||||
static void main_dispatcher_self_handle_channel_event(
|
||||
int event,
|
||||
SpiceChannelEventInfo *info)
|
||||
static void main_dispatcher_self_handle_channel_event(MainDispatcher *self,
|
||||
int event,
|
||||
SpiceChannelEventInfo *info)
|
||||
{
|
||||
reds_handle_channel_event(reds, event, info);
|
||||
reds_handle_channel_event(self->reds, event, info);
|
||||
}
|
||||
|
||||
static void main_dispatcher_handle_channel_event(void *opaque,
|
||||
void *payload)
|
||||
{
|
||||
MainDispatcher *self = opaque;
|
||||
MainDispatcherChannelEventMessage *channel_event = payload;
|
||||
|
||||
main_dispatcher_self_handle_channel_event(channel_event->event,
|
||||
main_dispatcher_self_handle_channel_event(self,
|
||||
channel_event->event,
|
||||
channel_event->info);
|
||||
}
|
||||
|
||||
void main_dispatcher_channel_event(int event, SpiceChannelEventInfo *info)
|
||||
void main_dispatcher_channel_event(MainDispatcher *self, int event, SpiceChannelEventInfo *info)
|
||||
{
|
||||
MainDispatcherChannelEventMessage msg = {0,};
|
||||
|
||||
if (pthread_self() == main_dispatcher.base.self) {
|
||||
main_dispatcher_self_handle_channel_event(event, info);
|
||||
if (pthread_self() == self->base.self) {
|
||||
main_dispatcher_self_handle_channel_event(self, event, info);
|
||||
return;
|
||||
}
|
||||
msg.event = event;
|
||||
msg.info = info;
|
||||
dispatcher_send_message(&main_dispatcher.base, MAIN_DISPATCHER_CHANNEL_EVENT,
|
||||
dispatcher_send_message(&self->base, MAIN_DISPATCHER_CHANNEL_EVENT,
|
||||
&msg);
|
||||
}
|
||||
|
||||
@ -116,67 +117,71 @@ void main_dispatcher_channel_event(int event, SpiceChannelEventInfo *info)
|
||||
static void main_dispatcher_handle_migrate_complete(void *opaque,
|
||||
void *payload)
|
||||
{
|
||||
MainDispatcher *self = opaque;
|
||||
MainDispatcherMigrateSeamlessDstCompleteMessage *mig_complete = payload;
|
||||
|
||||
reds_on_client_seamless_migrate_complete(reds, mig_complete->client);
|
||||
reds_on_client_seamless_migrate_complete(self->reds, mig_complete->client);
|
||||
red_client_unref(mig_complete->client);
|
||||
}
|
||||
|
||||
static void main_dispatcher_handle_mm_time_latency(void *opaque,
|
||||
void *payload)
|
||||
{
|
||||
MainDispatcher *self = opaque;
|
||||
MainDispatcherMmTimeLatencyMessage *msg = payload;
|
||||
reds_set_client_mm_time_latency(reds, msg->client, msg->latency);
|
||||
reds_set_client_mm_time_latency(self->reds, msg->client, msg->latency);
|
||||
red_client_unref(msg->client);
|
||||
}
|
||||
|
||||
static void main_dispatcher_handle_client_disconnect(void *opaque,
|
||||
void *payload)
|
||||
{
|
||||
MainDispatcher *self = opaque;
|
||||
MainDispatcherClientDisconnectMessage *msg = payload;
|
||||
|
||||
spice_debug("client=%p", msg->client);
|
||||
reds_client_disconnect(reds, msg->client);
|
||||
reds_client_disconnect(self->reds, msg->client);
|
||||
red_client_unref(msg->client);
|
||||
}
|
||||
|
||||
void main_dispatcher_seamless_migrate_dst_complete(RedClient *client)
|
||||
void main_dispatcher_seamless_migrate_dst_complete(MainDispatcher *self,
|
||||
RedClient *client)
|
||||
{
|
||||
MainDispatcherMigrateSeamlessDstCompleteMessage msg;
|
||||
|
||||
if (pthread_self() == main_dispatcher.base.self) {
|
||||
reds_on_client_seamless_migrate_complete(reds, client);
|
||||
if (pthread_self() == self->base.self) {
|
||||
reds_on_client_seamless_migrate_complete(self->reds, client);
|
||||
return;
|
||||
}
|
||||
|
||||
msg.client = red_client_ref(client);
|
||||
dispatcher_send_message(&main_dispatcher.base, MAIN_DISPATCHER_MIGRATE_SEAMLESS_DST_COMPLETE,
|
||||
dispatcher_send_message(&self->base, MAIN_DISPATCHER_MIGRATE_SEAMLESS_DST_COMPLETE,
|
||||
&msg);
|
||||
}
|
||||
|
||||
void main_dispatcher_set_mm_time_latency(RedClient *client, uint32_t latency)
|
||||
void main_dispatcher_set_mm_time_latency(MainDispatcher *self, RedClient *client, uint32_t latency)
|
||||
{
|
||||
MainDispatcherMmTimeLatencyMessage msg;
|
||||
|
||||
if (pthread_self() == main_dispatcher.base.self) {
|
||||
reds_set_client_mm_time_latency(reds, client, latency);
|
||||
if (pthread_self() == self->base.self) {
|
||||
reds_set_client_mm_time_latency(self->reds, client, latency);
|
||||
return;
|
||||
}
|
||||
|
||||
msg.client = red_client_ref(client);
|
||||
msg.latency = latency;
|
||||
dispatcher_send_message(&main_dispatcher.base, MAIN_DISPATCHER_SET_MM_TIME_LATENCY,
|
||||
dispatcher_send_message(&self->base, MAIN_DISPATCHER_SET_MM_TIME_LATENCY,
|
||||
&msg);
|
||||
}
|
||||
|
||||
void main_dispatcher_client_disconnect(RedClient *client)
|
||||
void main_dispatcher_client_disconnect(MainDispatcher *self, RedClient *client)
|
||||
{
|
||||
MainDispatcherClientDisconnectMessage msg;
|
||||
|
||||
if (!client->disconnecting) {
|
||||
spice_debug("client %p", client);
|
||||
msg.client = red_client_ref(client);
|
||||
dispatcher_send_message(&main_dispatcher.base, MAIN_DISPATCHER_CLIENT_DISCONNECT,
|
||||
dispatcher_send_message(&self->base, MAIN_DISPATCHER_CLIENT_DISCONNECT,
|
||||
&msg);
|
||||
} else {
|
||||
spice_debug("client %p already during disconnection", client);
|
||||
@ -185,9 +190,9 @@ void main_dispatcher_client_disconnect(RedClient *client)
|
||||
|
||||
static void dispatcher_handle_read(int fd, int event, void *opaque)
|
||||
{
|
||||
Dispatcher *dispatcher = opaque;
|
||||
MainDispatcher *self = opaque;
|
||||
|
||||
dispatcher_handle_recv_read(dispatcher);
|
||||
dispatcher_handle_recv_read(&self->base);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -195,23 +200,25 @@ static void dispatcher_handle_read(int fd, int event, void *opaque)
|
||||
* Reds routines shouldn't be exposed. Instead reds.c should register the callbacks,
|
||||
* and the corresponding operations should be made only via main_dispatcher.
|
||||
*/
|
||||
void main_dispatcher_init(SpiceCoreInterfaceInternal *core)
|
||||
MainDispatcher* main_dispatcher_new(RedsState *reds, SpiceCoreInterfaceInternal *core)
|
||||
{
|
||||
memset(&main_dispatcher, 0, sizeof(main_dispatcher));
|
||||
main_dispatcher.core = core;
|
||||
dispatcher_init(&main_dispatcher.base, MAIN_DISPATCHER_NUM_MESSAGES, &main_dispatcher.base);
|
||||
core->watch_add(core, main_dispatcher.base.recv_fd, SPICE_WATCH_EVENT_READ,
|
||||
dispatcher_handle_read, &main_dispatcher.base);
|
||||
dispatcher_register_handler(&main_dispatcher.base, MAIN_DISPATCHER_CHANNEL_EVENT,
|
||||
MainDispatcher *main_dispatcher = g_new0(MainDispatcher, 1);
|
||||
main_dispatcher->core = core;
|
||||
main_dispatcher->reds = reds;
|
||||
dispatcher_init(&main_dispatcher->base, MAIN_DISPATCHER_NUM_MESSAGES, main_dispatcher);
|
||||
core->watch_add(core, main_dispatcher->base.recv_fd, SPICE_WATCH_EVENT_READ,
|
||||
dispatcher_handle_read, main_dispatcher);
|
||||
dispatcher_register_handler(&main_dispatcher->base, MAIN_DISPATCHER_CHANNEL_EVENT,
|
||||
main_dispatcher_handle_channel_event,
|
||||
sizeof(MainDispatcherChannelEventMessage), 0 /* no ack */);
|
||||
dispatcher_register_handler(&main_dispatcher.base, MAIN_DISPATCHER_MIGRATE_SEAMLESS_DST_COMPLETE,
|
||||
dispatcher_register_handler(&main_dispatcher->base, MAIN_DISPATCHER_MIGRATE_SEAMLESS_DST_COMPLETE,
|
||||
main_dispatcher_handle_migrate_complete,
|
||||
sizeof(MainDispatcherMigrateSeamlessDstCompleteMessage), 0 /* no ack */);
|
||||
dispatcher_register_handler(&main_dispatcher.base, MAIN_DISPATCHER_SET_MM_TIME_LATENCY,
|
||||
dispatcher_register_handler(&main_dispatcher->base, MAIN_DISPATCHER_SET_MM_TIME_LATENCY,
|
||||
main_dispatcher_handle_mm_time_latency,
|
||||
sizeof(MainDispatcherMmTimeLatencyMessage), 0 /* no ack */);
|
||||
dispatcher_register_handler(&main_dispatcher.base, MAIN_DISPATCHER_CLIENT_DISCONNECT,
|
||||
dispatcher_register_handler(&main_dispatcher->base, MAIN_DISPATCHER_CLIENT_DISCONNECT,
|
||||
main_dispatcher_handle_client_disconnect,
|
||||
sizeof(MainDispatcherClientDisconnectMessage), 0 /* no ack */);
|
||||
return main_dispatcher;
|
||||
}
|
||||
|
||||
@ -21,16 +21,18 @@
|
||||
#include <spice.h>
|
||||
#include "red-channel.h"
|
||||
|
||||
void main_dispatcher_channel_event(int event, SpiceChannelEventInfo *info);
|
||||
void main_dispatcher_seamless_migrate_dst_complete(RedClient *client);
|
||||
void main_dispatcher_set_mm_time_latency(RedClient *client, uint32_t latency);
|
||||
typedef struct MainDispatcher MainDispatcher;
|
||||
|
||||
void main_dispatcher_channel_event(MainDispatcher *self, int event, SpiceChannelEventInfo *info);
|
||||
void main_dispatcher_seamless_migrate_dst_complete(MainDispatcher *self, RedClient *client);
|
||||
void main_dispatcher_set_mm_time_latency(MainDispatcher *self, RedClient *client, uint32_t latency);
|
||||
/*
|
||||
* Disconnecting the client is always executed asynchronously,
|
||||
* in order to protect from expired references in the routines
|
||||
* that triggered the client destruction.
|
||||
*/
|
||||
void main_dispatcher_client_disconnect(RedClient *client);
|
||||
void main_dispatcher_client_disconnect(MainDispatcher *self, RedClient *client);
|
||||
|
||||
void main_dispatcher_init(SpiceCoreInterfaceInternal *core);
|
||||
MainDispatcher* main_dispatcher_new(RedsState *reds, SpiceCoreInterfaceInternal *core);
|
||||
|
||||
#endif //MAIN_DISPATCHER_H
|
||||
|
||||
@ -941,6 +941,7 @@ error:
|
||||
|
||||
static void red_channel_client_seamless_migration_done(RedChannelClient *rcc)
|
||||
{
|
||||
RedsState *reds = red_channel_get_server(rcc->channel);
|
||||
rcc->wait_migrate_data = FALSE;
|
||||
|
||||
pthread_mutex_lock(&rcc->client->lock);
|
||||
@ -953,7 +954,8 @@ static void red_channel_client_seamless_migration_done(RedChannelClient *rcc)
|
||||
rcc->client->seamless_migrate = FALSE;
|
||||
/* migration completion might have been triggered from a different thread
|
||||
* than the main thread */
|
||||
main_dispatcher_seamless_migrate_dst_complete(rcc->client);
|
||||
main_dispatcher_seamless_migrate_dst_complete(reds_get_main_dispatcher(reds),
|
||||
rcc->client);
|
||||
if (rcc->latency_monitor.timer) {
|
||||
red_channel_client_start_ping_timer(rcc, PING_TEST_IDLE_NET_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
@ -242,6 +242,7 @@ struct RedsState {
|
||||
RedSSLParameters ssl_parameters;
|
||||
SpiceCoreInterfaceInternal *core;
|
||||
GList *dispatchers;
|
||||
MainDispatcher *main_dispatcher;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -349,7 +349,9 @@ void reds_stream_free(RedsStream *s)
|
||||
|
||||
void reds_stream_push_channel_event(RedsStream *s, int event)
|
||||
{
|
||||
main_dispatcher_channel_event(event, s->priv->info);
|
||||
RedsState *reds = s->priv->reds;
|
||||
MainDispatcher *md = reds_get_main_dispatcher(reds);
|
||||
main_dispatcher_channel_event(md, event, s->priv->info);
|
||||
}
|
||||
|
||||
static void reds_stream_set_socket(RedsStream *stream, int socket)
|
||||
|
||||
@ -3350,7 +3350,7 @@ static int do_spice_init(RedsState *reds, SpiceCoreInterface *core_interface)
|
||||
reds_init_vd_agent_resources(reds);
|
||||
ring_init(&reds->clients);
|
||||
reds->num_clients = 0;
|
||||
main_dispatcher_init(reds->core);
|
||||
reds->main_dispatcher = main_dispatcher_new(reds, reds->core);
|
||||
ring_init(&reds->channels);
|
||||
ring_init(&reds->mig_target_clients);
|
||||
ring_init(&reds->char_devs_states);
|
||||
@ -4195,3 +4195,8 @@ uint32_t reds_qxl_ram_size(RedsState *reds)
|
||||
first = reds->dispatchers->data;
|
||||
return red_dispatcher_qxl_ram_size(first);
|
||||
}
|
||||
|
||||
MainDispatcher* reds_get_main_dispatcher(RedsState *reds)
|
||||
{
|
||||
return reds->main_dispatcher;
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "common/messages.h"
|
||||
#include "spice.h"
|
||||
#include "red-channel.h"
|
||||
#include "main-dispatcher.h"
|
||||
#include "migration-protocol.h"
|
||||
|
||||
typedef struct RedsState RedsState;
|
||||
@ -115,5 +116,6 @@ void reds_update_client_mouse_allowed(RedsState *reds);
|
||||
gboolean reds_use_client_monitors_config(RedsState *reds);
|
||||
void reds_client_monitors_config(RedsState *reds, VDAgentMonitorsConfig *monitors_config);
|
||||
void reds_set_mm_time(RedsState *reds, uint32_t mm_time);
|
||||
MainDispatcher* reds_get_main_dispatcher(RedsState *reds);
|
||||
|
||||
#endif
|
||||
|
||||
@ -683,6 +683,7 @@ static void update_client_playback_delay(void *opaque, uint32_t delay_ms)
|
||||
{
|
||||
StreamAgent *agent = opaque;
|
||||
DisplayChannelClient *dcc = agent->dcc;
|
||||
RedsState *reds = red_channel_get_server(dcc->common.base.channel);
|
||||
|
||||
dcc_update_streams_max_latency(dcc, agent);
|
||||
|
||||
@ -691,7 +692,9 @@ static void update_client_playback_delay(void *opaque, uint32_t delay_ms)
|
||||
agent->dcc->streams_max_latency = delay_ms;
|
||||
}
|
||||
spice_debug("resetting client latency: %u", agent->dcc->streams_max_latency);
|
||||
main_dispatcher_set_mm_time_latency(RED_CHANNEL_CLIENT(agent->dcc)->client, agent->dcc->streams_max_latency);
|
||||
main_dispatcher_set_mm_time_latency(reds_get_main_dispatcher(reds),
|
||||
RED_CHANNEL_CLIENT(agent->dcc)->client,
|
||||
agent->dcc->streams_max_latency);
|
||||
}
|
||||
|
||||
void dcc_create_stream(DisplayChannelClient *dcc, Stream *stream)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user