diff options
-rw-r--r-- | server/main-dispatcher.c | 12 | ||||
-rw-r--r-- | server/red-channel-client.c | 1 | ||||
-rw-r--r-- | server/red-client.c | 117 | ||||
-rw-r--r-- | server/red-client.h | 29 | ||||
-rw-r--r-- | server/reds.c | 2 |
5 files changed, 123 insertions, 38 deletions
diff --git a/server/main-dispatcher.c b/server/main-dispatcher.c index fe29b2df..09ac1ccd 100644 --- a/server/main-dispatcher.c +++ b/server/main-dispatcher.c @@ -208,7 +208,7 @@ static void main_dispatcher_handle_migrate_complete(void *opaque, MainDispatcherMigrateSeamlessDstCompleteMessage *mig_complete = payload; reds_on_client_seamless_migrate_complete(self->priv->reds, mig_complete->client); - red_client_unref(mig_complete->client); + g_object_unref(mig_complete->client); } static void main_dispatcher_handle_mm_time_latency(void *opaque, @@ -217,7 +217,7 @@ static void main_dispatcher_handle_mm_time_latency(void *opaque, MainDispatcher *self = opaque; MainDispatcherMmTimeLatencyMessage *msg = payload; reds_set_client_mm_time_latency(self->priv->reds, msg->client, msg->latency); - red_client_unref(msg->client); + g_object_unref(msg->client); } static void main_dispatcher_handle_client_disconnect(void *opaque, @@ -228,7 +228,7 @@ static void main_dispatcher_handle_client_disconnect(void *opaque, spice_debug("client=%p", msg->client); reds_client_disconnect(self->priv->reds, msg->client); - red_client_unref(msg->client); + g_object_unref(msg->client); } void main_dispatcher_seamless_migrate_dst_complete(MainDispatcher *self, @@ -241,7 +241,7 @@ void main_dispatcher_seamless_migrate_dst_complete(MainDispatcher *self, return; } - msg.client = red_client_ref(client); + msg.client = g_object_ref(client); dispatcher_send_message(DISPATCHER(self), MAIN_DISPATCHER_MIGRATE_SEAMLESS_DST_COMPLETE, &msg); } @@ -255,7 +255,7 @@ void main_dispatcher_set_mm_time_latency(MainDispatcher *self, RedClient *client return; } - msg.client = red_client_ref(client); + msg.client = g_object_ref(client); msg.latency = latency; dispatcher_send_message(DISPATCHER(self), MAIN_DISPATCHER_SET_MM_TIME_LATENCY, &msg); @@ -267,7 +267,7 @@ void main_dispatcher_client_disconnect(MainDispatcher *self, RedClient *client) if (!red_client_is_disconnecting(client)) { spice_debug("client %p", client); - msg.client = red_client_ref(client); + msg.client = g_object_ref(client); dispatcher_send_message(DISPATCHER(self), MAIN_DISPATCHER_CLIENT_DISCONNECT, &msg); } else { diff --git a/server/red-channel-client.c b/server/red-channel-client.c index 86d2305f..048286b4 100644 --- a/server/red-channel-client.c +++ b/server/red-channel-client.c @@ -36,7 +36,6 @@ #include "red-channel-client.h" #include "red-channel-client-private.h" #include "red-client.h" -#include "glib-compat.h" static const SpiceDataHeaderOpaque full_header_wrapper; static const SpiceDataHeaderOpaque mini_header_wrapper; diff --git a/server/red-client.c b/server/red-client.c index 39846720..91f4c17c 100644 --- a/server/red-client.c +++ b/server/red-client.c @@ -27,6 +27,7 @@ GLIST_FOREACH((_client ? (_client)->channels : NULL), _iter, RedChannelClient, _data) struct RedClient { + GObject parent; RedsState *reds; GList *channels; MainChannelClient *mcc; @@ -47,36 +48,109 @@ struct RedClient { int refs; }; -RedClient *red_client_ref(RedClient *client) +struct RedClientClass { - spice_assert(client); - g_atomic_int_inc(&client->refs); - return client; + GObjectClass parent_class; +}; + +G_DEFINE_TYPE(RedClient, red_client, G_TYPE_OBJECT) + +enum { + PROP0, + PROP_SPICE_SERVER, + PROP_MIGRATED +}; + +static void +red_client_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + RedClient *self = RED_CLIENT(object); + + switch (property_id) + { + case PROP_SPICE_SERVER: + g_value_set_pointer(value, self->reds); + break; + case PROP_MIGRATED: + g_value_set_boolean(value, self->during_target_migrate); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } } -RedClient *red_client_unref(RedClient *client) +static void +red_client_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) { - if (g_atomic_int_dec_and_test(&client->refs)) { - spice_debug("release client=%p", client); - pthread_mutex_destroy(&client->lock); - free(client); - return NULL; + RedClient *self = RED_CLIENT(object); + + switch (property_id) + { + case PROP_SPICE_SERVER: + self->reds = g_value_get_pointer(value); + break; + case PROP_MIGRATED: + self->during_target_migrate = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } - return client; } -RedClient *red_client_new(RedsState *reds, int migrated) +static void +red_client_finalize (GObject *object) +{ + RedClient *self = RED_CLIENT(object); + + spice_debug("release client=%p", self); + pthread_mutex_destroy(&self->lock); + + G_OBJECT_CLASS (red_client_parent_class)->finalize (object); +} + +static void +red_client_class_init (RedClientClass *klass) { - RedClient *client; + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = red_client_get_property; + object_class->set_property = red_client_set_property; + object_class->finalize = red_client_finalize; + + g_object_class_install_property(object_class, + PROP_SPICE_SERVER, + g_param_spec_pointer("spice-server", + "Spice server", + "The Spice Server", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property(object_class, + PROP_MIGRATED, + g_param_spec_boolean("migrated", + "migrated", + "Whether this client was migrated", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +} - client = spice_malloc0(sizeof(RedClient)); - client->reds = reds; - pthread_mutex_init(&client->lock, NULL); - client->thread_id = pthread_self(); - client->during_target_migrate = migrated; - client->refs = 1; +static void +red_client_init (RedClient *self) +{ + pthread_mutex_init(&self->lock, NULL); + self->thread_id = pthread_self(); +} - return client; +RedClient *red_client_new(RedsState *reds, int migrated) +{ + return g_object_new (RED_TYPE_CLIENT, + "spice-server", reds, + "migrated", migrated, + NULL); } void red_client_set_migration_seamless(RedClient *client) // dest @@ -146,9 +220,10 @@ void red_client_destroy(RedClient *client) spice_assert(red_channel_client_no_item_being_sent(rcc)); red_channel_client_destroy(rcc); } - red_client_unref(client); + g_object_unref(client); } + /* client->lock should be locked */ RedChannelClient *red_client_get_channel(RedClient *client, int type, int id) { diff --git a/server/red-client.h b/server/red-client.h index 3ab44409..1bf5ab8b 100644 --- a/server/red-client.h +++ b/server/red-client.h @@ -19,8 +19,26 @@ #ifndef _H_RED_CLIENT #define _H_RED_CLIENT +#include <glib-object.h> + #include "main-channel-client.h" +G_BEGIN_DECLS + +#define RED_TYPE_CLIENT red_client_get_type() + +#define RED_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RED_TYPE_CLIENT, RedClient)) +#define RED_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RED_TYPE_CLIENT, RedClientClass)) +#define RED_IS_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RED_TYPE_CLIENT)) +#define RED_IS_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RED_TYPE_CLIENT)) +#define RED_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RED_TYPE_CLIENT, RedClientClass)) + +typedef struct RedClient RedClient; +typedef struct RedClientClass RedClientClass; +typedef struct RedClientPrivate RedClientPrivate; + +GType red_client_get_type (void) G_GNUC_CONST; + RedClient *red_client_new(RedsState *reds, int migrated); /* @@ -28,15 +46,6 @@ RedClient *red_client_new(RedsState *reds, int migrated); */ void red_client_destroy(RedClient *client); -RedClient *red_client_ref(RedClient *client); - -/* - * releases the client resources when refs == 0. - * We assume the red_client_derstroy was called before - * we reached refs==0 - */ -RedClient *red_client_unref(RedClient *client); - gboolean red_client_add_channel(RedClient *client, RedChannelClient *rcc, GError **error); void red_client_remove_channel(RedChannelClient *rcc); RedChannelClient *red_client_get_channel(RedClient *client, int type, int id); @@ -62,4 +71,6 @@ gboolean red_client_is_disconnecting(RedClient *client); void red_client_set_disconnecting(RedClient *client); RedsState* red_client_get_server(RedClient *client); +G_END_DECLS + #endif /* _H_RED_CLIENT */ diff --git a/server/reds.c b/server/reds.c index 089c3257..77f566ec 100644 --- a/server/reds.c +++ b/server/reds.c @@ -68,7 +68,7 @@ #include "smartcard.h" #endif #include "reds-stream.h" -#include "utils.h" +#include "red-client.h" #include "reds-private.h" #include "video-encoder.h" |