diff options
author | Gilbok Lee <gilbok.lee@samsung.com> | 2018-01-11 18:51:22 +0900 |
---|---|---|
committer | Gilbok Lee <gilbok.lee@samsung.com> | 2018-04-05 10:28:48 +0900 |
commit | 74e23588fee3723faf3ebed27a81fa2959ac222f (patch) | |
tree | bc5238cc74858eec402fcf4f98bd70ffb9ab6322 /src/mm_radio_priv_hal.c | |
parent | ab9d9e32ded6ea49b718453ac5d2049d7d21ed42 (diff) | |
download | libmm-radio-74e23588fee3723faf3ebed27a81fa2959ac222f.tar.gz libmm-radio-74e23588fee3723faf3ebed27a81fa2959ac222f.tar.bz2 libmm-radio-74e23588fee3723faf3ebed27a81fa2959ac222f.zip |
Messages related to callback are posted using thread
[Version] 0.2.37
[Profile] Mobile, Wearable
[Issue Type] Fix bugs
Change-Id: I22f3d33f0f9ae30fa8bd3ce4251e2d094af17814
Diffstat (limited to 'src/mm_radio_priv_hal.c')
-rw-r--r--[-rwxr-xr-x] | src/mm_radio_priv_hal.c | 172 |
1 files changed, 150 insertions, 22 deletions
diff --git a/src/mm_radio_priv_hal.c b/src/mm_radio_priv_hal.c index 44d5bf5..5dab31b 100755..100644 --- a/src/mm_radio_priv_hal.c +++ b/src/mm_radio_priv_hal.c @@ -130,6 +130,8 @@ static void __mmradio_volume_changed_cb(volume_type_t type, unsigned int volume, static int __mmradio_set_media_volume(mm_radio_t *radio, unsigned int level); static int __resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res, void *user_data); +static void __mmradio_msg_thread(mm_radio_t *radio); +static void __mmradio_msg_push(mm_radio_t *radio, MMRadioMsgTypes msg_type, int msg_data); int _mmradio_apply_region(mm_radio_t *radio, MMRadioRegionType region, bool update) { @@ -186,11 +188,18 @@ int _mmradio_create_radio(mm_radio_t *radio) memset(&radio->region_setting, 0, sizeof(MMRadioRegion_t)); radio->local_volume = 1.0; + /* create msg queue for msg thread */ + radio->msg_queue = g_async_queue_new(); + if (!radio->msg_queue) { + MMRADIO_LOG_ERROR("failed to get msg g_async_queue_new"); + return MM_ERROR_RADIO_INTERNAL; + } + /* create mutex and thread */ ret = __mmradio_create_thread(radio); if (ret) { MMRADIO_LOG_ERROR("failed to create threads"); - return ret; + goto ERROR_THREAD; } MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL); @@ -200,18 +209,28 @@ int _mmradio_create_radio(mm_radio_t *radio) __resource_release_cb, radio, &radio->resource_manager); if (ret) { MMRADIO_LOG_ERROR("failed to create resource manager"); - return MM_ERROR_RADIO_INTERNAL; + ret = MM_ERROR_RADIO_INTERNAL; + goto ERROR_RESOURCE; } ret = radio_hal_interface_init(&(radio->hal_inf)); if (ret) { MMRADIO_LOG_ERROR("failed to init mmradio hal interface"); - return ret; + goto ERROR_HAL_INIT; } MMRADIO_LOG_FLEAVE(); return MM_ERROR_NONE; + +ERROR_HAL_INIT: + mm_resource_manager_destroy(radio->resource_manager); +ERROR_RESOURCE: + __mmradio_destroy_thread(radio); +ERROR_THREAD: + if (radio->msg_queue) + g_async_queue_unref(radio->msg_queue); + return ret; } int _mmradio_realize(mm_radio_t *radio) @@ -325,6 +344,9 @@ int _mmradio_destroy(mm_radio_t *radio) /* destroy mutex and thread */ __mmradio_destroy_thread(radio); + if (radio->msg_queue) + g_async_queue_unref(radio->msg_queue); + ret = radio_hal_interface_deinit(radio->hal_inf); if (ret) { MMRADIO_LOG_ERROR("failed to deinitialize radio hal interface"); @@ -833,10 +855,9 @@ void __mmradio_scan_thread(mm_radio_t *radio) MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_START, NULL); MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING); + prev_freq = 0; while (!radio->scan.stop) { uint32_t freq = 0; - prev_freq = 0; - MMMessageParamType param = { 0, }; MMRADIO_LOG_DEBUG("scanning...."); @@ -878,12 +899,12 @@ void __mmradio_scan_thread(mm_radio_t *radio) break; } - prev_freq = param.radio_scan.frequency = (int)freq; - MMRADIO_LOG_INFO("scanning : new frequency : [%d]", param.radio_scan.frequency); + prev_freq = (int)freq; + MMRADIO_LOG_INFO("scanning : new frequency : [%d]", prev_freq); /* drop if max freq is scanned */ - if (param.radio_scan.frequency >= radio->region_setting.band_max) { - MMRADIO_LOG_WARNING("%d freq is dropping...and stopping scan", param.radio_scan.frequency); + if (prev_freq >= radio->region_setting.band_max) { + MMRADIO_LOG_WARNING("%d freq is dropping...and stopping scan", prev_freq); break; } @@ -892,7 +913,7 @@ void __mmradio_scan_thread(mm_radio_t *radio) break; } - MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_INFO, ¶m); + __mmradio_msg_push(radio, MM_RADIO_MSG_SCAN_INFO, freq); } } @@ -953,9 +974,9 @@ FINISHED_ERR: } if (!radio->scan.stop) - MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_FINISH, NULL); + __mmradio_msg_push(radio, MM_RADIO_MSG_SCAN_FINISHED, 0); else - MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_STOP, NULL); + __mmradio_msg_push(radio, MM_RADIO_MSG_SCAN_STOPPED, 0); radio->scan.is_running = false; @@ -991,7 +1012,6 @@ void __mmradio_seek_thread(mm_radio_t *radio) { int ret = MM_ERROR_NONE; uint32_t freq = 0; - MMMessageParamType param = {0, }; MMRADIO_LOG_FENTER(); MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); @@ -1075,9 +1095,9 @@ void __mmradio_seek_thread(mm_radio_t *radio) radio->seek_unmute = false; } - param.radio_scan.frequency = radio->prev_seek_freq = (int)freq; - MMRADIO_LOG_INFO("seeking : new frequency : [%d]", param.radio_scan.frequency); - MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m); + radio->prev_seek_freq = (int)freq; + MMRADIO_LOG_INFO("seeking : new frequency : [%d]", (int) freq); + __mmradio_msg_push(radio, MM_RADIO_MSG_SEEK_FINISHED, freq); radio->seek.is_running = false; continue; @@ -1093,8 +1113,7 @@ SEEK_FAILED: radio->seek_unmute = false; } /* freq -1 means it's failed to seek */ - param.radio_scan.frequency = -1; - MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m); + __mmradio_msg_push(radio, MM_RADIO_MSG_SEEK_FINISHED, -1); radio->seek.is_running = false; } @@ -1285,9 +1304,8 @@ static bool __mmradio_set_state(mm_radio_t *radio, int new_state) msg.state.current = radio->current_state; if (radio->interrupted_by_resource_conflict) { - msg_type = MM_MESSAGE_STATE_INTERRUPTED; - msg.state.code = MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT; - MMRADIO_POST_MSG(radio, msg_type, &msg); + __mmradio_msg_push(radio, MM_RADIO_MSG_STATE_INTERRUPTED, + MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT); } else { msg_type = MM_MESSAGE_STATE_CHANGED; MMRADIO_POST_MSG(radio, msg_type, &msg); @@ -1482,6 +1500,14 @@ static int __mmradio_create_thread(mm_radio_t *radio) MMRADIO_INIT_MUTEX(radio->volume_lock); MMRADIO_INIT_MUTEX(radio->hal_seek_mutex); + radio->msg.thread_id = pthread_create(&radio->msg.thread, NULL, + (void *)__mmradio_msg_thread, (void *)radio); + if (radio->msg.thread_id) { + /* NOTE : we are dealing it as an error since we cannot expect it's behavior */ + MMRADIO_LOG_ERROR("failed to create thread : msg"); + goto ERROR; + } + MMRADIO_INIT_MUTEX(radio->seek.mutex); MMRADIO_INIT_COND(radio->seek.cond); @@ -1506,7 +1532,6 @@ static int __mmradio_create_thread(mm_radio_t *radio) return ret; ERROR: - if (radio->seek.thread) { MMRADIO_SEEK_THREAD_LOCK(radio); radio->seek.thread_exit = true; @@ -1516,6 +1541,18 @@ ERROR: radio->seek.thread = 0; } + if (radio->msg.thread) { + mm_radio_msg_t *msg = g_slice_new0(mm_radio_msg_t); + if (!msg) { + MMRADIO_LOG_ERROR("failed to get mm_radio_msg_t"); + } else { + msg->msg_type = MM_RADIO_MSG_DESTROY; + g_async_queue_push_front(radio->msg_queue, msg); + pthread_join(radio->msg.thread, NULL); + radio->msg.thread = 0; + } + } + pthread_mutex_destroy(&radio->cmd_lock); pthread_mutex_destroy(&radio->volume_lock); pthread_mutex_destroy(&radio->hal_seek_mutex); @@ -1551,6 +1588,18 @@ static void __mmradio_destroy_thread(mm_radio_t *radio) radio->scan.thread = 0; } + if (radio->msg.thread) { + mm_radio_msg_t *msg = g_slice_new0(mm_radio_msg_t); + if (!msg) { + MMRADIO_LOG_ERROR("failed to get mm_radio_msg_t"); + } else { + msg->msg_type = MM_RADIO_MSG_DESTROY; + g_async_queue_push_front(radio->msg_queue, msg); + pthread_join(radio->msg.thread, NULL); + radio->msg.thread = 0; + } + } + pthread_mutex_destroy(&radio->cmd_lock); pthread_mutex_destroy(&radio->volume_lock); pthread_mutex_destroy(&radio->hal_seek_mutex); @@ -1562,5 +1611,84 @@ static void __mmradio_destroy_thread(mm_radio_t *radio) pthread_cond_destroy(&radio->scan.cond); MMRADIO_LOG_FLEAVE(); +} + +void __mmradio_msg_push(mm_radio_t *radio, MMRadioMsgTypes msg_type, int msg_data) +{ + mm_radio_msg_t *msg = g_slice_new0(mm_radio_msg_t); + if (!msg) { + MMRADIO_LOG_ERROR("NULL msg pointer"); + return; + } + + msg->msg_type = msg_type; + msg->data = msg_data; + + MMRADIO_LOG_INFO("push msg_type: %d, msg_data: %d", (int)msg->msg_type, msg->data); + g_async_queue_push(radio->msg_queue, msg); +} + +void __mmradio_msg_thread(mm_radio_t *radio) +{ + MMMessageParamType param = {0,}; + mm_radio_msg_t *msg = NULL; + int exit_msg_thread = 0; + + /*we run a while one loop*/ + while (exit_msg_thread == 0) { + msg = (mm_radio_msg_t *)g_async_queue_pop(radio->msg_queue); + if (!msg) { + MMRADIO_LOG_ERROR("poped message is NULL!"); + break; + } + + switch (msg->msg_type) { + case MM_RADIO_MSG_DESTROY: + MMRADIO_LOG_INFO("get destroy msg. pop all event to finish this thread"); + mm_radio_msg_t *msg_pop = NULL; + while ((msg_pop = (mm_radio_msg_t *)g_async_queue_try_pop(radio->msg_queue))) { + if (msg_pop != NULL) { + MMRADIO_LOG_DEBUG("drop this msg type: %d", msg_pop->msg_type); + g_slice_free(mm_radio_msg_t, msg_pop); + } + } + exit_msg_thread = 1; + break; + case MM_RADIO_MSG_SCAN_INFO: + MMRADIO_LOG_INFO("get scan info frequency: %d", msg->data); + param.radio_scan.frequency = (int) msg->data; + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_INFO, ¶m); + break; + case MM_RADIO_MSG_SCAN_STOPPED: + MMRADIO_LOG_INFO("get scan stopped"); + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_STOP, NULL); + break; + case MM_RADIO_MSG_SCAN_FINISHED: + MMRADIO_LOG_INFO("get scan finished"); + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_FINISH, NULL); + break; + case MM_RADIO_MSG_SEEK_FINISHED: + MMRADIO_LOG_INFO("get seek finish frequency: %d", msg->data); + param.radio_scan.frequency = (int) msg->data; + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m); + break; + case MM_RADIO_MSG_STATE_INTERRUPTED: + MMRADIO_LOG_INFO("get state interrupted type: %d", msg->data); + param.union_type = MM_MSG_UNION_STATE; + param.state.previous = radio->old_state; + param.state.current = radio->current_state; + param.state.code = msg->data; + MMRADIO_POST_MSG(radio, MM_MESSAGE_STATE_INTERRUPTED, ¶m); + break; + default: + MMRADIO_LOG_ERROR("wrong msg_type : %d", msg->msg_type); + break; + } + + if (msg) + g_slice_free(mm_radio_msg_t, msg); + + } + MMRADIO_LOG_INFO("msg thread is finished"); } |