From b5ad2efaf5d3c8db9e4fc0d749ffa6152d20ed20 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Mon, 19 Dec 2011 05:47:55 +0000 Subject: 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 --- pjsip/src/pjsua-lib/pjsua_media.c | 65 +++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 12 deletions(-) (limited to 'pjsip') 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(¶m); 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(¶m.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; } -- cgit v1.2.3