diff options
author | Olivier CrĂȘte <olivier.crete@collabora.com> | 2018-10-28 14:46:11 +0000 |
---|---|---|
committer | Olivier CrĂȘte <olivier.crete@collabora.com> | 2018-10-28 15:38:45 +0000 |
commit | a4b82ce49ada44f82ae4de21ce2ce72bf4ce1c8c (patch) | |
tree | f3495610982599e3b265c2a894488f7aead9d710 /agent | |
parent | d2cdf2e284c04e633f6703945c591db7b75423d3 (diff) | |
download | libnice-a4b82ce49ada44f82ae4de21ce2ce72bf4ce1c8c.tar.gz |
component: Replace agent pointer with weak reference
This should make it safer.
Diffstat (limited to 'agent')
-rw-r--r-- | agent/agent.c | 71 | ||||
-rw-r--r-- | agent/component.c | 101 | ||||
-rw-r--r-- | agent/component.h | 11 | ||||
-rw-r--r-- | agent/conncheck.c | 10 | ||||
-rw-r--r-- | agent/stream.c | 4 | ||||
-rw-r--r-- | agent/stream.h | 2 |
6 files changed, 126 insertions, 73 deletions
diff --git a/agent/agent.c b/agent/agent.c index 9e5af2e..ed3bfd5 100644 --- a/agent/agent.c +++ b/agent/agent.c @@ -1625,12 +1625,18 @@ static void pseudo_tcp_socket_opened (PseudoTcpSocket *sock, gpointer user_data) { NiceComponent *component = user_data; - NiceAgent *agent = component->agent; + NiceAgent *agent; + + agent = g_weak_ref_get (&component->agent_ref); + if (agent == NULL) + return; nice_debug ("Agent %p: s%d:%d pseudo Tcp socket Opened", agent, component->stream_id, component->id); agent_signal_socket_writable (agent, component); + + g_object_unref (agent); } /* Will attempt to queue all @n_messages into the pseudo-TCP transmission @@ -1784,17 +1790,18 @@ static void pseudo_tcp_socket_readable (PseudoTcpSocket *sock, gpointer user_data) { NiceComponent *component = user_data; - NiceAgent *agent = component->agent; + NiceAgent *agent; gboolean has_io_callback; NiceStream *stream = NULL; guint stream_id = component->stream_id; guint component_id = component->id; - g_object_ref (agent); + agent = g_weak_ref_get (&component->agent_ref); + if (agent == NULL) + return; if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) { - g_object_unref (agent); goto out; } @@ -1850,7 +1857,7 @@ pseudo_tcp_socket_readable (PseudoTcpSocket *sock, gpointer user_data) break; } - nice_component_emit_io_callback (component, buf, len); + nice_component_emit_io_callback (agent, component, buf, len); if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) { @@ -1915,12 +1922,18 @@ static void pseudo_tcp_socket_writable (PseudoTcpSocket *sock, gpointer user_data) { NiceComponent *component = user_data; - NiceAgent *agent = component->agent; + NiceAgent *agent; + + agent = g_weak_ref_get (&component->agent_ref); + if (agent == NULL) + return; nice_debug_verbose ("Agent %p: s%d:%d pseudo Tcp socket writable", agent, component->stream_id, component->id); agent_signal_socket_writable (agent, component); + + g_object_unref (agent); } static void @@ -1928,12 +1941,18 @@ pseudo_tcp_socket_closed (PseudoTcpSocket *sock, guint32 err, gpointer user_data) { NiceComponent *component = user_data; - NiceAgent *agent = component->agent; + NiceAgent *agent; + + agent = g_weak_ref_get (&component->agent_ref); + if (agent == NULL) + return; nice_debug ("Agent %p: s%d:%d pseudo Tcp socket closed. " "Calling priv_pseudo_tcp_error().", agent, component->stream_id, component->id); priv_pseudo_tcp_error (agent, component); + + g_object_unref (agent); } @@ -1942,6 +1961,11 @@ pseudo_tcp_socket_write_packet (PseudoTcpSocket *psocket, const gchar *buffer, guint32 len, gpointer user_data) { NiceComponent *component = user_data; + NiceAgent *agent; + + agent = g_weak_ref_get (&component->agent_ref); + if (agent == NULL) + return WR_FAIL; if (component->selected_pair.local != NULL) { NiceSocket *sock; @@ -1956,7 +1980,7 @@ pseudo_tcp_socket_write_packet (PseudoTcpSocket *psocket, nice_debug_verbose ( "Agent %p : s%d:%d: sending %d bytes on socket %p (FD %d) to [%s]:%d", - component->agent, component->stream_id, component->id, len, + agent, component->stream_id, component->id, len, sock->fileno, g_socket_get_fd (sock->fileno), tmpbuf, nice_address_get_port (addr)); } @@ -1968,13 +1992,16 @@ pseudo_tcp_socket_write_packet (PseudoTcpSocket *psocket, * its transmission rate and, hopefully, the usage of system resources * which caused the EWOULDBLOCK in the first place. */ if (nice_socket_send (sock, addr, len, buffer) >= 0) { + g_object_unref (agent); return WR_SUCCESS; } } else { nice_debug ("%s: WARNING: Failed to send pseudo-TCP packet from agent %p " - "as no pair has been selected yet.", G_STRFUNC, component->agent); + "as no pair has been selected yet.", G_STRFUNC, agent); } + g_object_unref (agent); + return WR_FAIL; } @@ -2032,7 +2059,11 @@ void _tcp_sock_is_writable (NiceSocket *sock, gpointer user_data) { NiceComponent *component = user_data; - NiceAgent *agent = component->agent; + NiceAgent *agent; + + agent = g_weak_ref_get (&component->agent_ref); + if (agent == NULL) + return; agent_lock (agent); @@ -2049,6 +2080,8 @@ _tcp_sock_is_writable (NiceSocket *sock, gpointer user_data) agent_signal_socket_writable (agent, component); agent_unlock_and_emit (agent); + + g_object_unref (agent); } static const gchar * @@ -3216,7 +3249,7 @@ nice_agent_remove_stream ( /* Remove the stream and signal its removal. */ agent->streams = g_slist_remove (agent->streams, stream); - nice_stream_close (stream); + nice_stream_close (agent, stream); if (!agent->streams) priv_remove_keepalive_timer (agent); @@ -5073,7 +5106,7 @@ nice_agent_dispose (GObject *object) { NiceStream *s = i->data; - nice_stream_close (s); + nice_stream_close (agent, s); g_object_unref (s); } @@ -5133,7 +5166,10 @@ component_io_cb (GSocket *gsocket, GIOCondition condition, gpointer user_data) gboolean remove_source = FALSE; component = socket_source->component; - agent = component->agent; + + agent = g_weak_ref_get (&component->agent_ref); + if (agent == NULL) + return G_SOURCE_REMOVE; agent_lock (agent); @@ -5143,6 +5179,7 @@ component_io_cb (GSocket *gsocket, GIOCondition condition, gpointer user_data) nice_debug ("%s: stream %d destroyed", G_STRFUNC, component->stream_id); agent_unlock (agent); + g_object_unref (agent); return G_SOURCE_REMOVE; } @@ -5151,11 +5188,10 @@ component_io_cb (GSocket *gsocket, GIOCondition condition, gpointer user_data) nice_debug ("%s: source %p destroyed", G_STRFUNC, g_main_current_source ()); agent_unlock (agent); + g_object_unref (agent); return G_SOURCE_REMOVE; } - g_object_ref (agent); - /* Remove disconnected sockets when we get a HUP */ if (condition & G_IO_HUP) { nice_debug ("Agent %p: NiceSocket %p has received HUP", agent, @@ -5279,7 +5315,8 @@ component_io_cb (GSocket *gsocket, GIOCondition condition, gpointer user_data) " bytes", G_STRFUNC, agent, local_message.length); if (local_message.length > 0) { - nice_component_emit_io_callback (component, local_buf, local_message.length); + nice_component_emit_io_callback (agent, component, local_buf, + local_message.length); } } @@ -5466,7 +5503,7 @@ nice_agent_set_selected_pair ( NICE_COMPONENT_STATE_READY); /* step: set the selected pair */ - nice_component_update_selected_pair (component, &pair); + nice_component_update_selected_pair (agent, component, &pair); agent_signal_new_selected_pair (agent, stream_id, component_id, pair.local, pair.remote); diff --git a/agent/component.c b/agent/component.c index 6a03ead..2623f4c 100644 --- a/agent/component.c +++ b/agent/component.c @@ -183,27 +183,27 @@ nice_component_remove_socket (NiceAgent *agent, NiceComponent *cmp, if (candidate == cmp->selected_pair.local) { nice_component_clear_selected_pair (cmp); - agent_signal_component_state_change (cmp->agent, cmp->stream_id, + agent_signal_component_state_change (agent, cmp->stream_id, cmp->id, NICE_COMPONENT_STATE_FAILED); } - refresh_prune_candidate (cmp->agent, candidate); + refresh_prune_candidate (agent, candidate); if (candidate->sockptr != nsocket && stream) { - discovery_prune_socket (cmp->agent, candidate->sockptr); - conn_check_prune_socket (cmp->agent, stream, cmp, + discovery_prune_socket (agent, candidate->sockptr); + conn_check_prune_socket (agent, stream, cmp, candidate->sockptr); nice_component_detach_socket (cmp, candidate->sockptr); } - agent_remove_local_candidate (cmp->agent, candidate); + agent_remove_local_candidate (agent, candidate); nice_candidate_free (candidate); cmp->local_candidates = g_slist_delete_link (cmp->local_candidates, i); i = next; } - discovery_prune_socket (cmp->agent, nsocket); + discovery_prune_socket (agent, nsocket); if (stream) - conn_check_prune_socket (cmp->agent, stream, cmp, nsocket); + conn_check_prune_socket (agent, stream, cmp, nsocket); nice_component_detach_socket (cmp, nsocket); } @@ -238,10 +238,10 @@ nice_component_clean_turn_servers (NiceAgent *agent, NiceComponent *cmp) */ if (candidate == cmp->selected_pair.local) { if (cmp->turn_candidate) { - refresh_prune_candidate (cmp->agent, cmp->turn_candidate); - discovery_prune_socket (cmp->agent, cmp->turn_candidate->sockptr); + refresh_prune_candidate (agent, cmp->turn_candidate); + discovery_prune_socket (agent, cmp->turn_candidate->sockptr); if (stream) - conn_check_prune_socket (cmp->agent, stream, cmp, + conn_check_prune_socket (agent, stream, cmp, cmp->turn_candidate->sockptr); nice_component_detach_socket (cmp, cmp->turn_candidate->sockptr); nice_candidate_free (cmp->turn_candidate); @@ -252,13 +252,13 @@ nice_component_clean_turn_servers (NiceAgent *agent, NiceComponent *cmp) cmp->selected_pair.priority = 0; cmp->turn_candidate = candidate; } else { - refresh_prune_candidate (cmp->agent, candidate); - discovery_prune_socket (cmp->agent, candidate->sockptr); + refresh_prune_candidate (agent, candidate); + discovery_prune_socket (agent, candidate->sockptr); if (stream) - conn_check_prune_socket (cmp->agent, stream, cmp, + conn_check_prune_socket (agent, stream, cmp, candidate->sockptr); nice_component_detach_socket (cmp, candidate->sockptr); - agent_remove_local_candidate (cmp->agent, candidate); + agent_remove_local_candidate (agent, candidate); nice_candidate_free (candidate); } cmp->local_candidates = g_slist_delete_link (cmp->local_candidates, i); @@ -281,7 +281,7 @@ nice_component_clear_selected_pair (NiceComponent *component) /* Must be called with the agent lock held as it touches internal Component * state. */ void -nice_component_close (NiceComponent *cmp) +nice_component_close (NiceAgent *agent, NiceComponent *cmp) { IOCallbackData *data; GOutputVector *vec; @@ -309,7 +309,7 @@ nice_component_close (NiceComponent *cmp) cmp->turn_candidate = NULL; while (cmp->local_candidates) { - agent_remove_local_candidate (cmp->agent, cmp->local_candidates->data); + agent_remove_local_candidate (agent, cmp->local_candidates->data); nice_candidate_free (cmp->local_candidates->data); cmp->local_candidates = g_slist_delete_link (cmp->local_candidates, cmp->local_candidates); @@ -323,7 +323,7 @@ nice_component_close (NiceComponent *cmp) (GDestroyNotify) incoming_check_free); cmp->incoming_checks = NULL; - nice_component_clean_turn_servers (cmp->agent, cmp); + nice_component_clean_turn_servers (agent, cmp); if (cmp->tcp_clock) { g_source_destroy (cmp->tcp_clock); @@ -426,14 +426,14 @@ nice_component_restart (NiceComponent *cmp) * emit the "selected-pair-changed" signal. */ void -nice_component_update_selected_pair (NiceComponent *component, const CandidatePair *pair) +nice_component_update_selected_pair (NiceAgent *agent, NiceComponent *component, const CandidatePair *pair) { NiceStream *stream; g_assert (component); g_assert (pair); - stream = agent_find_stream (component->agent, component->stream_id); + stream = agent_find_stream (agent, component->stream_id); nice_debug ("setting SELECTED PAIR for component %u: %s:%s (prio:%" G_GUINT64_FORMAT ").", component->id, pair->local->foundation, @@ -441,11 +441,11 @@ nice_component_update_selected_pair (NiceComponent *component, const CandidatePa if (component->selected_pair.local && component->selected_pair.local == component->turn_candidate) { - refresh_prune_candidate (component->agent, component->turn_candidate); - discovery_prune_socket (component->agent, + refresh_prune_candidate (agent, component->turn_candidate); + discovery_prune_socket (agent, component->turn_candidate->sockptr); if (stream) - conn_check_prune_socket (component->agent, stream, component, + conn_check_prune_socket (agent, stream, component, component->turn_candidate->sockptr); nice_component_detach_socket (component, component->turn_candidate->sockptr); nice_candidate_free (component->turn_candidate); @@ -459,7 +459,7 @@ nice_component_update_selected_pair (NiceComponent *component, const CandidatePa component->selected_pair.priority = pair->priority; component->selected_pair.prflx_priority = pair->prflx_priority; - nice_component_add_valid_candidate (component, pair->remote); + nice_component_add_valid_candidate (agent, component, pair->remote); } /* @@ -590,8 +590,8 @@ nice_component_attach_socket (NiceComponent *component, NiceSocket *nicesock) } /* Create and attach a source */ - nice_debug ("Component %p (agent %p): Attach source (stream %u).", - component, component->agent, component->stream_id); + nice_debug ("Component %p: Attach source (stream %u).", + component, component->stream_id); socket_source_attach (socket_source, component->ctx); } @@ -809,9 +809,11 @@ emit_io_callback_cb (gpointer user_data) guint stream_id, component_id; NiceAgent *agent; - agent = component->agent; - - g_object_ref (agent); + agent = g_weak_ref_get (&component->agent_ref); + if (agent == NULL) { + nice_debug ("Agent for component %p is gone", component); + return FALSE; + } stream_id = component->stream_id; component_id = component->id; @@ -872,10 +874,9 @@ emit_io_callback_cb (gpointer user_data) /* This must be called with the agent lock *held*. */ void -nice_component_emit_io_callback (NiceComponent *component, +nice_component_emit_io_callback (NiceAgent *agent, NiceComponent *component, const guint8 *buf, gsize buf_len) { - NiceAgent *agent; guint stream_id, component_id; NiceAgentRecvFunc io_callback; gpointer io_user_data; @@ -884,7 +885,6 @@ nice_component_emit_io_callback (NiceComponent *component, g_assert (buf != NULL); g_assert (buf_len > 0); - agent = component->agent; stream_id = component->stream_id; component_id = component->id; @@ -1044,7 +1044,7 @@ nice_component_init (NiceComponent *component) component->state = NICE_COMPONENT_STATE_DISCONNECTED; component->restart_candidate = NULL; component->tcp = NULL; - component->agent = NULL; + g_weak_ref_init (&component->agent_ref, NULL); g_mutex_init (&component->io_mutex); g_queue_init (&component->pending_io_messages); @@ -1071,11 +1071,15 @@ static void nice_component_constructed (GObject *obj) { NiceComponent *component; + NiceAgent *agent; component = NICE_COMPONENT (obj); - g_assert (component->agent != NULL); - nice_agent_init_stun_agent (component->agent, &component->stun_agent); + agent = g_weak_ref_get (&component->agent_ref); + g_assert (agent != NULL); + nice_agent_init_stun_agent (agent, &component->stun_agent); + + g_object_unref (agent); G_OBJECT_CLASS (nice_component_parent_class)->constructed (obj); } @@ -1095,14 +1099,25 @@ nice_component_get_property (GObject *obj, break; case PROP_AGENT: - g_value_set_object (value, component->agent); - break; + { + NiceAgent *agent; + agent = g_weak_ref_get (&component->agent_ref); + if (agent) + g_value_take_object (value, agent); + break; + } case PROP_STREAM: { - NiceStream *stream = agent_find_stream (component->agent, - component->stream_id); - g_value_set_object (value, stream); + NiceAgent *agent; + NiceStream *stream = NULL; + + agent = g_weak_ref_get (&component->agent_ref); + if (agent) { + stream = agent_find_stream (agent, component->stream_id); + g_value_set_object (value, stream); + g_object_unref (agent); + } break; } default: @@ -1125,7 +1140,7 @@ nice_component_set_property (GObject *obj, break; case PROP_AGENT: - component->agent = g_value_get_object (value); + g_weak_ref_set (&component->agent_ref, g_value_get_object (value)); break; case PROP_STREAM: @@ -1174,6 +1189,8 @@ nice_component_finalize (GObject *obj) g_main_context_unref (cmp->own_ctx); + g_weak_ref_clear (&cmp->agent_ref); + g_atomic_int_inc (&n_components_destroyed); nice_debug ("Destroyed NiceComponent (%u created, %u destroyed)", n_components_created, n_components_destroyed); @@ -1473,7 +1490,7 @@ turn_server_unref (TurnServer *turn) } void -nice_component_add_valid_candidate (NiceComponent *component, +nice_component_add_valid_candidate (NiceAgent *agent, NiceComponent *component, const NiceCandidate *candidate) { guint count = 0; @@ -1494,7 +1511,7 @@ nice_component_add_valid_candidate (NiceComponent *component, char str[INET6_ADDRSTRLEN]; nice_address_to_string (&candidate->addr, str); nice_debug ("Agent %p : %d:%d Adding valid source" - " candidate: %s:%d trans: %d", component->agent, + " candidate: %s:%d trans: %d", agent, candidate->stream_id, candidate->component_id, str, nice_address_get_port (&candidate->addr), candidate->transport); } diff --git a/agent/component.h b/agent/component.h index 39486d9..a56826f 100644 --- a/agent/component.h +++ b/agent/component.h @@ -199,8 +199,7 @@ struct _NiceComponent { recv_messages */ GError **recv_buf_error; /* error information about failed reads */ - NiceAgent *agent; /* unowned, immutable: can be accessed without holding the - * agent lock */ + GWeakRef agent_ref; guint stream_id; StunAgent stun_agent; /* This stun agent is used to validate all stun requests */ @@ -236,7 +235,7 @@ NiceComponent * nice_component_new (guint component_id, NiceAgent *agent, NiceStream *stream); void -nice_component_close (NiceComponent *component); +nice_component_close (NiceAgent *agent, NiceComponent *component); gboolean nice_component_find_pair (NiceComponent *component, NiceAgent *agent, @@ -246,7 +245,7 @@ void nice_component_restart (NiceComponent *component); void -nice_component_update_selected_pair (NiceComponent *component, +nice_component_update_selected_pair (NiceAgent *agent, NiceComponent *component, const CandidatePair *pair); NiceCandidate * @@ -284,7 +283,7 @@ nice_component_set_io_callback (NiceComponent *component, NiceInputMessage *recv_messages, guint n_recv_messages, GError **error); void -nice_component_emit_io_callback (NiceComponent *component, +nice_component_emit_io_callback (NiceAgent *agent, NiceComponent *component, const guint8 *buf, gsize buf_len); gboolean nice_component_has_io_callback (NiceComponent *component); @@ -303,7 +302,7 @@ void turn_server_unref (TurnServer *turn); void -nice_component_add_valid_candidate (NiceComponent *component, +nice_component_add_valid_candidate (NiceAgent *agent, NiceComponent *component, const NiceCandidate *candidate); gboolean diff --git a/agent/conncheck.c b/agent/conncheck.c index 3993ef6..0821bdc 100644 --- a/agent/conncheck.c +++ b/agent/conncheck.c @@ -1732,7 +1732,7 @@ static gboolean priv_update_selected_pair (NiceAgent *agent, NiceComponent *comp cpair.priority = pair->priority; /* cpair.keepalive is not used by nice_component_update_selected_pair() */ - nice_component_update_selected_pair (component, &cpair); + nice_component_update_selected_pair (agent, component, &cpair); priv_conn_keepalive_tick_unlocked (agent); @@ -3041,7 +3041,7 @@ static CandidateCheckPair *priv_process_response_check_for_reflexive(NiceAgent * SET_PAIR_STATE (agent, p, NICE_CHECK_SUCCEEDED); priv_remove_pair_from_triggered_check_queue (agent, p); priv_free_all_stun_transactions (p, component); - nice_component_add_valid_candidate (component, remote_candidate); + nice_component_add_valid_candidate (agent, component, remote_candidate); } else { if (!local_cand) { @@ -3079,7 +3079,7 @@ static CandidateCheckPair *priv_process_response_check_for_reflexive(NiceAgent * } if (new_pair && new_pair->valid) - nice_component_add_valid_candidate (component, remote_candidate); + nice_component_add_valid_candidate (agent, component, remote_candidate); return new_pair; @@ -3165,7 +3165,7 @@ static gboolean priv_map_reply_to_conn_check_request (NiceAgent *agent, NiceStre nice_debug ("Agent %p : Mapped address not found", agent); SET_PAIR_STATE (agent, p, NICE_CHECK_SUCCEEDED); p->valid = TRUE; - nice_component_add_valid_candidate (component, p->remote); + nice_component_add_valid_candidate (agent, component, p->remote); } else ok_pair = priv_process_response_check_for_reflexive (agent, stream, component, p, sockptr, &sockaddr.addr, @@ -4203,7 +4203,7 @@ gboolean conn_check_handle_inbound_stun (NiceAgent *agent, NiceStream *stream, } } - nice_component_add_valid_candidate (component, remote_candidate); + nice_component_add_valid_candidate (agent, component, remote_candidate); priv_reply_to_conn_check (agent, stream, component, local_candidate, remote_candidate, from, nicesock, rbuf_len, &msg, use_candidate); diff --git a/agent/stream.c b/agent/stream.c index c1bd87b..80815a0 100644 --- a/agent/stream.c +++ b/agent/stream.c @@ -81,13 +81,13 @@ nice_stream_new (guint stream_id, guint n_components, NiceAgent *agent) } void -nice_stream_close (NiceStream *stream) +nice_stream_close (NiceAgent *agent, NiceStream *stream) { GSList *i; for (i = stream->components; i; i = i->next) { NiceComponent *component = i->data; - nice_component_close (component); + nice_component_close (agent, component); } } diff --git a/agent/stream.h b/agent/stream.h index f586ff8..de51217 100644 --- a/agent/stream.h +++ b/agent/stream.h @@ -101,7 +101,7 @@ NiceStream * nice_stream_new (guint stream_id, guint n_components, NiceAgent *agent); void -nice_stream_close (NiceStream *stream); +nice_stream_close (NiceAgent *agent, NiceStream *stream); NiceComponent * nice_stream_find_component_by_id (NiceStream *stream, guint id); |