From: liang121.sun Date: Tue, 7 May 2013 09:46:55 +0000 (+0800) Subject: [Merge] Fix race condition issue. X-Git-Tag: accepted/tizen/20130520.101107^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Ftizen_2.1;p=platform%2Fcore%2Fmultimedia%2Favsystem.git [Merge] Fix race condition issue. Change-Id: Icce57d8413d081194a150f3dc3205f610392675d --- diff --git a/avsys-audio-handle.c b/avsys-audio-handle.c index 8eca6b3..1232c92 100644 --- a/avsys-audio-handle.c +++ b/avsys-audio-handle.c @@ -439,6 +439,39 @@ int avsys_audio_handle_alloc(int *handle) } } +int avsys_audio_handle_alloc_unlocked(int *handle) +{ + long long int flag = 0x01; + int i; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + temp = &control; + + avsys_info(AVAUDIO, "%s\n", __func__); + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + + for (i = 0; i < AVSYS_AUDIO_HANDLE_MAX; i++) { + if ((control->allocated & flag) == 0) { /* alloc condition */ + control->allocated |= flag; + break; + } else { + flag <<= 1; + } + } + + if (i == AVSYS_AUDIO_HANDLE_MAX) { + *handle = -1; + return AVSYS_STATE_ERR_RANGE_OVER; + } else { + avsys_info(AVAUDIO, "handle allocated %d\n", i); + memset(&control->handles[i], 0, sizeof(avsys_audio_handle_t)); + control->handles[i].pid = getpid(); + control->handles[i].tid = avsys_gettid(); + *handle = i; + return AVSYS_STATE_SUCCESS; + } +} + int avsys_audio_handle_free(int handle) { long long int flag = 0x01; @@ -523,6 +556,43 @@ int avsys_audio_handle_get_ptr(int handle, avsys_audio_handle_t **ptr, const int return ret; } +int avsys_audio_handle_get_ptr_unlocked(int handle, avsys_audio_handle_t **ptr, const int mode) +{ + long long int flag = 0x01; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + int ret = AVSYS_STATE_SUCCESS; + + if (handle < 0 || handle >= AVSYS_AUDIO_HANDLE_MAX) { + *ptr = NULL; + return AVSYS_STATE_ERR_INVALID_HANDLE; + } + + if (mode < 0 || mode >= HANDLE_PTR_MODE_NUM) { + *ptr = NULL; + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + + temp = &control; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_HANDLE, (void **)temp))) { + avsys_error(AVAUDIO, "avsys_audio_get_shm() failed in %s\n", __func__); + *ptr = NULL; + return AVSYS_STATE_ERR_INTERNAL; + } + + flag <<= handle; + + if (control->allocated & flag) { + *ptr = &(control->handles[handle]); + ret = AVSYS_STATE_SUCCESS; + } else { + *ptr = NULL; + ret = AVSYS_STATE_ERR_INVALID_VALUE; + } + + return ret; +} + int avsys_audio_handle_release_ptr(int handle, const int mode) { long long int flag = 0x01; diff --git a/avsys-audio.c b/avsys-audio.c index 029d93a..39dd1c8 100644 --- a/avsys-audio.c +++ b/avsys-audio.c @@ -37,6 +37,7 @@ #include "avsys-audio.h" #include "avsys-audio-logical-volume.h" #include "avsys-common.h" +#include "avsys-audio-sync.h" #include "avsys-audio-path.h" #include "avsys-audio-alsa.h" @@ -50,6 +51,10 @@ #define FADEUP_CALC_BIAS (1) static int __avsys_audio_set_info(avsys_audio_handle_t *p, avsys_audio_param_t *param); +static int __avsys_audio_handle_init(int *handle, + avsys_audio_handle_t **ptr, + avsys_audio_param_t *param); + void __init_module(void); void __fini_module(void); @@ -122,7 +127,9 @@ int avsys_audio_open(avsys_audio_param_t *param, avsys_handle_t *phandle, int *s avsys_error(AVAUDIO, "Unused handle cleanup before handle allocation failed in %s\n", __func__); goto error; } - err = avsys_audio_handle_alloc(&handle); + + err = __avsys_audio_handle_init(&handle,&p,param); + if (AVSYS_STATE_ERR_RANGE_OVER == err) { avsys_error(AVAUDIO, "audio handle is fully allocated..try cleanup\n"); err = avsys_audio_handle_rejuvenation(); @@ -131,7 +138,7 @@ int avsys_audio_open(avsys_audio_param_t *param, avsys_handle_t *phandle, int *s goto error; } avsys_error(AVAUDIO, "one more try...to allocate audio handle\n"); - err = avsys_audio_handle_alloc(&handle); + err = __avsys_audio_handle_init(&handle,&p,param); if (AVSYS_FAIL(err)) { avsys_error(AVAUDIO, "handle alloc failed 1 in %s\n", __func__); goto error; @@ -141,17 +148,6 @@ int avsys_audio_open(avsys_audio_param_t *param, avsys_handle_t *phandle, int *s goto error; } - err = avsys_audio_handle_get_ptr(handle, &p, HANDLE_PTR_MODE_NORMAL); - if (AVSYS_FAIL(err)) { - goto error; - } - - /* set information to handle */ - err = __avsys_audio_set_info(p, param); - if (AVSYS_FAIL(err)) { - goto error; - } - if (p->mode == AVSYS_AUDIO_MODE_OUTPUT || p->mode == AVSYS_AUDIO_MODE_OUTPUT_CLOCK || p->mode == AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY || p->mode == AVSYS_AUDIO_MODE_OUTPUT_AP_CALL || p->mode == AVSYS_AUDIO_MODE_OUTPUT_VIDEO) { /* set volume table */ @@ -756,6 +752,37 @@ static int __avsys_audio_set_info(avsys_audio_handle_t *p, avsys_audio_param_t * return AVSYS_STATE_SUCCESS; } +static int __avsys_audio_handle_init(int *handle, + avsys_audio_handle_t **ptr, + avsys_audio_param_t *param) +{ + int err = AVSYS_STATE_ERR_UNKNOWN; + + if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) { + avsys_error(AVAUDIO,"avsys_audio_lock_sync() failed in %s\n", __func__); + return AVSYS_STATE_ERR_INTERNAL; + } + + err = avsys_audio_handle_alloc_unlocked(handle); + + if (AVSYS_STATE_SUCCESS == err) { + + err = avsys_audio_handle_get_ptr_unlocked(*handle, ptr, HANDLE_PTR_MODE_NORMAL); + if(AVSYS_STATE_SUCCESS == err) { + + /* set information to handle */ + err = __avsys_audio_set_info(*ptr, param); + } + } + + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) { + avsys_error(AVAUDIO,"avsys_audio_unlock_sync() failed in %s\n", __func__); + return AVSYS_STATE_ERR_INTERNAL; + } + + return err; +} + EXPORT_API int avsys_audio_earjack_manager_init(int *earjack_type, int *waitfd) { diff --git a/include/avsys-audio-handle.h b/include/avsys-audio-handle.h index 41db071..4e9b1e1 100644 --- a/include/avsys-audio-handle.h +++ b/include/avsys-audio-handle.h @@ -101,8 +101,10 @@ int avsys_audio_handle_reset(int *volume_value); int avsys_audio_handle_dump(void); int avsys_audio_handle_rejuvenation(void); int avsys_audio_handle_alloc(int *handle); +int avsys_audio_handle_alloc_unlocked(int *handle); int avsys_audio_handle_free(int handle); int avsys_audio_handle_get_ptr(int handle, avsys_audio_handle_t **ptr, const int mode); +int avsys_audio_handle_get_ptr_unlocked(int handle, avsys_audio_handle_t **ptr, const int mode); int avsys_audio_handle_release_ptr(int handle, const int mode); int avsys_audio_handle_set_mute(int handle, int mute); int avsys_audio_handle_ext_dev_set_mute(avsysaudio_ext_device_t device_type, int mute); diff --git a/packaging/avsystem.spec b/packaging/avsystem.spec index 5064ad3..6937e51 100644 --- a/packaging/avsystem.spec +++ b/packaging/avsystem.spec @@ -1,6 +1,6 @@ Name: avsystem Summary: Audio Video System -Version: 0.5.4 +Version: 0.5.5 Release: 0 Group: System/Libraries License: Apache-2.0