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 | |
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
-rwxr-xr-x | packaging/libmm-radio.spec | 2 | ||||
-rw-r--r-- | src/include/mm_radio_priv.h | 20 | ||||
-rw-r--r-- | src/include/mm_radio_priv_hal.h | 20 | ||||
-rw-r--r-- | src/mm_radio_priv_emulator.c | 168 | ||||
-rw-r--r--[-rwxr-xr-x] | src/mm_radio_priv_hal.c | 172 |
5 files changed, 337 insertions, 45 deletions
diff --git a/packaging/libmm-radio.spec b/packaging/libmm-radio.spec index 84a7ade..66a472d 100755 --- a/packaging/libmm-radio.spec +++ b/packaging/libmm-radio.spec @@ -1,6 +1,6 @@ Name: libmm-radio Summary: Multimedia Framework Radio Library -Version: 0.2.36 +Version: 0.2.37 Release: 0 Group: System/Libraries License: Apache-2.0 diff --git a/src/include/mm_radio_priv.h b/src/include/mm_radio_priv.h index 7870aab..1c7d6df 100644 --- a/src/include/mm_radio_priv.h +++ b/src/include/mm_radio_priv.h @@ -41,6 +41,8 @@ #include <gst/gst.h> #include <gst/gstbuffer.h> +#include <glib.h> + #ifdef __cplusplus extern "C" { #endif @@ -133,6 +135,22 @@ typedef struct { bool thread_exit; } MMRadioThread_t; +typedef enum { + MM_RADIO_MSG_DESTROY = 0, + MM_RADIO_MSG_SCAN_INFO, + MM_RADIO_MSG_SCAN_STOPPED, + MM_RADIO_MSG_SCAN_FINISHED, + MM_RADIO_MSG_SEEK_FINISHED, + MM_RADIO_MSG_STATE_INTERRUPTED, + MM_RADIO_MSG_NUM +} MMRadioMsgTypes; + +typedef struct { + bool destroy; + MMRadioMsgTypes msg_type; + int data; +} mm_radio_msg_t; + /*--------------------------------------------------------------------------- GLOBAL DATA TYPE DEFINITIONS: ---------------------------------------------------------------------------*/ @@ -165,6 +183,8 @@ typedef struct { MMHandleType* attrs; /* message callback */ + GAsyncQueue *msg_queue; + MMRadioThread_t msg; MMMessageCallback msg_cb; void* msg_cb_param; diff --git a/src/include/mm_radio_priv_hal.h b/src/include/mm_radio_priv_hal.h index 2a68170..ed80aee 100644 --- a/src/include/mm_radio_priv_hal.h +++ b/src/include/mm_radio_priv_hal.h @@ -44,6 +44,8 @@ #include "radio_hal_interface.h" #include <linux/videodev2.h> +#include <glib.h> + #ifdef __cplusplus extern "C" { #endif @@ -137,6 +139,22 @@ typedef struct { bool thread_exit; } MMRadioThread_t; +typedef enum { + MM_RADIO_MSG_DESTROY = 0, + MM_RADIO_MSG_SCAN_INFO, + MM_RADIO_MSG_SCAN_STOPPED, + MM_RADIO_MSG_SCAN_FINISHED, + MM_RADIO_MSG_SEEK_FINISHED, + MM_RADIO_MSG_STATE_INTERRUPTED, + MM_RADIO_MSG_NUM +} MMRadioMsgTypes; + +typedef struct { + bool destroy; + MMRadioMsgTypes msg_type; + int data; +} mm_radio_msg_t; + /*--------------------------------------------------------------------------- GLOBAL DATA TYPE DEFINITIONS: ---------------------------------------------------------------------------*/ @@ -156,6 +174,8 @@ typedef struct { MMHandleType *attrs; /* message callback */ + GAsyncQueue *msg_queue; + MMRadioThread_t msg; MMMessageCallback msg_cb; void *msg_cb_param; diff --git a/src/mm_radio_priv_emulator.c b/src/mm_radio_priv_emulator.c index 21d211a..21f0f11 100644 --- a/src/mm_radio_priv_emulator.c +++ b/src/mm_radio_priv_emulator.c @@ -133,6 +133,8 @@ static int __mmradio_set_band_range(mm_radio_t * radio); static int __mmradio_get_wave_num(mm_radio_t * radio); 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); /*=========================================================================== FUNCTION DEFINITIONS ========================================================================== */ @@ -218,11 +220,18 @@ int _mmradio_create_radio(mm_radio_t * radio) radio->subs_id = 0; 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); @@ -232,12 +241,20 @@ 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; } MMRADIO_LOG_FLEAVE(); return MM_ERROR_NONE; + +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) @@ -335,6 +352,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 = mm_resource_manager_destroy(radio->resource_manager); if (ret) { MMRADIO_LOG_ERROR("failed to destroy resource manager"); @@ -879,7 +899,6 @@ void __mmradio_scan_thread(mm_radio_t * radio) while (!radio->scan.stop) { - MMMessageParamType param = { 0, }; freq = 0; MMRADIO_LOG_DEBUG("scanning...."); @@ -913,21 +932,20 @@ void __mmradio_scan_thread(mm_radio_t * radio) if (freq == prev_freq) continue; - prev_freq = param.radio_scan.frequency = freq; - MMRADIO_SLOG_DEBUG("scanning : new frequency : [%d]", param.radio_scan.frequency); + prev_freq = freq; + MMRADIO_LOG_INFO("scanning : new frequency : [%d]", freq); /* drop if max freq is scanned */ - if (param.radio_scan.frequency == radio->region_setting.band_max - || param.radio_scan.frequency > radio->region_setting.band_max - || param.radio_scan.frequency < radio->region_setting.band_min) { - MMRADIO_LOG_DEBUG("%d freq is dropping...and stopping scan", param.radio_scan.frequency); + if (freq >= radio->region_setting.band_max + || freq < radio->region_setting.band_min) { + MMRADIO_LOG_DEBUG("%d freq is dropping...and stopping scan", freq); break; } if (radio->scan.stop) break; /* doesn't need to post */ - MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_INFO, ¶m); + __mmradio_msg_push(radio, MM_RADIO_MSG_SCAN_INFO, freq); emulatoridx++; if (emulatoridx >= EMULATOR_FREQ_MAX) break; @@ -948,9 +966,9 @@ FINISHED: } 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; radio->scan.stop = false; @@ -982,7 +1000,6 @@ void __mmradio_seek_thread(mm_radio_t * radio) int freq = 0; int i = 0; int emulatoridx = 0; - MMMessageParamType param = { 0, }; MMRADIO_LOG_FENTER(); MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); @@ -1056,17 +1073,16 @@ void __mmradio_seek_thread(mm_radio_t * radio) } } - param.radio_scan.frequency = radio->prev_seek_freq = freq; - MMRADIO_SLOG_DEBUG("seeking : new frequency : [%d]", param.radio_scan.frequency); - MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m); + radio->prev_seek_freq = freq; + MMRADIO_LOG_INFO("seeking : new frequency : [%d]", (int) freq); + __mmradio_msg_push(radio, MM_RADIO_MSG_SEEK_FINISHED, freq); radio->seek.stop = true; radio->seek.is_running = false; continue; SEEK_FAILED: /* 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.stop = true; radio->seek.is_running = false; } @@ -1255,9 +1271,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); @@ -1446,6 +1461,14 @@ static int __mmradio_create_thread(mm_radio_t *radio) MMRADIO_INIT_MUTEX(radio->cmd_lock); + 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); @@ -1471,7 +1494,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; @@ -1481,6 +1503,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->seek.mutex); pthread_cond_destroy(&radio->seek.cond); @@ -1514,6 +1548,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->seek.mutex); @@ -1522,5 +1568,83 @@ 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 finished 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"); } 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"); } |