red-client: Make RedClient pure C++

Remove GObject.
Add access protection.

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
This commit is contained in:
Frediano Ziglio 2020-03-05 10:21:43 +00:00 committed by Frediano Ziglio
parent cc86a7fb53
commit fef97b14e5
2 changed files with 33 additions and 110 deletions

View File

@ -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,

View File

@ -19,19 +19,25 @@
#ifndef RED_CLIENT_H_
#define RED_CLIENT_H_
#include <glib-object.h>
#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"