From 4b65d7d166b1318f34e35b0db62b7533a36c6c80 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Wed, 19 Oct 2011 12:45:05 +0000 Subject: Fixed #1216: New pjsua_destroy2() API to allow shutting down the library without sending any outgoing messages git-svn-id: http://svn.pjsip.org/repos/pjproject/branches/1.x@3829 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/include/pjsua-lib/pjsua.h | 24 +++++++++++++++++++ pjsip/include/pjsua-lib/pjsua_internal.h | 8 +++---- pjsip/src/pjsua-lib/pjsua_acc.c | 6 ++--- pjsip/src/pjsua-lib/pjsua_core.c | 34 +++++++++++++++++++++------ pjsip/src/pjsua-lib/pjsua_media.c | 6 ++++- pjsip/src/pjsua-lib/pjsua_pres.c | 40 ++++++++++++++++++++------------ 6 files changed, 88 insertions(+), 30 deletions(-) (limited to 'pjsip') diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index 40c4e27d..433f23a6 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -1293,6 +1293,18 @@ typedef struct pjsua_config } pjsua_config; +/** + * Flags to be given to pjsua_destroy2() + */ +typedef enum pjsua_destroy_flag +{ + /** + * Do not invoke any networking functions. + */ + PJSUA_DESTROY_NO_NETWORK = 1 + +} pjsua_destroy_flag; + /** * Use this function to initialize pjsua config. * @@ -1429,11 +1441,23 @@ PJ_DECL(pj_status_t) pjsua_start(void); * Application.may safely call this function more than once if it doesn't * keep track of it's state. * + * @see pjsua_destroy2() + * * @return PJ_SUCCESS on success, or the appropriate error code. */ PJ_DECL(pj_status_t) pjsua_destroy(void); +/** + * Variant of destroy with additional flags. + * + * @param flags Combination of pjsua_destroy_flag enumeration. + * + * @return PJ_SUCCESS on success, or the appropriate error code. + */ +PJ_DECL(pj_status_t) pjsua_destroy2(unsigned flags); + + /** * Poll pjsua for events, and if necessary block the caller thread for * the specified maximum interval (in miliseconds). diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h index a7aed985..af6fd9f9 100644 --- a/pjsip/include/pjsua-lib/pjsua_internal.h +++ b/pjsip/include/pjsua-lib/pjsua_internal.h @@ -463,7 +463,7 @@ void pjsua_pres_update_acc(int acc_id, pj_bool_t force); /* * Shutdown presence. */ -void pjsua_pres_shutdown(void); +void pjsua_pres_shutdown(unsigned flags); /** * Init presence for aoocunt. @@ -478,12 +478,12 @@ pj_status_t pjsua_pres_init_publish_acc(int acc_id); /** * Send un-PUBLISH */ -void pjsua_pres_unpublish(pjsua_acc *acc); +void pjsua_pres_unpublish(pjsua_acc *acc, unsigned flags); /** * Terminate server subscription for the account */ -void pjsua_pres_delete_acc(int acc_id); +void pjsua_pres_delete_acc(int acc_id, unsigned flags); /** * Init IM module handler to handle incoming MESSAGE outside dialog. @@ -518,7 +518,7 @@ pj_status_t pjsua_media_subsys_start(void); /** * Destroy pjsua media subsystem. */ -pj_status_t pjsua_media_subsys_destroy(void); +pj_status_t pjsua_media_subsys_destroy(unsigned flags); /** * Private: check if we can accept the message. diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c index 0a7cf16e..4091d7e8 100644 --- a/pjsip/src/pjsua-lib/pjsua_acc.c +++ b/pjsip/src/pjsua-lib/pjsua_acc.c @@ -582,7 +582,7 @@ PJ_DEF(pj_status_t) pjsua_acc_del(pjsua_acc_id acc_id) } /* Delete server presence subscription */ - pjsua_pres_delete_acc(acc_id); + pjsua_pres_delete_acc(acc_id, 0); /* Release account pool */ if (pjsua_var.acc[acc_id].pool) { @@ -801,7 +801,7 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id, if (acc->cfg.publish_enabled != cfg->publish_enabled) { acc->cfg.publish_enabled = cfg->publish_enabled; if (!acc->cfg.publish_enabled) - pjsua_pres_unpublish(acc); + pjsua_pres_unpublish(acc, 0); else update_reg = PJ_TRUE; } @@ -1995,7 +1995,7 @@ PJ_DEF(pj_status_t) pjsua_acc_set_registration( pjsua_acc_id acc_id, goto on_return; } - pjsua_pres_unpublish(&pjsua_var.acc[acc_id]); + pjsua_pres_unpublish(&pjsua_var.acc[acc_id], 0); status = pjsip_regc_unregister(pjsua_var.acc[acc_id].regc, &tdata); } diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index 393d3d1a..6274f4d4 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -1283,7 +1283,7 @@ pj_status_t resolve_stun_server(pj_bool_t wait) /* * Destroy pjsua. */ -PJ_DEF(pj_status_t) pjsua_destroy(void) +PJ_DEF(pj_status_t) pjsua_destroy2(unsigned flags) { int i; /* Must be signed */ @@ -1302,10 +1302,12 @@ PJ_DEF(pj_status_t) pjsua_destroy(void) if (pjsua_var.endpt) { unsigned max_wait; - PJ_LOG(4,(THIS_FILE, "Shutting down...")); + PJ_LOG(4,(THIS_FILE, "Shutting down, flags=%d...", flags)); /* Terminate all calls. */ - pjsua_call_hangup_all(); + if ((flags & PJSUA_DESTROY_NO_NETWORK) == 0) { + pjsua_call_hangup_all(); + } /* Set all accounts to offline */ for (i=0; i<(int)PJ_ARRAY_SIZE(pjsua_var.acc); ++i) { @@ -1316,10 +1318,10 @@ PJ_DEF(pj_status_t) pjsua_destroy(void) } /* Terminate all presence subscriptions. */ - pjsua_pres_shutdown(); + pjsua_pres_shutdown(flags); /* Destroy media (to shutdown media transports etc) */ - pjsua_media_subsys_destroy(); + pjsua_media_subsys_destroy(flags); /* Wait for sometime until all publish client sessions are done * (ticket #364) @@ -1333,6 +1335,11 @@ PJ_DEF(pj_status_t) pjsua_destroy(void) max_wait = pjsua_var.acc[i].cfg.unpublish_max_wait_time_msec; } + /* No need to wait if we didn't send anything */ + if (flags & PJSUA_DESTROY_NO_NETWORK) { + max_wait = 0; + } + /* Second stage, wait for unpublications to complete */ for (i=0; i<(int)(max_wait/50); ++i) { unsigned j; @@ -1362,7 +1369,8 @@ PJ_DEF(pj_status_t) pjsua_destroy(void) if (!pjsua_var.acc[i].valid) continue; - if (pjsua_var.acc[i].regc) { + if (pjsua_var.acc[i].regc && (flags & PJSUA_DESTROY_NO_NETWORK)==0) + { pjsua_acc_set_registration(i, PJ_FALSE); } } @@ -1387,6 +1395,11 @@ PJ_DEF(pj_status_t) pjsua_destroy(void) max_wait = pjsua_var.acc[i].cfg.unreg_timeout; } + /* No need to wait if we didn't send anything */ + if (flags & PJSUA_DESTROY_NO_NETWORK) { + max_wait = 0; + } + /* Second stage, wait for unregistrations to complete */ for (i=0; i<(int)(max_wait/50); ++i) { unsigned j; @@ -1407,8 +1420,9 @@ PJ_DEF(pj_status_t) pjsua_destroy(void) /* Wait for some time to allow unregistration and ICE/TURN * transports shutdown to complete: */ - if (i < 20) + if (i < 20 && (flags & PJSUA_DESTROY_NO_NETWORK) == 0) { busy_sleep(1000 - i*50); + } PJ_LOG(4,(THIS_FILE, "Destroying...")); @@ -1469,6 +1483,12 @@ PJ_DEF(pj_status_t) pjsua_destroy(void) } +PJ_DEF(pj_status_t) pjsua_destroy(void) +{ + return pjsua_destroy2(0); +} + + /** * Application is recommended to call this function after all initialization * is done, so that the library can do additional checking set up diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c index e939dba9..5cdc554b 100644 --- a/pjsip/src/pjsua-lib/pjsua_media.c +++ b/pjsip/src/pjsua-lib/pjsua_media.c @@ -658,7 +658,7 @@ pj_status_t pjsua_media_subsys_start(void) /* * Destroy pjsua media subsystem. */ -pj_status_t pjsua_media_subsys_destroy(void) +pj_status_t pjsua_media_subsys_destroy(unsigned flags) { unsigned i; @@ -698,6 +698,10 @@ pj_status_t pjsua_media_subsys_destroy(void) pjsua_media_channel_deinit(i); } if (pjsua_var.calls[i].med_tp && pjsua_var.calls[i].med_tp_auto_del) { + /* TODO: check if we're not allowed to send to network in the + * "flags", and if so do not do TURN allocation... + */ + PJ_UNUSED_ARG(flags); pjmedia_transport_close(pjsua_var.calls[i].med_tp); } pjsua_var.calls[i].med_tp = NULL; diff --git a/pjsip/src/pjsua-lib/pjsua_pres.c b/pjsip/src/pjsua-lib/pjsua_pres.c index 6b5b20ba..699d749f 100644 --- a/pjsip/src/pjsua-lib/pjsua_pres.c +++ b/pjsip/src/pjsua-lib/pjsua_pres.c @@ -1277,13 +1277,17 @@ pj_status_t pjsua_pres_init_acc(int acc_id) /* Unpublish presence publication */ -void pjsua_pres_unpublish(pjsua_acc *acc) +void pjsua_pres_unpublish(pjsua_acc *acc, unsigned flags) { if (acc->publish_sess) { pjsua_acc_config *acc_cfg = &acc->cfg; acc->online_status = PJ_FALSE; - send_publish(acc->index, PJ_FALSE); + + if ((flags & PJSUA_DESTROY_NO_NETWORK) == 0) { + send_publish(acc->index, PJ_FALSE); + } + /* By ticket #364, don't destroy the session yet (let the callback destroy it) if (acc->publish_sess) { @@ -1296,7 +1300,7 @@ void pjsua_pres_unpublish(pjsua_acc *acc) } /* Terminate server subscription for the account */ -void pjsua_pres_delete_acc(int acc_id) +void pjsua_pres_delete_acc(int acc_id, unsigned flags) { pjsua_acc *acc = &pjsua_var.acc[acc_id]; pjsua_srv_pres *uapres; @@ -1318,11 +1322,15 @@ void pjsua_pres_delete_acc(int acc_id) pres_status.info[0].basic_open = pjsua_var.acc[acc_id].online_status; pjsip_pres_set_status(uapres->sub, &pres_status); - if (pjsip_pres_notify(uapres->sub, - PJSIP_EVSUB_STATE_TERMINATED, NULL, - &reason, &tdata)==PJ_SUCCESS) - { - pjsip_pres_send_request(uapres->sub, tdata); + if ((flags & PJSUA_DESTROY_NO_NETWORK) == 0) { + if (pjsip_pres_notify(uapres->sub, + PJSIP_EVSUB_STATE_TERMINATED, NULL, + &reason, &tdata)==PJ_SUCCESS) + { + pjsip_pres_send_request(uapres->sub, tdata); + } + } else { + pjsip_pres_terminate(uapres->sub, PJ_FALSE); } uapres = next; @@ -1333,7 +1341,7 @@ void pjsua_pres_delete_acc(int acc_id) pj_list_init(&acc->pres_srv_list); /* Terminate presence publication, if any */ - pjsua_pres_unpublish(acc); + pjsua_pres_unpublish(acc, flags); } @@ -2252,7 +2260,7 @@ pj_status_t pjsua_pres_start(void) /* * Shutdown presence. */ -void pjsua_pres_shutdown(void) +void pjsua_pres_shutdown(unsigned flags) { unsigned i; @@ -2266,17 +2274,19 @@ void pjsua_pres_shutdown(void) for (i=0; i