Commit ef2b58f6 authored by Philip Withnall's avatar Philip Withnall

agent: Turn Component into a GObject

This makes it reference-counted. This will be useful for allowing
GDatagramBased and GIOStream objects to hold references to the stream
and component they are interested in, allowing removal of the global
NiceAgent lock previously needed to look up the component for every I/O
operation.

Deprecate all the old methods until it’s properly namespaced.
Reviewed-by: default avatarOlivier Crête <olivier.crete@collabora.com>
Differential Revision: https://phabricator.freedesktop.org/D307
parent 1f084193
...@@ -59,6 +59,24 @@ static volatile unsigned int n_components_destroyed = 0; ...@@ -59,6 +59,24 @@ static volatile unsigned int n_components_destroyed = 0;
#include "discovery.h" #include "discovery.h"
#include "agent-priv.h" #include "agent-priv.h"
G_DEFINE_TYPE (NiceComponent, nice_component, G_TYPE_OBJECT);
typedef enum {
PROP_ID = 1,
PROP_AGENT,
PROP_STREAM,
} NiceComponentProperty;
static void
nice_component_constructed (GObject *obj);
static void
nice_component_get_property (GObject *obj,
guint property_id, GValue *value, GParamSpec *pspec);
static void
nice_component_set_property (GObject *obj,
guint property_id, const GValue *value, GParamSpec *pspec);
static void
nice_component_finalize (GObject *obj);
static void static void
component_schedule_io_callback (Component *component); component_schedule_io_callback (Component *component);
...@@ -124,43 +142,11 @@ socket_source_free (SocketSource *source) ...@@ -124,43 +142,11 @@ socket_source_free (SocketSource *source)
Component * Component *
component_new (guint id, NiceAgent *agent, Stream *stream) component_new (guint id, NiceAgent *agent, Stream *stream)
{ {
Component *component; return g_object_new (NICE_TYPE_COMPONENT,
"id", id,
g_atomic_int_inc (&n_components_created); "agent", agent,
nice_debug ("Created NiceComponent (%u created, %u destroyed)", "stream", stream,
n_components_created, n_components_destroyed); NULL);
component = g_slice_new0 (Component);
component->id = id;
component->state = NICE_COMPONENT_STATE_DISCONNECTED;
component->restart_candidate = NULL;
component->tcp = NULL;
component->agent = agent;
component->stream = stream;
nice_agent_init_stun_agent (agent, &component->stun_agent);
g_mutex_init (&component->io_mutex);
g_queue_init (&component->pending_io_messages);
component->io_callback_id = 0;
component->own_ctx = g_main_context_new ();
component->stop_cancellable = g_cancellable_new ();
component->stop_cancellable_source =
g_cancellable_source_new (component->stop_cancellable);
g_source_set_dummy_callback (component->stop_cancellable_source);
g_source_attach (component->stop_cancellable_source, component->own_ctx);
component->ctx = g_main_context_ref (component->own_ctx);
/* Start off with a fresh main context and all I/O paused. This
* will be updated when nice_agent_attach_recv() or nice_agent_recv_messages()
* are called. */
component_set_io_context (component, NULL);
component_set_io_callback (component, NULL, NULL, NULL, 0, NULL);
g_queue_init (&component->queued_tcp_packets);
return component;
} }
void void
...@@ -304,33 +290,7 @@ component_close (Component *cmp) ...@@ -304,33 +290,7 @@ component_close (Component *cmp)
void void
component_free (Component *cmp) component_free (Component *cmp)
{ {
/* Component should have been closed already. */ g_object_unref (cmp);
g_warn_if_fail (cmp->local_candidates == NULL);
g_warn_if_fail (cmp->remote_candidates == NULL);
g_warn_if_fail (cmp->incoming_checks == NULL);
g_clear_object (&cmp->tcp);
g_clear_object (&cmp->stop_cancellable);
g_clear_object (&cmp->iostream);
g_mutex_clear (&cmp->io_mutex);
if (cmp->stop_cancellable_source != NULL) {
g_source_destroy (cmp->stop_cancellable_source);
g_source_unref (cmp->stop_cancellable_source);
}
if (cmp->ctx != NULL) {
g_main_context_unref (cmp->ctx);
cmp->ctx = NULL;
}
g_main_context_unref (cmp->own_ctx);
g_slice_free (Component, cmp);
g_atomic_int_inc (&n_components_destroyed);
nice_debug ("Destroyed NiceComponent (%u created, %u destroyed)",
n_components_created, n_components_destroyed);
} }
/* /*
...@@ -938,6 +898,202 @@ component_deschedule_io_callback (Component *component) ...@@ -938,6 +898,202 @@ component_deschedule_io_callback (Component *component)
component->io_callback_id = 0; component->io_callback_id = 0;
} }
static void
nice_component_class_init (NiceComponentClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = nice_component_constructed;
object_class->get_property = nice_component_get_property;
object_class->set_property = nice_component_set_property;
object_class->finalize = nice_component_finalize;
/**
* NiceComponent:id:
*
* The unique numeric ID of the component.
*
* Since: UNRELEASED
*/
g_object_class_install_property (object_class, PROP_ID,
g_param_spec_uint (
"id",
"ID",
"The unique numeric ID of the component.",
1, G_MAXUINT, 1,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
/**
* NiceComponent:agent:
*
* The #NiceAgent this component belongs to.
*
* Since: UNRELEASED
*/
g_object_class_install_property (object_class, PROP_AGENT,
g_param_spec_object (
"agent",
"Agent",
"The NiceAgent this component belongs to.",
NICE_TYPE_AGENT,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
/**
* NiceComponent:stream:
*
* The #NiceStream this component belongs to.
*
* Since: UNRELEASED
*/
g_object_class_install_property (object_class, PROP_STREAM,
g_param_spec_object (
"stream",
"Stream",
"The NiceStream this component belongs to.",
NICE_TYPE_STREAM,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}
static void
nice_component_init (NiceComponent *component)
{
g_atomic_int_inc (&n_components_created);
nice_debug ("Created NiceComponent (%u created, %u destroyed)",
n_components_created, n_components_destroyed);
component->id = 0;
component->state = NICE_COMPONENT_STATE_DISCONNECTED;
component->restart_candidate = NULL;
component->tcp = NULL;
component->agent = NULL;
component->stream = NULL;
g_mutex_init (&component->io_mutex);
g_queue_init (&component->pending_io_messages);
component->io_callback_id = 0;
component->own_ctx = g_main_context_new ();
component->stop_cancellable = g_cancellable_new ();
component->stop_cancellable_source =
g_cancellable_source_new (component->stop_cancellable);
g_source_set_dummy_callback (component->stop_cancellable_source);
g_source_attach (component->stop_cancellable_source, component->own_ctx);
component->ctx = g_main_context_ref (component->own_ctx);
/* Start off with a fresh main context and all I/O paused. This
* will be updated when nice_agent_attach_recv() or nice_agent_recv_messages()
* are called. */
component_set_io_context (component, NULL);
component_set_io_callback (component, NULL, NULL, NULL, 0, NULL);
g_queue_init (&component->queued_tcp_packets);
}
static void
nice_component_constructed (GObject *obj)
{
NiceComponent *component;
component = NICE_COMPONENT (obj);
g_assert (component->agent != NULL);
nice_agent_init_stun_agent (component->agent, &component->stun_agent);
G_OBJECT_CLASS (nice_component_parent_class)->constructed (obj);
}
static void
nice_component_get_property (GObject *obj,
guint property_id, GValue *value, GParamSpec *pspec)
{
NiceComponent *component;
component = NICE_COMPONENT (obj);
switch ((NiceComponentProperty) property_id)
{
case PROP_ID:
g_value_set_uint (value, component->id);
break;
case PROP_AGENT:
g_value_set_object (value, component->agent);
break;
case PROP_STREAM:
g_value_set_object (value, component->stream);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
}
}
static void
nice_component_set_property (GObject *obj,
guint property_id, const GValue *value, GParamSpec *pspec)
{
NiceComponent *component;
component = NICE_COMPONENT (obj);
switch ((NiceComponentProperty) property_id)
{
case PROP_ID:
component->id = g_value_get_uint (value);
break;
case PROP_AGENT:
component->agent = g_value_get_object (value);
break;
case PROP_STREAM:
component->stream = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
}
}
/* Must be called with the agent lock released as it could dispose of
* NiceIOStreams. */
static void
nice_component_finalize (GObject *obj)
{
NiceComponent *cmp;
cmp = NICE_COMPONENT (obj);
/* Component should have been closed already. */
g_warn_if_fail (cmp->local_candidates == NULL);
g_warn_if_fail (cmp->remote_candidates == NULL);
g_warn_if_fail (cmp->incoming_checks == NULL);
g_clear_object (&cmp->tcp);
g_clear_object (&cmp->stop_cancellable);
g_clear_object (&cmp->iostream);
g_mutex_clear (&cmp->io_mutex);
if (cmp->stop_cancellable_source != NULL) {
g_source_destroy (cmp->stop_cancellable_source);
g_source_unref (cmp->stop_cancellable_source);
}
if (cmp->ctx != NULL) {
g_main_context_unref (cmp->ctx);
cmp->ctx = NULL;
}
g_main_context_unref (cmp->own_ctx);
g_atomic_int_inc (&n_components_destroyed);
nice_debug ("Destroyed NiceComponent (%u created, %u destroyed)",
n_components_created, n_components_destroyed);
G_OBJECT_CLASS (nice_component_parent_class)->finalize (obj);
}
/** /**
* ComponentSource: * ComponentSource:
* *
......
...@@ -42,7 +42,8 @@ ...@@ -42,7 +42,8 @@
#include <glib.h> #include <glib.h>
typedef struct _Component Component; typedef struct _Component Component G_GNUC_DEPRECATED_FOR(NiceComponent);
typedef Component NiceComponent;
#include "agent.h" #include "agent.h"
#include "agent-priv.h" #include "agent-priv.h"
...@@ -137,9 +138,23 @@ io_callback_data_new (const guint8 *buf, gsize buf_len); ...@@ -137,9 +138,23 @@ io_callback_data_new (const guint8 *buf, gsize buf_len);
void void
io_callback_data_free (IOCallbackData *data); io_callback_data_free (IOCallbackData *data);
#define NICE_TYPE_COMPONENT nice_component_get_type()
#define NICE_COMPONENT(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), NICE_TYPE_COMPONENT, NiceComponent))
#define NICE_COMPONENT_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), NICE_TYPE_COMPONENT, NiceComponentClass))
#define NICE_IS_COMPONENT(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), NICE_TYPE_COMPONENT))
#define NICE_IS_COMPONENT_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), NICE_TYPE_COMPONENT))
#define NICE_COMPONENT_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), NICE_TYPE_COMPONENT, NiceComponentClass))
struct _Component struct _Component
{ {
/*< private >*/
GObject parent;
NiceComponentType type; NiceComponentType type;
guint id; /* component id */ guint id; /* component id */
NiceComponentState state; NiceComponentState state;
...@@ -212,37 +227,58 @@ struct _Component ...@@ -212,37 +227,58 @@ struct _Component
GQueue queued_tcp_packets; GQueue queued_tcp_packets;
}; };
typedef struct {
GObjectClass parent_class;
} NiceComponentClass;
GType nice_component_get_type (void);
G_DEPRECATED
Component * Component *
component_new (guint component_id, NiceAgent *agent, Stream *stream); component_new (guint component_id, NiceAgent *agent, Stream *stream);
G_DEPRECATED
void void
component_close (Component *cmp); component_close (Component *cmp);
G_DEPRECATED_FOR(g_object_unref)
void void
component_free (Component *cmp); component_free (Component *cmp);
G_DEPRECATED
gboolean gboolean
component_find_pair (Component *cmp, NiceAgent *agent, const gchar *lfoundation, const gchar *rfoundation, CandidatePair *pair); component_find_pair (Component *cmp, NiceAgent *agent, const gchar *lfoundation, const gchar *rfoundation, CandidatePair *pair);
G_DEPRECATED
void void
component_restart (Component *cmp); component_restart (Component *cmp);
G_DEPRECATED
void void
component_update_selected_pair (Component *component, const CandidatePair *pair); component_update_selected_pair (Component *component, const CandidatePair *pair);
G_DEPRECATED
NiceCandidate * NiceCandidate *
component_find_remote_candidate (const Component *component, const NiceAddress *addr, NiceCandidateTransport transport); component_find_remote_candidate (const Component *component, const NiceAddress *addr, NiceCandidateTransport transport);
G_DEPRECATED
NiceCandidate * NiceCandidate *
component_set_selected_remote_candidate (NiceAgent *agent, Component *component, component_set_selected_remote_candidate (NiceAgent *agent, Component *component,
NiceCandidate *candidate); NiceCandidate *candidate);
G_DEPRECATED
void void
component_attach_socket (Component *component, NiceSocket *nsocket); component_attach_socket (Component *component, NiceSocket *nsocket);
G_DEPRECATED
void void
component_detach_socket (Component *component, NiceSocket *nsocket); component_detach_socket (Component *component, NiceSocket *nsocket);
G_DEPRECATED
void void
component_detach_all_sockets (Component *component); component_detach_all_sockets (Component *component);
G_DEPRECATED
void void
component_free_socket_sources (Component *component); component_free_socket_sources (Component *component);
...@@ -251,22 +287,26 @@ component_input_source_new (NiceAgent *agent, guint stream_id, ...@@ -251,22 +287,26 @@ component_input_source_new (NiceAgent *agent, guint stream_id,
guint component_id, GPollableInputStream *pollable_istream, guint component_id, GPollableInputStream *pollable_istream,
GCancellable *cancellable); GCancellable *cancellable);
G_DEPRECATED
GMainContext * GMainContext *
component_dup_io_context (Component *component); component_dup_io_context (Component *component);
G_DEPRECATED
void void
component_set_io_context (Component *component, GMainContext *context); component_set_io_context (Component *component, GMainContext *context);
G_DEPRECATED
void void
component_set_io_callback (Component *component, component_set_io_callback (Component *component,
NiceAgentRecvFunc func, gpointer user_data, NiceAgentRecvFunc func, gpointer user_data,
NiceInputMessage *recv_messages, guint n_recv_messages, NiceInputMessage *recv_messages, guint n_recv_messages,
GError **error); GError **error);
G_DEPRECATED
void void
component_emit_io_callback (Component *component, component_emit_io_callback (Component *component,
const guint8 *buf, gsize buf_len); const guint8 *buf, gsize buf_len);
G_DEPRECATED
gboolean gboolean
component_has_io_callback (Component *component); component_has_io_callback (Component *component);
G_DEPRECATED
void void
component_clean_turn_servers (Component *component); component_clean_turn_servers (Component *component);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment