Commit 1b0efa66 authored by Olivier Crête's avatar Olivier Crête
Browse files

pseudotcp: Use weak ref for internal GSources

parent c0272f55
......@@ -1234,6 +1234,28 @@ queue_rst_message (PseudoTcpSocket *self)
queue (self, "", 0, FLAG_RST);
}
typedef struct _PseudoTcpSocketWeakRef {
GWeakRef ref;
} PseudoTcpSocketWeakRef;
static PseudoTcpSocketWeakRef *
pseudo_tcp_weak_ref_new (PseudoTcpSocket *self)
{
PseudoTcpSocketWeakRef *weak = g_slice_new0 (PseudoTcpSocketWeakRef);
g_weak_ref_init (&weak->ref, self);
return weak;
}
static void
pseudo_tcp_weak_ref_free (PseudoTcpSocketWeakRef *weak)
{
g_weak_ref_clear (&weak->ref);
g_slice_free (PseudoTcpSocketWeakRef, weak);
}
static gboolean
pseudo_tcp_socket_listen_locked (PseudoTcpSocket *self)
{
......@@ -1255,7 +1277,9 @@ pseudo_tcp_socket_listen_locked (PseudoTcpSocket *self)
priv->base_source = g_source_ref (source);
g_source_set_name (priv->base_source, "Pseudo-TCP base");
g_source_set_callback (priv->base_source,
(GSourceFunc) notify_pseudo_tcp_socket_base, self, NULL);
(GSourceFunc) notify_pseudo_tcp_socket_base,
pseudo_tcp_weak_ref_new (self),
(GDestroyNotify) pseudo_tcp_weak_ref_free);
g_source_attach (priv->base_source, priv->main_context);
g_source_unref (source);
}
......@@ -1501,17 +1525,19 @@ pseudo_tcp_socket_notify_packet(PseudoTcpSocket *self,
return FALSE;
}
g_rec_mutex_lock (&self->priv->mutex);
/* Hold a reference to the PseudoTcpSocket during parsing, since it may be
* closed from within a callback. */
g_object_ref (self);
g_rec_mutex_lock (&self->priv->mutex);
retval = parse (self, (guint8 *) buffer, HEADER_SIZE,
(guint8 *) buffer + HEADER_SIZE, len - HEADER_SIZE);
g_object_unref (self);
g_rec_mutex_unlock (&self->priv->mutex);
g_object_unref (self);
return retval;
}
......@@ -1520,12 +1546,13 @@ static gboolean
notify_pseudo_tcp_socket_base (GDatagramBased *datagram_based,
GIOCondition condition, gpointer user_data)
{
PseudoTcpSocketWeakRef *weak = user_data;
PseudoTcpSocket *self;
gboolean would_block = FALSE, has_errored = FALSE, has_closed = FALSE;
self = user_data;
self = g_weak_ref_get (&weak->ref);
if (g_source_is_destroyed (g_main_current_source ())) {
if (g_source_is_destroyed (g_main_current_source ()) || self == NULL) {
DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Source was destroyed. "
"Avoided race condition in notify_pseudo_tcp_socket_base.");
return G_SOURCE_REMOVE;
......@@ -1535,7 +1562,6 @@ notify_pseudo_tcp_socket_base (GDatagramBased *datagram_based,
/* Hold a reference to the PseudoTcpSocket during parsing, since it may be
* closed from within a callback. */
g_object_ref (self);
while (!would_block && !has_errored && !has_closed) {
#define TCP_HEADER_SIZE 24 /* bytes */
......@@ -1633,10 +1659,10 @@ notify_pseudo_tcp_socket_base (GDatagramBased *datagram_based,
closedown (self, EPIPE, CLOSEDOWN_LOCAL);
}
g_object_unref (self);
g_rec_mutex_unlock (&self->priv->mutex);
g_object_unref (self);
return (has_errored || has_closed) ? G_SOURCE_REMOVE : G_SOURCE_CONTINUE;
}
......@@ -2675,12 +2701,14 @@ done:
static gboolean
notify_pseudo_tcp_socket_clock (gpointer user_data)
{
PseudoTcpSocketWeakRef *weak = user_data;
PseudoTcpSocket *self;
self = user_data;
self = g_weak_ref_get (&weak->ref);
if (g_source_is_destroyed (g_main_current_source ())) {
nice_debug ("Source was destroyed. "
if (g_source_is_destroyed (g_main_current_source ()) ||
self == NULL) {
nice_debug ("Source or socket was destroyed. "
"Avoided race condition in notify_pseudo_tcp_socket_clock");
return G_SOURCE_REMOVE;
}
......@@ -2690,6 +2718,8 @@ notify_pseudo_tcp_socket_clock (gpointer user_data)
adjust_tcp_clock (self);
g_rec_mutex_unlock (&self->priv->mutex);
g_object_unref (self);
return G_SOURCE_CONTINUE;
}
......@@ -2739,7 +2769,9 @@ adjust_tcp_clock (PseudoTcpSocket *self)
g_source_set_name (priv->tcp_clock_source, "Pseudo-TCP clock");
g_source_set_callback (priv->tcp_clock_source,
(GSourceFunc) notify_pseudo_tcp_socket_clock, self, NULL);
(GSourceFunc) notify_pseudo_tcp_socket_clock,
pseudo_tcp_weak_ref_new (self),
(GDestroyNotify) pseudo_tcp_weak_ref_free);
g_source_attach (priv->tcp_clock_source, priv->main_context);
}
}
......
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