diff --git a/daemon/call.c b/daemon/call.c index df7cfe956..0ff52fd37 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -75,6 +75,8 @@ static void __monologue_destroy(struct call_monologue *monologue, int recurse); static int monologue_destroy(struct call_monologue *ml); static struct timeval add_ongoing_calls_dur_in_interval(struct timeval *interval_start, struct timeval *interval_duration); +static void __call_free(void *p); +static void __call_cleanup(struct call *c); /* called with call->master_lock held in R */ static int call_timer_delete_monologues(struct call *c) { @@ -715,6 +717,17 @@ int call_init() { return 0; } +void call_free(void) { + GList *ll = g_hash_table_get_values(rtpe_callhash); + for (GList *l = ll; l; l = l->next) { + struct call *c = l->data; + __call_cleanup(c); + obj_put(c); + } + g_list_free(ll); + g_hash_table_destroy(rtpe_callhash); +} + void payload_type_free(struct rtp_payload_type *p) { @@ -2264,10 +2277,47 @@ static struct timeval add_ongoing_calls_dur_in_interval(struct timeval *interval return res; } +static void __call_cleanup(struct call *c) { + for (GList *l = c->streams.head; l; l = l->next) { + struct packet_stream *ps = l->data; + + send_timer_put(&ps->send_timer); + jb_put(&ps->jb); + __unkernelize(ps); + dtls_shutdown(ps); + ps->selected_sfd = NULL; + g_queue_clear(&ps->sfds); + crypto_cleanup(&ps->crypto); + + ps->rtp_sink = NULL; + ps->rtcp_sink = NULL; + } + + for (GList *l = c->medias.head; l; l = l->next) { + struct call_media *md = l->data; + ice_shutdown(&md->ice_agent); + t38_gateway_stop(md->t38_gateway); + t38_gateway_put(&md->t38_gateway); + } + + for (GList *l = c->monologues.head; l; l = l->next) { + struct call_monologue *ml = l->data; + media_player_stop(ml->player); + media_player_put(&ml->player); + } + + while (c->stream_fds.head) { + struct stream_fd *sfd = g_queue_pop_head(&c->stream_fds); + poller_del_item(rtpe_poller, sfd->socket.fd); + obj_put(sfd); + } + + recording_finish(c); +} + /* called lock-free, but must hold a reference to the call */ void call_destroy(struct call *c) { struct packet_stream *ps=0; - struct stream_fd *sfd; GList *l; int ret; struct call_monologue *ml; @@ -2412,41 +2462,7 @@ no_stats_output: cdr_update_entry(c); - for (l = c->streams.head; l; l = l->next) { - ps = l->data; - - send_timer_put(&ps->send_timer); - jb_put(&ps->jb); - __unkernelize(ps); - dtls_shutdown(ps); - ps->selected_sfd = NULL; - g_queue_clear(&ps->sfds); - crypto_cleanup(&ps->crypto); - - ps->rtp_sink = NULL; - ps->rtcp_sink = NULL; - } - - for (l = c->medias.head; l; l = l->next) { - md = l->data; - ice_shutdown(&md->ice_agent); - t38_gateway_stop(md->t38_gateway); - t38_gateway_put(&md->t38_gateway); - } - - for (l = c->monologues.head; l; l = l->next) { - ml = l->data; - media_player_stop(ml->player); - media_player_put(&ml->player); - } - - while (c->stream_fds.head) { - sfd = g_queue_pop_head(&c->stream_fds); - poller_del_item(rtpe_poller, sfd->socket.fd); - obj_put(sfd); - } - - recording_finish(c); + __call_cleanup(c); rwlock_unlock_w(&c->master_lock); } diff --git a/daemon/main.c b/daemon/main.c index ade1a5d83..ae41287e9 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -944,6 +944,7 @@ int main(int argc, char **argv) { unfill_initial_rtpe_cfg(&initial_rtpe_config); options_free(); + call_free(); interfaces_free(); return 0; diff --git a/include/call.h b/include/call.h index d92264172..ebe12f9ad 100644 --- a/include/call.h +++ b/include/call.h @@ -419,6 +419,7 @@ extern struct stats rtpe_stats; /* copied from statsps once a second */ int call_init(void); +void call_free(void); void call_get_all_calls(GQueue *q); struct call_monologue *__monologue_create(struct call *call);