#define SM_STATE_CHECK_FOR_PRIV(handle, expected_state) \
_CHECK_CONDITION(handle->state == expected_state, MM_ERROR_SOUND_INVALID_STATE, "MM_ERROR_SOUND_INVALID_STATE")
+#define SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(x_mutex, x_mutex_to_unlock, x_return) \
+switch (pthread_mutex_lock(x_mutex)) { \
+case EINVAL: \
+ LOGW("try mutex init.."); \
+ if (pthread_mutex_init(x_mutex, NULL)) { \
+ if (pthread_mutex_unlock(x_mutex_to_unlock)) \
+ LOGE("mutex unlock failed"); \
+ return x_return; \
+ } else { \
+ if (pthread_mutex_lock(x_mutex)) { \
+ LOGE("mutex lock failed"); \
+ if (pthread_mutex_unlock(x_mutex_to_unlock)) \
+ LOGE("mutex unlock failed"); \
+ return x_return; \
+ } \
+ break; \
+ } \
+ if (pthread_mutex_unlock(x_mutex_to_unlock)) \
+ LOGE("mutex unlock failed"); \
+ return x_return; \
+case 0: \
+ break; \
+default: \
+ LOGE("mutex lock failed"); \
+ if (pthread_mutex_unlock(x_mutex_to_unlock)) \
+ LOGE("mutex unlock failed"); \
+ return x_return; \
+}
+
#define SM_ENTER_CRITICAL_SECTION_WITH_RETURN(x_mutex, x_return) \
switch (pthread_mutex_lock(x_mutex)) { \
case EINVAL: \
- LOGW("try mutex init..\n"); \
+ LOGW("try mutex init.."); \
if (pthread_mutex_init(x_mutex, NULL)) { \
return x_return; \
} else { \
if (pthread_mutex_lock(x_mutex)) { \
- LOGE("mutex lock failed\n"); \
+ LOGE("mutex lock failed"); \
return x_return; \
} \
break; \
case 0: \
break; \
default: \
- LOGE("mutex lock failed\n"); \
+ LOGE("mutex lock failed"); \
return x_return; \
}
+#define SM_ENTER_CRITICAL_SECTION(x_mutex) \
+switch (pthread_mutex_lock(x_mutex)) { \
+case EINVAL: \
+ LOGW("try mutex init.."); \
+ if (pthread_mutex_init(x_mutex, NULL)) { \
+ return; \
+ } else { \
+ if (pthread_mutex_lock(x_mutex)) { \
+ LOGE("mutex lock failed"); \
+ return; \
+ } \
+ break; \
+ } \
+ return; \
+case 0: \
+ break; \
+default: \
+ LOGE("mutex lock failed"); \
+ return; \
+}
+
#define SM_LEAVE_CRITICAL_SECTION(x_mutex) \
if (pthread_mutex_unlock(x_mutex)) { \
- LOGE("mutex unlock failed\n"); \
+ LOGE("mutex unlock failed"); \
}
#define SM_REF_FOR_STREAM_INFO(x_count, x_return) \
void *user_data;
manual_route_info_s manual_route_info;
pthread_mutex_t focus_state_mutex;
+ pthread_mutex_t focus_cb_mutex;
} sound_stream_info_s;
typedef enum {
return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
}
- SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
+ if (!is_focus_cb_thread) {
+ SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
+ SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
+ } else {
+ SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
+ }
if (stream_h->acquired_focus & focus_mask) {
LOGE("invalid state: focus_mask[0x%x], acquired_focus[0x%x]", focus_mask, stream_h->acquired_focus);
LEAVE:
SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
+ if (!is_focus_cb_thread)
+ SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
return _convert_sound_manager_error_code(__func__, ret);
}
if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
return _convert_sound_manager_error_code(__func__, ret);
- SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
+ if (!is_focus_cb_thread) {
+ SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
+ SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
+ } else {
+ SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
+ }
if (!(stream_h->acquired_focus & focus_mask)) {
LOGE("invalid state: focus_mask[0x%x], acquired_focus[0x%x]", focus_mask, stream_h->acquired_focus);
LEAVE:
SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
+ if (!is_focus_cb_thread)
+ SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
return _convert_sound_manager_error_code(__func__, ret);
}
return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
}
- SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
+ if (!is_focus_cb_thread) {
+ SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
+ SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
+ } else {
+ SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
+ }
if (is_focus_cb_thread && (stream_h->prev_acquired_focus > stream_h->acquired_focus)) {
LOGE("just lost focus in this callback, it is not allowed to acquire all again. acquired_focus[0x%x], prev[0x%x]",
LEAVE:
SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
+ if (!is_focus_cb_thread)
+ SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
return _convert_sound_manager_error_code(__func__, ret);
}
if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
return _convert_sound_manager_error_code(__func__, ret);
- SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
+ if (!is_focus_cb_thread) {
+ SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
+ SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
+ } else {
+ SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
+ }
if (is_focus_cb_thread && (stream_h->prev_acquired_focus < stream_h->acquired_focus)) {
LOGE("just acquired focus in this callback, it is not allowed to release all again. acquired_focus[0x%x], prev[0x%x]",
LEAVE:
SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
+ if (!is_focus_cb_thread)
+ SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
return _convert_sound_manager_error_code(__func__, ret);
}