summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2011-12-19 05:47:55 +0000
committerBenny Prijono <bennylp@teluu.com>2011-12-19 05:47:55 +0000
commitb5ad2efaf5d3c8db9e4fc0d749ffa6152d20ed20 (patch)
treef303a6705d91d11a7e142fc662023a50e57a8add /pjsip
parentd95570a3f0b389a9385d0215e8b415c6fabc4da7 (diff)
Fixed #1426: Race condition in auto-closing and/or auto-opening of the sound device
git-svn-id: http://svn.pjsip.org/repos/pjproject/branches/1.x@3913 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/src/pjsua-lib/pjsua_media.c65
1 files changed, 53 insertions, 12 deletions
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index 5cdc554b..f56b8f5b 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -1984,7 +1984,6 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
pjsip_endpt_cancel_timer(pjsua_var.endpt, &pjsua_var.snd_idle_timer);
pjsua_var.snd_idle_timer.id = PJ_FALSE;
}
- PJSUA_UNLOCK();
/* For audio switchboard (i.e. APS-Direct):
@@ -2038,6 +2037,7 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
peer_info.bits_per_sample);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error opening sound device", status);
+ PJSUA_UNLOCK();
return status;
}
@@ -2051,6 +2051,7 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
status = open_snd_dev(&param);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error opening sound device", status);
+ PJSUA_UNLOCK();
return status;
}
} else {
@@ -2058,6 +2059,7 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
status = pjsua_set_snd_dev(pjsua_var.cap_dev, pjsua_var.play_dev);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error opening sound device", status);
+ PJSUA_UNLOCK();
return status;
}
}
@@ -2075,12 +2077,14 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
status = pjsua_set_snd_dev(pjsua_var.cap_dev, pjsua_var.play_dev);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error opening sound device", status);
+ PJSUA_UNLOCK();
return status;
}
}
}
+ PJSUA_UNLOCK();
return pjmedia_conf_connect_port(pjsua_var.mconf, source, sink, 0);
}
@@ -2916,8 +2920,11 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,
unsigned i;
pj_status_t status = -1;
+ PJSUA_LOCK();
+
/* Null-sound */
if (capture_dev==NULL_SND_DEV_ID && playback_dev==NULL_SND_DEV_ID) {
+ PJSUA_UNLOCK();
return pjsua_set_null_snd_dev();
}
@@ -2948,8 +2955,10 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,
status = create_aud_param(&param.base, capture_dev, playback_dev,
alt_cr[i], pjsua_var.media_cfg.channel_count,
samples_per_frame, 16);
- if (status != PJ_SUCCESS)
+ if (status != PJ_SUCCESS) {
+ PJSUA_UNLOCK();
return status;
+ }
/* Open! */
param.options = 0;
@@ -2960,11 +2969,13 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to open sound device", status);
+ PJSUA_UNLOCK();
return status;
}
pjsua_var.no_snd = PJ_FALSE;
+ PJSUA_UNLOCK();
return PJ_SUCCESS;
}
@@ -2977,6 +2988,8 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,
PJ_DEF(pj_status_t) pjsua_get_snd_dev(int *capture_dev,
int *playback_dev)
{
+ PJSUA_LOCK();
+
if (capture_dev) {
*capture_dev = pjsua_var.cap_dev;
}
@@ -2984,6 +2997,8 @@ PJ_DEF(pj_status_t) pjsua_get_snd_dev(int *capture_dev,
*playback_dev = pjsua_var.play_dev;
}
+ PJSUA_UNLOCK();
+
return PJ_SUCCESS;
}
@@ -2996,12 +3011,14 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void)
pjmedia_port *conf_port;
pj_status_t status;
+ PJSUA_LOCK();
+
/* Close existing sound device */
close_snd_dev();
/* Create memory pool for sound device. */
pjsua_var.snd_pool = pjsua_pool_create("pjsua_snd", 4000, 4000);
- PJ_ASSERT_RETURN(pjsua_var.snd_pool, PJ_ENOMEM);
+ PJ_ASSERT_ON_FAIL(pjsua_var.snd_pool, {PJSUA_UNLOCK(); return PJ_ENOMEM;});
PJ_LOG(4,(THIS_FILE, "Opening null sound device.."));
@@ -3017,18 +3034,20 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void)
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create null sound device",
status);
+ PJSUA_UNLOCK();
return status;
}
/* Start the master port */
status = pjmedia_master_port_start(pjsua_var.null_snd);
- PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+ PJ_ASSERT_ON_FAIL(status == PJ_SUCCESS, {PJSUA_UNLOCK(); return status;});
pjsua_var.cap_dev = NULL_SND_DEV_ID;
pjsua_var.play_dev = NULL_SND_DEV_ID;
pjsua_var.no_snd = PJ_FALSE;
+ PJSUA_UNLOCK();
return PJ_SUCCESS;
}
@@ -3039,10 +3058,14 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void)
*/
PJ_DEF(pjmedia_port*) pjsua_set_no_snd_dev(void)
{
+ PJSUA_LOCK();
+
/* Close existing sound device */
close_snd_dev();
-
pjsua_var.no_snd = PJ_TRUE;
+
+ PJSUA_UNLOCK();
+
return pjmedia_conf_get_master_port(pjsua_var.mconf);
}
@@ -3052,13 +3075,18 @@ PJ_DEF(pjmedia_port*) pjsua_set_no_snd_dev(void)
*/
PJ_DEF(pj_status_t) pjsua_set_ec(unsigned tail_ms, unsigned options)
{
+ pj_status_t status = PJ_SUCCESS;
+
+ PJSUA_LOCK();
+
pjsua_var.media_cfg.ec_tail_len = tail_ms;
if (pjsua_var.snd_port)
- return pjmedia_snd_port_set_ec( pjsua_var.snd_port, pjsua_var.pool,
- tail_ms, options);
+ status = pjmedia_snd_port_set_ec(pjsua_var.snd_port, pjsua_var.pool,
+ tail_ms, options);
- return PJ_SUCCESS;
+ PJSUA_UNLOCK();
+ return status;
}
@@ -3095,6 +3123,8 @@ PJ_DEF(pj_status_t) pjsua_snd_set_setting( pjmedia_aud_dev_cap cap,
return PJMEDIA_EAUD_INVCAP;
}
+ PJSUA_LOCK();
+
/* If sound is active, set it immediately */
if (pjsua_snd_is_active()) {
pjmedia_aud_stream *strm;
@@ -3105,8 +3135,10 @@ PJ_DEF(pj_status_t) pjsua_snd_set_setting( pjmedia_aud_dev_cap cap,
status = PJ_SUCCESS;
}
- if (status != PJ_SUCCESS)
+ if (status != PJ_SUCCESS) {
+ PJSUA_UNLOCK();
return status;
+ }
/* Save in internal param for later device open */
if (keep) {
@@ -3114,6 +3146,8 @@ PJ_DEF(pj_status_t) pjsua_snd_set_setting( pjmedia_aud_dev_cap cap,
cap, pval);
}
+ PJSUA_UNLOCK();
+
return status;
}
@@ -3123,6 +3157,10 @@ PJ_DEF(pj_status_t) pjsua_snd_set_setting( pjmedia_aud_dev_cap cap,
PJ_DEF(pj_status_t) pjsua_snd_get_setting( pjmedia_aud_dev_cap cap,
void *pval)
{
+ pj_status_t status;
+
+ PJSUA_LOCK();
+
/* If sound device has never been opened before, open it to
* retrieve the initial setting from the device (e.g. audio
* volume)
@@ -3138,12 +3176,15 @@ PJ_DEF(pj_status_t) pjsua_snd_get_setting( pjmedia_aud_dev_cap cap,
pjmedia_aud_stream *strm;
strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port);
- return pjmedia_aud_stream_get_cap(strm, cap, pval);
+ status = pjmedia_aud_stream_get_cap(strm, cap, pval);
} else {
/* Otherwise retrieve from internal param */
- return pjmedia_aud_param_get_cap(&pjsua_var.aud_param,
- cap, pval);
+ status = pjmedia_aud_param_get_cap(&pjsua_var.aud_param,
+ cap, pval);
}
+
+ PJSUA_UNLOCK();
+ return status;
}