Ignore:
Timestamp:
Mar 22, 2012 11:29:20 AM (12 years ago)
Author:
nanang
Message:

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.
Location:
pjproject/branches/1.x
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/1.x/pjlib/src/pj/os_core_symbian.cpp

    r3553 r3986  
    7676}; 
    7777 
     78/* Flag and reference counter for PJLIB instance */ 
     79static int initialized; 
     80 
    7881/* Flags to indicate which TLS variables have been used */ 
    7982static int tls_vars[PJ_MAX_TLS]; 
     
    8285static unsigned atexit_count; 
    8386static void (*atexit_func[32])(void); 
    84  
    85  
    8687 
    8788 
     
    336337    pj_status_t status; 
    337338     
     339    /* Check if PJLIB have been initialized */ 
     340    if (initialized) { 
     341        ++initialized; 
     342        return PJ_SUCCESS; 
     343    } 
     344 
    338345    pj_ansi_strcpy(main_thread.obj_name, "pjthread"); 
    339346 
     
    369376#endif 
    370377 
     378    /* Flag PJLIB as initialized */ 
     379    ++initialized; 
     380    pj_assert(initialized == 1); 
     381 
    371382    PJ_LOG(5,(THIS_FILE, "PJLIB initialized.")); 
    372383    return PJ_SUCCESS; 
     
    391402PJ_DEF(void) pj_shutdown(void) 
    392403{ 
     404    /* Only perform shutdown operation when 'initialized' reaches zero */ 
     405    pj_assert(initialized > 0); 
     406    if (--initialized != 0) 
     407        return; 
     408 
    393409    /* Call atexit() functions */ 
    394410    while (atexit_count > 0) { 
  • pjproject/branches/1.x/pjlib/src/pj/os_core_unix.c

    r3553 r3986  
    103103 
    104104 
     105/* 
     106 * Flag and reference counter for PJLIB instance. 
     107 */ 
     108static int initialized; 
     109 
    105110#if PJ_HAS_THREADS 
    106111    static pj_thread_t main_thread; 
     
    127132    pj_str_t guid; 
    128133    pj_status_t rc; 
     134 
     135    /* Check if PJLIB have been initialized */ 
     136    if (initialized) { 
     137        ++initialized; 
     138        return PJ_SUCCESS; 
     139    } 
    129140 
    130141#if PJ_HAS_THREADS 
     
    168179#endif    
    169180 
     181    /* Flag PJLIB as initialized */ 
     182    ++initialized; 
     183    pj_assert(initialized == 1); 
     184 
    170185    PJ_LOG(4,(THIS_FILE, "pjlib %s for POSIX initialized", 
    171186              PJ_VERSION)); 
     
    192207{ 
    193208    int i; 
     209 
     210    /* Only perform shutdown operation when 'initialized' reaches zero */ 
     211    pj_assert(initialized > 0); 
     212    if (--initialized != 0) 
     213        return; 
    194214 
    195215    /* Call atexit() functions */ 
  • pjproject/branches/1.x/pjlib/src/pj/os_core_win32.c

    r3553 r3986  
    118118 
    119119/* 
     120 * Flag and reference counter for PJLIB instance. 
     121 */ 
     122static int initialized; 
     123 
     124/* 
    120125 * Static global variables. 
    121126 */ 
     
    142147    pj_str_t guid; 
    143148    pj_status_t rc; 
     149 
     150    /* Check if PJLIB have been initialized */ 
     151    if (initialized) { 
     152        ++initialized; 
     153        return PJ_SUCCESS; 
     154    } 
    144155 
    145156    /* Init Winsock.. */ 
     
    188199#endif    
    189200 
     201    /* Flag PJLIB as initialized */ 
     202    ++initialized; 
     203    pj_assert(initialized == 1); 
     204 
    190205    PJ_LOG(4,(THIS_FILE, "pjlib %s for win32 initialized", 
    191206              PJ_VERSION)); 
     
    213228{ 
    214229    int i; 
     230 
     231    /* Only perform shutdown operation when 'initialized' reaches zero */ 
     232    pj_assert(initialized > 0); 
     233    if (--initialized != 0) 
     234        return; 
    215235 
    216236    /* Display stack usage */ 
  • pjproject/branches/1.x/pjmedia/include/pjmedia/endpoint.h

    r3553 r3986  
    5858 
    5959} pjmedia_endpt_flag; 
     60 
     61 
     62/** 
     63 * Type of callback to register to pjmedia_endpt_atexit(). 
     64 */ 
     65typedef void (*pjmedia_endpt_exit_callback)(pjmedia_endpt *endpt); 
    6066 
    6167 
     
    205211 
    206212 
     213/** 
     214 * Register cleanup function to be called by media endpoint when  
     215 * #pjmedia_endpt_destroy() is called. 
     216 * 
     217 * @param endpt         The media endpoint. 
     218 * @param func          The function to be registered. 
     219 * 
     220 * @return              PJ_SUCCESS on success. 
     221 */ 
     222PJ_DECL(pj_status_t) pjmedia_endpt_atexit(pjmedia_endpt *endpt, 
     223                                          pjmedia_endpt_exit_callback func); 
     224 
     225 
     226 
    207227PJ_END_DECL 
    208228 
  • pjproject/branches/1.x/pjmedia/include/pjmedia/transport_srtp.h

    r3553 r3986  
    201201 * library deinitialization to #pj_atexit(), so the deinitialization 
    202202 * of SRTP library will be performed automatically by PJLIB destructor. 
    203  */ 
    204 PJ_DECL(pj_status_t) pjmedia_srtp_init_lib(void); 
     203 * 
     204 * @param endpt     The media endpoint instance. 
     205 * 
     206 * @return          PJ_SUCCESS on success. 
     207 */ 
     208PJ_DECL(pj_status_t) pjmedia_srtp_init_lib(pjmedia_endpt *endpt); 
    205209 
    206210 
  • pjproject/branches/1.x/pjmedia/src/pjmedia/endpoint.c

    r3957 r3986  
    2424#include <pj/assert.h> 
    2525#include <pj/ioqueue.h> 
     26#include <pj/lock.h> 
    2627#include <pj/log.h> 
    2728#include <pj/os.h> 
     
    5758 
    5859 
     60/* List of media endpoint exit callback. */ 
     61typedef struct exit_cb 
     62{ 
     63    PJ_DECL_LIST_MEMBER             (struct exit_cb); 
     64    pjmedia_endpt_exit_callback     func; 
     65} exit_cb; 
     66 
     67 
    5968/** Concrete declaration of media endpoint. */ 
    6069struct pjmedia_endpt 
     
    8695    /** Is telephone-event enable */ 
    8796    pj_bool_t             has_telephone_event; 
     97 
     98    /** List of exit callback. */ 
     99    exit_cb               exit_cb_list; 
    88100}; 
    89101 
     
    129141        goto on_error; 
    130142 
     143    /* Initialize exit callback list. */ 
     144    pj_list_init(&endpt->exit_cb_list); 
     145 
    131146    /* Create ioqueue if none is specified. */ 
    132147    if (endpt->ioqueue == NULL) { 
     
    189204PJ_DEF(pj_status_t) pjmedia_endpt_destroy (pjmedia_endpt *endpt) 
    190205{ 
     206    exit_cb *ecb; 
    191207    unsigned i; 
    192208 
     
    202218            endpt->thread[i] = NULL; 
    203219        } 
     220    } 
     221 
     222    /* Call all registered exit callbacks */ 
     223    ecb = endpt->exit_cb_list.next; 
     224    while (ecb != &endpt->exit_cb_list) { 
     225        (*ecb->func)(endpt); 
     226        ecb = ecb->next; 
    204227    } 
    205228 
     
    629652    return PJ_SUCCESS; 
    630653} 
     654 
     655PJ_DEF(pj_status_t) pjmedia_endpt_atexit( pjmedia_endpt *endpt, 
     656                                          pjmedia_endpt_exit_callback func) 
     657{ 
     658    exit_cb *new_cb; 
     659 
     660    PJ_ASSERT_RETURN(endpt && func, PJ_EINVAL); 
     661 
     662    if (endpt->quit_flag) 
     663        return PJ_EINVALIDOP; 
     664 
     665    new_cb = PJ_POOL_ZALLOC_T(endpt->pool, exit_cb); 
     666    new_cb->func = func; 
     667 
     668    pj_enter_critical_section(); 
     669    pj_list_push_back(&endpt->exit_cb_list, new_cb); 
     670    pj_leave_critical_section(); 
     671 
     672    return PJ_SUCCESS; 
     673} 
  • pjproject/branches/1.x/pjmedia/src/pjmedia/transport_srtp.c

    r3961 r3986  
    271271 
    272272static pj_bool_t libsrtp_initialized; 
    273 static void pjmedia_srtp_deinit_lib(void); 
    274  
    275 PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(void) 
     273static void pjmedia_srtp_deinit_lib(pjmedia_endpt *endpt); 
     274 
     275PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(pjmedia_endpt *endpt) 
    276276{ 
    277277    if (libsrtp_initialized == PJ_FALSE) { 
     
    285285        } 
    286286 
    287         if (pj_atexit(pjmedia_srtp_deinit_lib) != PJ_SUCCESS) { 
     287        if (pjmedia_endpt_atexit(endpt, pjmedia_srtp_deinit_lib) != PJ_SUCCESS) 
     288        { 
    288289            /* There will be memory leak when it fails to schedule libsrtp  
    289290             * deinitialization, however the memory leak could be harmless, 
     
    300301} 
    301302 
    302 static void pjmedia_srtp_deinit_lib(void) 
     303static void pjmedia_srtp_deinit_lib(pjmedia_endpt *endpt) 
    303304{ 
    304305    err_status_t err; 
     306 
     307    /* Note that currently this SRTP init/deinit is not equipped with 
     308     * reference counter, it should be safe as normally there is only 
     309     * one single instance of media endpoint and even if it isn't, the 
     310     * pjmedia_transport_srtp_create() will invoke SRTP init (the only 
     311     * drawback should be the delay described by #788). 
     312     */ 
     313 
     314    PJ_UNUSED_ARG(endpt); 
    305315 
    306316    err = srtp_deinit(); 
     
    411421 
    412422    /* Init libsrtp. */ 
    413     status = pjmedia_srtp_init_lib(); 
     423    status = pjmedia_srtp_init_lib(endpt); 
    414424    if (status != PJ_SUCCESS) 
    415425        return status; 
  • pjproject/branches/1.x/pjsip/include/pjsip/sip_endpoint.h

    r3828 r3986  
    6363 */ 
    6464 
     65 
     66/** 
     67 * Type of callback to register to pjsip_endpt_atexit(). 
     68 */ 
     69typedef void (*pjsip_endpt_exit_callback)(pjsip_endpoint *endpt); 
     70 
     71 
    6572/** 
    6673 * Create an instance of SIP endpoint from the specified pool factory. 
     
    512519 
    513520 
     521/** 
     522 * Register cleanup function to be called by SIP endpoint when  
     523 * #pjsip_endpt_destroy() is called. 
     524 * 
     525 * @param endpt         The SIP endpoint. 
     526 * @param func          The function to be registered. 
     527 * 
     528 * @return              PJ_SUCCESS on success. 
     529 */ 
     530PJ_DECL(pj_status_t) pjsip_endpt_atexit(pjsip_endpoint *endpt, 
     531                                        pjsip_endpt_exit_callback func); 
     532 
    514533 
    515534/** 
  • pjproject/branches/1.x/pjsip/src/pjsip-ua/sip_replaces.c

    r3553 r3986  
    163163 
    164164/* Deinitialize Replaces */ 
    165 static void pjsip_replaces_deinit_module(void) 
    166 { 
     165static void pjsip_replaces_deinit_module(pjsip_endpoint *endpt) 
     166{ 
     167    PJ_TODO(provide_initialized_flag_for_each_endpoint); 
     168    PJ_UNUSED_ARG(endpt); 
    167169    is_initialized = PJ_FALSE; 
    168170} 
     
    192194 
    193195    /* Register deinit module to be executed when PJLIB shutdown */ 
    194     if (pj_atexit(&pjsip_replaces_deinit_module) != PJ_SUCCESS) { 
     196    if (pjsip_endpt_atexit(endpt, &pjsip_replaces_deinit_module) != PJ_SUCCESS) 
     197    { 
    195198        /* Failure to register this function may cause this module won't  
    196199         * work properly when the stack is restarted (without quitting  
  • pjproject/branches/1.x/pjsip/src/pjsip-ua/sip_timer.c

    r3553 r3986  
    496496 
    497497/* Deinitialize Session Timers */ 
    498 static void pjsip_timer_deinit_module(void) 
    499 { 
     498static void pjsip_timer_deinit_module(pjsip_endpoint *endpt) 
     499{ 
     500    PJ_TODO(provide_initialized_flag_for_each_endpoint); 
     501    PJ_UNUSED_ARG(endpt); 
    500502    is_initialized = PJ_FALSE; 
    501503} 
     
    532534 
    533535    /* Register deinit module to be executed when PJLIB shutdown */ 
    534     if (pj_atexit(&pjsip_timer_deinit_module) != PJ_SUCCESS) { 
     536    if (pjsip_endpt_atexit(endpt, &pjsip_timer_deinit_module) != PJ_SUCCESS) { 
    535537        /* Failure to register this function may cause this module won't  
    536538         * work properly when the stack is restarted (without quitting  
  • pjproject/branches/1.x/pjsip/src/pjsip/sip_endpoint.c

    r3553 r3986  
    4141#define MAX_METHODS   32 
    4242 
     43 
     44/* List of SIP endpoint exit callback. */ 
     45typedef struct exit_cb 
     46{ 
     47    PJ_DECL_LIST_MEMBER             (struct exit_cb); 
     48    pjsip_endpt_exit_callback       func; 
     49} exit_cb; 
     50 
     51 
    4352/** 
    4453 * The SIP endpoint. 
     
    8796    /** Additional request headers. */ 
    8897    pjsip_hdr            req_hdr; 
     98 
     99    /** List of exit callback. */ 
     100    exit_cb              exit_cb_list; 
    89101}; 
    90102 
     
    446458    pj_list_init(&endpt->module_list); 
    447459 
     460    /* Initialize exit callback list. */ 
     461    pj_list_init(&endpt->exit_cb_list); 
     462 
    448463    /* Create R/W mutex for module manipulation. */ 
    449464    status = pj_rwmutex_create(endpt->pool, "ept%p", &endpt->mod_mutex); 
     
    560575{ 
    561576    pjsip_module *mod; 
     577    exit_cb *ecb; 
    562578 
    563579    PJ_LOG(5, (THIS_FILE, "Destroying endpoing instance..")); 
     580 
     581    /* Call all registered exit callbacks */ 
     582    ecb = endpt->exit_cb_list.next; 
     583    while (ecb != &endpt->exit_cb_list) { 
     584        (*ecb->func)(endpt); 
     585        ecb = ecb->next; 
     586    } 
    564587 
    565588    /* Phase 1: stop all modules */ 
     
    11791202} 
    11801203 
     1204 
     1205PJ_DEF(pj_status_t) pjsip_endpt_atexit( pjsip_endpoint *endpt, 
     1206                                        pjsip_endpt_exit_callback func) 
     1207{ 
     1208    exit_cb *new_cb; 
     1209 
     1210    PJ_ASSERT_RETURN(endpt && func, PJ_EINVAL); 
     1211 
     1212    new_cb = PJ_POOL_ZALLOC_T(endpt->pool, exit_cb); 
     1213    new_cb->func = func; 
     1214 
     1215    pj_mutex_lock(endpt->mutex); 
     1216    pj_list_push_back(&endpt->exit_cb_list, new_cb); 
     1217    pj_mutex_unlock(endpt->mutex); 
     1218 
     1219    return PJ_SUCCESS; 
     1220} 
  • pjproject/branches/1.x/pjsip/src/pjsua-lib/pjsua_media.c

    r3962 r3986  
    336336 
    337337#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) 
    338     /* Initialize SRTP library. */ 
    339     status = pjmedia_srtp_init_lib(); 
     338    /* Initialize SRTP library (ticket #788). */ 
     339    status = pjmedia_srtp_init_lib(pjsua_var.med_endpt); 
    340340    if (status != PJ_SUCCESS) { 
    341341        pjsua_perror(THIS_FILE, "Error initializing SRTP library",  
Note: See TracChangeset for help on using the changeset viewer.