diff options
author | Philip Withnall <philip.withnall@collabora.co.uk> | 2014-04-24 16:11:03 +0100 |
---|---|---|
committer | Philip Withnall <philip.withnall@collabora.co.uk> | 2014-04-25 08:00:12 +0100 |
commit | e1d19e27d185a2e6b5a8342ce505301511ab269a (patch) | |
tree | c3e05305b66f941828a4dab235164c690fec19f1 | |
parent | 1d17111ca20c2dec3b5e504bdb7dd6e5667f5ac9 (diff) |
agent: Simplify gathering-done stage of UPnP handling
This introduces no functional changes, but consolidates and documents
the code a bit more.
-rw-r--r-- | agent/agent.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/agent/agent.c b/agent/agent.c index 73ffb91..437bd57 100644 --- a/agent/agent.c +++ b/agent/agent.c @@ -1974,6 +1974,7 @@ static gboolean priv_upnp_timeout_cb (gpointer user_data) agent_lock(); + /* If the source has been destroyed, we have already freed all mappings. */ if (g_source_is_destroyed (g_main_current_source ())) { agent_unlock (); return FALSE; @@ -1981,9 +1982,29 @@ static gboolean priv_upnp_timeout_cb (gpointer user_data) nice_debug ("Agent %p : UPnP port mapping timed out", agent); + /* We cannot free priv->upnp here as it may be holding mappings open which + * we are using (e.g. if some mappings were successful and others errored). */ g_slist_free_full (agent->upnp_mapping, (GDestroyNotify) nice_address_free); agent->upnp_mapping = NULL; + agent_check_upnp_gathering_done (agent); + + agent_unlock_and_emit (agent); + return FALSE; +} + +/* Check whether UPnP gathering is done, which is true when the list of pending + * mappings (upnp_mapping) is empty. When it is empty, we have heard back from + * gupnp-igd about each of the mappings we added, either successfully or not. + * + * Note that upnp_mapping has to be a list, rather than a counter, as the + * mapped-external-port and error-mapping-port signals could be emitted multiple + * times for each mapping. */ +static void agent_check_upnp_gathering_done (NiceAgent *agent) +{ + if (agent->upnp_mapping != NULL) + return; + if (agent->upnp_timer_source != NULL) { g_source_destroy (agent->upnp_timer_source); g_source_unref (agent->upnp_timer_source); @@ -1991,9 +2012,6 @@ static gboolean priv_upnp_timeout_cb (gpointer user_data) } agent_gathering_done (agent); - - agent_unlock_and_emit (agent); - return FALSE; } static void _upnp_mapped_external_port (GUPnPSimpleIgd *self, gchar *proto, @@ -2049,14 +2067,7 @@ static void _upnp_mapped_external_port (GUPnPSimpleIgd *self, gchar *proto, } end: - if (agent->upnp_mapping == NULL) { - if (agent->upnp_timer_source != NULL) { - g_source_destroy (agent->upnp_timer_source); - g_source_unref (agent->upnp_timer_source); - agent->upnp_timer_source = NULL; - } - agent_gathering_done (agent); - } + agent_check_upnp_gathering_done (agent); agent_unlock_and_emit (agent); } @@ -2085,14 +2096,7 @@ static void _upnp_error_mapping_port (GUPnPSimpleIgd *self, GError *error, } } - if (agent->upnp_mapping == NULL) { - if (agent->upnp_timer_source != NULL) { - g_source_destroy (agent->upnp_timer_source); - g_source_unref (agent->upnp_timer_source); - agent->upnp_timer_source = NULL; - } - agent_gathering_done (agent); - } + agent_check_upnp_gathering_done (agent); } agent_unlock_and_emit (agent); |