agent: Make the TurnServer structure refcounted
authorOlivier Crête <olivier.crete@collabora.com>
Tue, 22 Apr 2014 21:05:57 +0000 (17:05 -0400)
committerOlivier Crête <olivier.crete@collabora.com>
Fri, 25 Apr 2014 01:04:31 +0000 (21:04 -0400)
Instead of just blindling assuming that all of the pointers are valid
until the end.

agent/agent.c
agent/candidate.c
agent/candidate.h
agent/component.c
agent/component.h
agent/discovery.c

index 824b016..35f2764 100644 (file)
@@ -1820,7 +1820,7 @@ priv_add_new_candidate_discovery_turn (NiceAgent *agent,
     component_attach_socket (component, cdisco->nicesock);
   }
 
-  cdisco->turn = turn;
+  cdisco->turn = turn_server_ref (turn);
   cdisco->server = turn->server;
 
   cdisco->stream = stream;
index 348d216..f326482 100644 (file)
@@ -80,6 +80,9 @@ nice_candidate_free (NiceCandidate *candidate)
   if (candidate->password)
     g_free (candidate->password);
 
+  if (candidate->turn)
+    turn_server_unref (candidate->turn);
+
   g_slice_free (NiceCandidate, candidate);
 }
 
@@ -180,6 +183,7 @@ nice_candidate_copy (const NiceCandidate *candidate)
 
   memcpy (copy, candidate, sizeof(NiceCandidate));
 
+  copy->turn = NULL;
   copy->username = g_strdup (copy->username);
   copy->password = g_strdup (copy->password);
 
index d6747d9..b5ee7e9 100644 (file)
@@ -129,6 +129,8 @@ typedef struct _TurnServer TurnServer;
  */
 struct _TurnServer
 {
+  gint ref_count;
+
   NiceAddress server;       /**< TURN server address */
   gchar *username;           /**< TURN username */
   gchar *password;           /**< TURN password */
index 9c82c0a..3cd4855 100644 (file)
@@ -148,15 +148,8 @@ component_new (guint id, NiceAgent *agent, Stream *stream)
 void
 component_clean_turn_servers (Component *cmp)
 {
-  GList *item;
 
-  for (item = cmp->turn_servers; item; item = g_list_next (item)) {
-    TurnServer *turn = item->data;
-    g_free (turn->username);
-    g_free (turn->password);
-    g_slice_free (TurnServer, turn);
-  }
-  g_list_free (cmp->turn_servers);
+  g_list_free_full (cmp->turn_servers, (GDestroyNotify) turn_server_unref);
   cmp->turn_servers = NULL;
 }
 
@@ -1080,6 +1073,7 @@ turn_server_new (const gchar *server_ip, guint server_port,
 
   nice_address_init (&turn->server);
 
+  turn->ref_count = 1;
   if (nice_address_set_from_string (&turn->server, server_ip)) {
     nice_address_set_port (&turn->server, server_port);
   } else {
@@ -1092,3 +1086,23 @@ turn_server_new (const gchar *server_ip, guint server_port,
 
   return turn;
 }
+
+TurnServer *
+turn_server_ref (TurnServer *turn)
+{
+  turn->ref_count++;
+
+  return turn;
+}
+
+void
+turn_server_unref (TurnServer *turn)
+{
+  turn->ref_count--;
+
+  if (turn->ref_count == 0) {
+    g_free (turn->username);
+    g_free (turn->password);
+    g_slice_free (TurnServer, turn);
+  }
+}
index 699118a..b1e6507 100644 (file)
@@ -265,6 +265,13 @@ TurnServer *
 turn_server_new (const gchar *server_ip, guint server_port,
     const gchar *username, const gchar *password, NiceRelayType type);
 
+TurnServer *
+turn_server_ref (TurnServer *turn);
+
+void
+turn_server_unref (TurnServer *turn);
+
+
 G_END_DECLS
 
 #endif /* _NICE_COMPONENT_H */
index 35c5a7a..6866f57 100644 (file)
@@ -74,6 +74,9 @@ static inline int priv_timer_expired (GTimeVal *timer, GTimeVal *now)
  */
 static void discovery_free_item (CandidateDiscovery *cand)
 {
+  if (cand->turn)
+    turn_server_unref (cand->turn);
+
   g_slice_free (CandidateDiscovery, cand);
 }
 
@@ -584,7 +587,7 @@ discovery_add_relay_candidate (
   candidate->stream_id = stream_id;
   candidate->component_id = component_id;
   candidate->addr = *address;
-  candidate->turn = turn;
+  candidate->turn = turn_server_ref (turn);
 
   /* step: link to the base candidate+socket */
   relay_socket = nice_turn_socket_new (agent->main_context, address,