summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2009-10-14 01:58:04 +0000
committerBenny Prijono <bennylp@teluu.com>2009-10-14 01:58:04 +0000
commit2dd0fe09ceb1675de340d5d4ff84251b3697b435 (patch)
tree57bbbf8f79d24d908bc2aae95d9134e3cd37d72e /pjsip
parentb2aac52d83d6e4fb46e2bef723647fa2bb1ad8be (diff)
Ticket #970: More gracefull PJSUA-LIB shutdown sequence. Enhancements:
- wait for unregistration to complete (or a preconfigured delay expires) - new account config field to set the maximum delay to wait for unregistration - rejects incoming requests (INVITE, SUBSCRIBE, and OPTIONS) when shutdown is in progress git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2943 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h19
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c8
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c64
-rw-r--r--pjsip/src/pjsua-lib/pjsua_media.c2
-rw-r--r--pjsip/src/pjsua-lib/pjsua_pres.c10
5 files changed, 83 insertions, 20 deletions
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index d6db65b9..c0eb8b25 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -1725,6 +1725,17 @@ PJ_DECL(pj_status_t) pjsua_transport_close( pjsua_transport_id id,
/**
+ * Default maximum time to wait for account unregistration transactions to
+ * complete during library shutdown sequence.
+ *
+ * Default: 4000 (4 seconds)
+ */
+#ifndef PJSUA_UNREG_TIMEOUT
+# define PJSUA_UNREG_TIMEOUT 4000
+#endif
+
+
+/**
* Default PUBLISH expiration
*/
#ifndef PJSUA_PUBLISH_EXPIRATION
@@ -1919,6 +1930,14 @@ typedef struct pjsua_acc_config
*/
unsigned reg_timeout;
+ /**
+ * Specify the maximum time to wait for unregistration requests to
+ * complete during library shutdown sequence.
+ *
+ * Default: PJSUA_UNREG_TIMEOUT
+ */
+ unsigned unreg_timeout;
+
/**
* Number of credentials in the credential array.
*/
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index c57873f6..a845940c 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -645,6 +645,14 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata)
if (dlg || tsx)
return PJ_FALSE;
+ /* Don't want to accept the call if shutdown is in progress */
+ if (pjsua_var.thread_quit_flag) {
+ pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata,
+ PJSIP_SC_TEMPORARILY_UNAVAILABLE, NULL,
+ NULL, NULL);
+ return PJ_TRUE;
+ }
+
PJSUA_LOCK();
/* Find free call slot. */
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index 39ad80d8..0b6f48c7 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -161,6 +161,7 @@ PJ_DEF(void) pjsua_acc_config_default(pjsua_acc_config *cfg)
pj_bzero(cfg, sizeof(*cfg));
cfg->reg_timeout = PJSUA_REG_INTERVAL;
+ cfg->unreg_timeout = PJSUA_UNREG_TIMEOUT;
pjsip_publishc_opt_default(&cfg->publish_opt);
cfg->unpublish_max_wait_time_msec = PJSUA_UNPUBLISH_MAX_WAIT_TIME_MSEC;
cfg->transport_id = PJSUA_INVALID_ID;
@@ -305,6 +306,14 @@ static pj_bool_t options_on_rx_request(pjsip_rx_data *rdata)
return PJ_FALSE;
}
+ /* Don't want to handle if shutdown is in progress */
+ if (pjsua_var.thread_quit_flag) {
+ pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata,
+ PJSIP_SC_TEMPORARILY_UNAVAILABLE, NULL,
+ NULL, NULL);
+ return PJ_TRUE;
+ }
+
/* Create basic response. */
status = pjsip_endpt_create_response(pjsua_var.endpt, rdata, 200, NULL,
&tdata);
@@ -1231,6 +1240,8 @@ PJ_DEF(pj_status_t) pjsua_destroy(void)
if (pjsua_var.endpt) {
unsigned max_wait;
+ PJ_LOG(4,(THIS_FILE, "Shutting down..."));
+
/* Terminate all calls. */
pjsua_call_hangup_all();
@@ -1245,6 +1256,9 @@ PJ_DEF(pj_status_t) pjsua_destroy(void)
/* Terminate all presence subscriptions. */
pjsua_pres_shutdown();
+ /* Destroy media (to shutdown media transports etc) */
+ pjsua_media_subsys_destroy();
+
/* Wait for sometime until all publish client sessions are done
* (ticket #364)
*/
@@ -1290,10 +1304,6 @@ PJ_DEF(pj_status_t) pjsua_destroy(void)
pjsua_acc_set_registration(i, PJ_FALSE);
}
}
- }
-
- /* Destroy endpoint. */
- if (pjsua_var.endpt) {
/* Terminate any pending STUN resolution */
if (!pj_list_empty(&pjsua_var.stun_res)) {
@@ -1305,23 +1315,40 @@ PJ_DEF(pj_status_t) pjsua_destroy(void)
}
}
- /* Wait for some time to allow unregistration and ICE/TURN
- * transports shutdown to complete:
- */
- PJ_LOG(4,(THIS_FILE, "Shutting down..."));
- busy_sleep(1000);
+ /* Wait until all unregistrations are done (ticket #364) */
+ /* First stage, get the maximum wait time */
+ max_wait = 100;
+ for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.acc); ++i) {
+ if (!pjsua_var.acc[i].valid)
+ continue;
+ if (pjsua_var.acc[i].cfg.unreg_timeout > max_wait)
+ max_wait = pjsua_var.acc[i].cfg.unreg_timeout;
+ }
+
+ /* Second stage, wait for unregistrations to complete */
+ for (i=0; i<(int)(max_wait/50); ++i) {
+ unsigned j;
+ for (j=0; j<PJ_ARRAY_SIZE(pjsua_var.acc); ++j) {
+ if (!pjsua_var.acc[j].valid)
+ continue;
- PJ_LOG(4,(THIS_FILE, "Destroying..."));
+ if (pjsua_var.acc[j].regc)
+ break;
+ }
+ if (j != PJ_ARRAY_SIZE(pjsua_var.acc))
+ busy_sleep(50);
+ else
+ break;
+ }
+ /* Note variable 'i' is used below */
- /* Terminate all calls again, just in case there's new call
- * picked up during busy_sleep()
+ /* Wait for some time to allow unregistration and ICE/TURN
+ * transports shutdown to complete:
*/
- pjsua_call_hangup_all();
+ if (i < 20)
+ busy_sleep(1000 - i*50);
- /* Destroy media after all polling is done, as there may be
- * incoming request that needs handling (e.g. OPTIONS)
- */
- pjsua_media_subsys_destroy();
+ PJ_LOG(4,(THIS_FILE, "Destroying..."));
/* Must destroy endpoint first before destroying pools in
* buddies or accounts, since shutting down transaction layer
@@ -1346,9 +1373,6 @@ PJ_DEF(pj_status_t) pjsua_destroy(void)
pjsua_var.acc[i].pool = NULL;
}
}
- } else {
- /* Destroy media */
- pjsua_media_subsys_destroy();
}
/* Destroy mutex */
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index 243f4f65..01f33a1c 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -640,6 +640,8 @@ pj_status_t pjsua_media_subsys_destroy(void)
{
unsigned i;
+ PJ_LOG(4,(THIS_FILE, "Shutting down media.."));
+
close_snd_dev();
if (pjsua_var.mconf) {
diff --git a/pjsip/src/pjsua-lib/pjsua_pres.c b/pjsip/src/pjsua-lib/pjsua_pres.c
index 4515636c..935a41e7 100644
--- a/pjsip/src/pjsua-lib/pjsua_pres.c
+++ b/pjsip/src/pjsua-lib/pjsua_pres.c
@@ -682,6 +682,14 @@ static pj_bool_t pres_on_rx_request(pjsip_rx_data *rdata)
/* Incoming SUBSCRIBE: */
+ /* Don't want to accept the request if shutdown is in progress */
+ if (pjsua_var.thread_quit_flag) {
+ pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata,
+ PJSIP_SC_TEMPORARILY_UNAVAILABLE, NULL,
+ NULL, NULL);
+ return PJ_TRUE;
+ }
+
PJSUA_LOCK();
/* Find which account for the incoming request. */
@@ -1721,6 +1729,8 @@ void pjsua_pres_shutdown(void)
{
unsigned i;
+ PJ_LOG(4,(THIS_FILE, "Shutting down presence.."));
+
if (pjsua_var.pres_timer.id != 0) {
pjsip_endpt_cancel_timer(pjsua_var.endpt, &pjsua_var.pres_timer);
pjsua_var.pres_timer.id = PJ_FALSE;