Convert RedClient to GObject

Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
This commit is contained in:
Jonathon Jongsma 2016-10-26 14:47:36 -05:00 committed by Frediano Ziglio
parent bc8d967e67
commit fe1583a6a9
4 changed files with 124 additions and 39 deletions

View File

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

View File

@ -27,6 +27,7 @@
GLIST_FOREACH((_client ? (_client)->channels : NULL), _iter, RedChannelClient, _data)
struct RedClient {
GObject parent;
RedsState *reds;
GList *channels;
MainChannelClient *mcc;
@ -45,39 +46,111 @@ struct RedClient {
int during_target_migrate;
int seamless_migrate;
int num_migrated_channels; /* for seamless - number of channels that wait for migrate data*/
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;
}
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)
{
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();
}
RedClient *red_client_new(RedsState *reds, int migrated)
{
RedClient *client;
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;
return client;
return g_object_new (RED_TYPE_CLIENT,
"spice-server", reds,
"migrated", migrated,
NULL);
}
void red_client_set_migration_seamless(RedClient *client) // dest
@ -148,9 +221,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)
{

View File

@ -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;
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_destroy 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 */

View File

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