From 759520a6f180a638027fdc7be58e12772247fe47 Mon Sep 17 00:00:00 2001 From: Nanang Izzuddin Date: Thu, 22 Mar 2012 11:29:20 +0000 Subject: Close #1466 (using PJLIB outside PJSUA-LIB context): - static reference counter for PJLIB init/shutdown. - implemented atexit() in PJMEDIA and PJSIP level: pjmedia_endpt_atexit() & pjsip_endpt_atexit(). - updated pjmedia/transport_srtp.c, pjsip/sip_timer.c, and pjsip/sip_replaces.c to use the new atexit() functions. - API change: pjmedia_srtp_init_lib() now requires 'pjmedia_endpt' param. git-svn-id: http://svn.pjsip.org/repos/pjproject/branches/1.x@3986 74dad513-b988-da41-8d7b-12977e46ad98 --- pjmedia/src/pjmedia/endpoint.c | 43 ++++++++++++++++++++++++++++++++++++ pjmedia/src/pjmedia/transport_srtp.c | 20 ++++++++++++----- 2 files changed, 58 insertions(+), 5 deletions(-) (limited to 'pjmedia/src') diff --git a/pjmedia/src/pjmedia/endpoint.c b/pjmedia/src/pjmedia/endpoint.c index a9adfc2b..43ed4ccf 100644 --- a/pjmedia/src/pjmedia/endpoint.c +++ b/pjmedia/src/pjmedia/endpoint.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,14 @@ static int PJ_THREAD_FUNC worker_proc(void*); #define MAX_THREADS 16 +/* List of media endpoint exit callback. */ +typedef struct exit_cb +{ + PJ_DECL_LIST_MEMBER (struct exit_cb); + pjmedia_endpt_exit_callback func; +} exit_cb; + + /** Concrete declaration of media endpoint. */ struct pjmedia_endpt { @@ -85,6 +94,9 @@ struct pjmedia_endpt /** Is telephone-event enable */ pj_bool_t has_telephone_event; + + /** List of exit callback. */ + exit_cb exit_cb_list; }; /** @@ -128,6 +140,9 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create(pj_pool_factory *pf, if (status != PJ_SUCCESS) goto on_error; + /* Initialize exit callback list. */ + pj_list_init(&endpt->exit_cb_list); + /* Create ioqueue if none is specified. */ if (endpt->ioqueue == NULL) { @@ -188,6 +203,7 @@ PJ_DEF(pjmedia_codec_mgr*) pjmedia_endpt_get_codec_mgr(pjmedia_endpt *endpt) */ PJ_DEF(pj_status_t) pjmedia_endpt_destroy (pjmedia_endpt *endpt) { + exit_cb *ecb; unsigned i; PJ_ASSERT_RETURN(endpt, PJ_EINVAL); @@ -203,6 +219,13 @@ PJ_DEF(pj_status_t) pjmedia_endpt_destroy (pjmedia_endpt *endpt) } } + /* Call all registered exit callbacks */ + ecb = endpt->exit_cb_list.next; + while (ecb != &endpt->exit_cb_list) { + (*ecb->func)(endpt); + ecb = ecb->next; + } + /* Destroy internal ioqueue */ if (endpt->ioqueue && endpt->own_ioqueue) { pj_ioqueue_destroy(endpt->ioqueue); @@ -628,3 +651,23 @@ PJ_DEF(pj_status_t) pjmedia_endpt_dump(pjmedia_endpt *endpt) return PJ_SUCCESS; } + +PJ_DEF(pj_status_t) pjmedia_endpt_atexit( pjmedia_endpt *endpt, + pjmedia_endpt_exit_callback func) +{ + exit_cb *new_cb; + + PJ_ASSERT_RETURN(endpt && func, PJ_EINVAL); + + if (endpt->quit_flag) + return PJ_EINVALIDOP; + + new_cb = PJ_POOL_ZALLOC_T(endpt->pool, exit_cb); + new_cb->func = func; + + pj_enter_critical_section(); + pj_list_push_back(&endpt->exit_cb_list, new_cb); + pj_leave_critical_section(); + + return PJ_SUCCESS; +} diff --git a/pjmedia/src/pjmedia/transport_srtp.c b/pjmedia/src/pjmedia/transport_srtp.c index b37fd79b..76bd1518 100644 --- a/pjmedia/src/pjmedia/transport_srtp.c +++ b/pjmedia/src/pjmedia/transport_srtp.c @@ -270,9 +270,9 @@ const char* get_libsrtp_errstr(int err) } static pj_bool_t libsrtp_initialized; -static void pjmedia_srtp_deinit_lib(void); +static void pjmedia_srtp_deinit_lib(pjmedia_endpt *endpt); -PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(void) +PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(pjmedia_endpt *endpt) { if (libsrtp_initialized == PJ_FALSE) { err_status_t err; @@ -284,7 +284,8 @@ PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(void) return PJMEDIA_ERRNO_FROM_LIBSRTP(err); } - if (pj_atexit(pjmedia_srtp_deinit_lib) != PJ_SUCCESS) { + if (pjmedia_endpt_atexit(endpt, pjmedia_srtp_deinit_lib) != PJ_SUCCESS) + { /* There will be memory leak when it fails to schedule libsrtp * deinitialization, however the memory leak could be harmless, * since in modern OS's memory used by an application is released @@ -299,10 +300,19 @@ PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(void) return PJ_SUCCESS; } -static void pjmedia_srtp_deinit_lib(void) +static void pjmedia_srtp_deinit_lib(pjmedia_endpt *endpt) { err_status_t err; + /* Note that currently this SRTP init/deinit is not equipped with + * reference counter, it should be safe as normally there is only + * one single instance of media endpoint and even if it isn't, the + * pjmedia_transport_srtp_create() will invoke SRTP init (the only + * drawback should be the delay described by #788). + */ + + PJ_UNUSED_ARG(endpt); + err = srtp_deinit(); if (err != err_status_ok) { PJ_LOG(4, (THIS_FILE, "Failed to deinitialize libsrtp: %s", @@ -410,7 +420,7 @@ PJ_DEF(pj_status_t) pjmedia_transport_srtp_create( } /* Init libsrtp. */ - status = pjmedia_srtp_init_lib(); + status = pjmedia_srtp_init_lib(endpt); if (status != PJ_SUCCESS) return status; -- cgit v1.2.3