summaryrefslogtreecommitdiff
path: root/src/mm_radio_priv_hal.c
diff options
context:
space:
mode:
authorGilbok Lee <gilbok.lee@samsung.com>2018-01-11 18:51:22 +0900
committerGilbok Lee <gilbok.lee@samsung.com>2018-04-05 10:28:48 +0900
commit74e23588fee3723faf3ebed27a81fa2959ac222f (patch)
treebc5238cc74858eec402fcf4f98bd70ffb9ab6322 /src/mm_radio_priv_hal.c
parentab9d9e32ded6ea49b718453ac5d2049d7d21ed42 (diff)
downloadlibmm-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.c172
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, &param);
+ __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, &param);
+ 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, &param);
+ __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, &param);
+ 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, &param);
+ 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, &param);
+ 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");
}