From fef97b14e50b550c6148482b4b8049c3f6ba96ae Mon Sep 17 00:00:00 2001 From: Frediano Ziglio Date: Thu, 5 Mar 2020 10:21:43 +0000 Subject: [PATCH] red-client: Make RedClient pure C++ Remove GObject. Add access protection. Signed-off-by: Frediano Ziglio --- server/red-client.cpp | 116 ++++++------------------------------------ server/red-client.h | 27 ++++++---- 2 files changed, 33 insertions(+), 110 deletions(-) diff --git a/server/red-client.cpp b/server/red-client.cpp index 5eb6dfdd..9ee5ef51 100644 --- a/server/red-client.cpp +++ b/server/red-client.cpp @@ -24,113 +24,27 @@ #define FOREACH_CHANNEL_CLIENT(_client, _data) \ GLIST_FOREACH(_client->channels, RedChannelClient, _data) -struct RedClientClass +RedClient::~RedClient() { - 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); + if (mcc) { + mcc->unref(); + mcc = nullptr; } + spice_debug("release client=%p", this); + pthread_mutex_destroy(&lock); } -static void -red_client_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) +RedClient::RedClient(RedsState *reds, bool migrated): + reds(reds), + during_target_migrate(migrated) { - RedClient *self = RED_CLIENT(object); - - switch (property_id) - { - case PROP_SPICE_SERVER: - self->reds = (RedsState*) 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); - } -} - -static void -red_client_finalize (GObject *object) -{ - RedClient *self = RED_CLIENT(object); - - if (self->mcc) { - self->mcc->unref(); - self->mcc = nullptr; - } - 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) -{ - 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)); -} - -static void -red_client_init(RedClient *self) -{ - pthread_mutex_init(&self->lock, NULL); - self->thread_id = pthread_self(); + pthread_mutex_init(&lock, NULL); + thread_id = pthread_self(); } RedClient *red_client_new(RedsState *reds, int migrated) { - return (RedClient*) g_object_new(RED_TYPE_CLIENT, - "spice-server", reds, - "migrated", migrated, - NULL); + return new RedClient(reds, migrated); } void RedClient::set_migration_seamless() // dest @@ -223,11 +137,11 @@ void RedClient::destroy() /* client->lock should be locked */ -static RedChannelClient *red_client_get_channel(RedClient *client, int type, int id) +RedChannelClient *RedClient::get_channel(int type, int id) { RedChannelClient *rcc; - FOREACH_CHANNEL_CLIENT(client, rcc) { + FOREACH_CHANNEL_CLIENT(this, rcc) { RedChannel *channel; channel = rcc->get_channel(); @@ -260,7 +174,7 @@ gboolean RedClient::add_channel(RedChannelClient *rcc, GError **error) goto cleanup; } - if (red_client_get_channel(this, type, id)) { + if (get_channel(type, id)) { g_set_error(error, SPICE_SERVER_ERROR, SPICE_SERVER_ERROR_FAILED, diff --git a/server/red-client.h b/server/red-client.h index 00bc0ec4..e41c56d4 100644 --- a/server/red-client.h +++ b/server/red-client.h @@ -19,19 +19,25 @@ #ifndef RED_CLIENT_H_ #define RED_CLIENT_H_ -#include - #include "main-channel-client.h" #include "push-visibility.h" -SPICE_DECLARE_TYPE(RedClient, red_client, CLIENT); -#define RED_TYPE_CLIENT red_client_get_type() - RedClient *red_client_new(RedsState *reds, int migrated); -struct RedClient: public GObject +class RedClient final { +public: + SPICE_CXX_GLIB_ALLOCATOR + + RedClient(RedsState *reds, bool migrated); +protected: + ~RedClient(); + +public: + void ref() { g_atomic_int_inc(&_ref); } + void unref() { if (g_atomic_int_dec_and_test(&_ref)) delete this; } + /* * disconnects all the client's channels (should be called from the client's thread) */ @@ -59,7 +65,10 @@ struct RedClient: public GObject void set_disconnecting(); RedsState* get_server(); - RedsState *reds; +private: + RedChannelClient *get_channel(int type, int id); + + RedsState *const reds; GList *channels; MainChannelClient *mcc; pthread_mutex_t lock; // different channels can be in different threads @@ -77,8 +86,8 @@ struct RedClient: public GObject int during_target_migrate; int seamless_migrate; int num_migrated_channels; /* for seamless - number of channels that wait for migrate data*/ - void ref() { g_object_ref(this); } - void unref() { g_object_unref(this); } + + gint _ref = 1; }; #include "pop-visibility.h"