The timeout has a weak ref that should be enough.
GSList *local_addresses; /* list of NiceAddresses for local
interfaces */
GSList *streams; /* list of Stream objects */
+ GSList *pruning_streams; /* list of Streams current being shut down */
GMainContext *main_context; /* main context pointer */
guint next_candidate_id; /* id of next created candidate */
guint next_stream_id; /* id of next created candidate */
nice_stream_close (agent, stream);
- g_object_unref (agent);
+ agent->pruning_streams = g_slist_remove (agent->pruning_streams, stream);
agent_unlock (agent);
return;
}
- g_object_ref (agent);
-
/* note: remove items with matching stream_ids from both lists */
conn_check_prune_stream (agent, stream);
discovery_prune_stream (agent, stream_id);
refresh_prune_stream_async (agent, stream,
(NiceTimeoutLockedCallback) on_stream_refreshes_pruned);
+ agent->pruning_streams = g_slist_prepend (agent->pruning_streams, stream);
+
/* Remove the stream and signal its removal. */
agent->streams = g_slist_remove (agent->streams, stream);
agent->streams = g_slist_delete_link(agent->streams, agent->streams);
}
+ while (agent->pruning_streams) {
+ NiceStream *s = agent->pruning_streams->data;
+
+ nice_stream_close (agent, s);
+ g_object_unref (s);
+
+ agent->pruning_streams = g_slist_delete_link(agent->pruning_streams,
+ agent->pruning_streams);
+ }
+
while ((sig = g_queue_pop_head (&agent->pending_signals))) {
free_queued_signal (sig);
}
g_clear_pointer (&cand->tick_source, g_source_unref);
}
+ if (cand->destroy_source) {
+ g_source_destroy (cand->destroy_source);
+ g_source_unref (cand->destroy_source);
+ }
+
if (cand->destroy_cb) {
cand->destroy_cb (cand->destroy_cb_data);
}
cand->timer_source = NULL;
}
+ g_source_destroy (cand->destroy_source);
+ g_source_unref (cand->destroy_source);
+ cand->destroy_source = NULL;
+
username = (uint8_t *)cand->candidate->turn->username;
username_len = (size_t) strlen (cand->candidate->turn->username);
password = (uint8_t *)cand->candidate->turn->password;
for (it = refreshes; it; it = it->next) {
CandidateRefresh *cand = it->data;
- GSource *timeout_source = NULL;
if (cand->disposing)
continue;
cand->destroy_cb = (GDestroyNotify) on_refresh_removed;
cand->destroy_cb_data = data;
- agent_timeout_add_with_context( agent, &timeout_source,
- "TURN refresh remove async", timeout,
- refresh_remove_async, cand);
+ agent_timeout_add_with_context(agent, &cand->destroy_source,
+ "TURN refresh remove async", timeout, refresh_remove_async, cand);
- g_source_unref (timeout_source);
++data->items_to_free;
}
gboolean disposing;
GDestroyNotify destroy_cb;
gpointer destroy_cb_data;
+ GSource *destroy_source;
} CandidateRefresh;
void refresh_free (NiceAgent *agent, CandidateRefresh *refresh);