diff options
author | Gilbok Lee <gilbok.lee@samsung.com> | 2018-04-17 15:37:27 +0900 |
---|---|---|
committer | Gilbok Lee <gilbok.lee@samsung.com> | 2018-04-24 17:14:11 +0900 |
commit | cc9cd23fde25c4756919d55eb62d4761fd51efcc (patch) | |
tree | f22390a69b04d422f37a47eaee4927c24325727f | |
parent | 74e23588fee3723faf3ebed27a81fa2959ac222f (diff) | |
download | libmm-radio-cc9cd23fde25c4756919d55eb62d4761fd51efcc.tar.gz libmm-radio-cc9cd23fde25c4756919d55eb62d4761fd51efcc.tar.bz2 libmm-radio-cc9cd23fde25c4756919d55eb62d4761fd51efcc.zip |
When creating a thread, waiting for the thread function to start
[Version] 0.2.38
[Profile] Mobile, Wearable
[Issue Type] Fix bugs
Change-Id: I5f8cc010267a0b95882996e981fbf65bd33f6385
-rwxr-xr-x | packaging/libmm-radio.spec | 2 | ||||
-rw-r--r-- | src/include/mm_radio_priv.h | 14 | ||||
-rw-r--r-- | src/include/mm_radio_priv_hal.h | 14 | ||||
-rw-r--r-- | src/include/mm_radio_utils.h | 32 | ||||
-rw-r--r-- | src/mm_radio_priv_emulator.c | 341 | ||||
-rw-r--r-- | src/mm_radio_priv_hal.c | 338 |
6 files changed, 450 insertions, 291 deletions
diff --git a/packaging/libmm-radio.spec b/packaging/libmm-radio.spec index 66a472d..3833445 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.37 +Version: 0.2.38 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 1c7d6df..a806c12 100644 --- a/src/include/mm_radio_priv.h +++ b/src/include/mm_radio_priv.h @@ -151,6 +151,13 @@ typedef struct { int data; } mm_radio_msg_t; +typedef enum { + MM_RADIO_THREAD_MSG = 0, + MM_RADIO_THREAD_SEEK, + MM_RADIO_THREAD_SCAN, + MM_RADIO_THREAD_NUM +} MMRadioThreadTypes; + /*--------------------------------------------------------------------------- GLOBAL DATA TYPE DEFINITIONS: ---------------------------------------------------------------------------*/ @@ -182,9 +189,10 @@ typedef struct { /* radio attributes */ MMHandleType* attrs; + MMRadioThread_t thread[MM_RADIO_THREAD_NUM]; + /* message callback */ GAsyncQueue *msg_queue; - MMRadioThread_t msg; MMMessageCallback msg_cb; void* msg_cb_param; @@ -200,11 +208,7 @@ typedef struct { /* hw debug */ struct v4l2_dbg_register reg; - /* scan */ - MMRadioThread_t scan; - /* seek */ - MMRadioThread_t seek; int prev_seek_freq; MMRadioSeekDirectionType seek_direction; diff --git a/src/include/mm_radio_priv_hal.h b/src/include/mm_radio_priv_hal.h index ed80aee..31fb1ce 100644 --- a/src/include/mm_radio_priv_hal.h +++ b/src/include/mm_radio_priv_hal.h @@ -155,6 +155,13 @@ typedef struct { int data; } mm_radio_msg_t; +typedef enum { + MM_RADIO_THREAD_MSG = 0, + MM_RADIO_THREAD_SEEK, + MM_RADIO_THREAD_SCAN, + MM_RADIO_THREAD_NUM +} MMRadioThreadTypes; + /*--------------------------------------------------------------------------- GLOBAL DATA TYPE DEFINITIONS: ---------------------------------------------------------------------------*/ @@ -173,17 +180,14 @@ typedef struct { /* radio attributes */ MMHandleType *attrs; + MMRadioThread_t thread[MM_RADIO_THREAD_NUM]; + /* message callback */ GAsyncQueue *msg_queue; - MMRadioThread_t msg; MMMessageCallback msg_cb; void *msg_cb_param; - /* scan */ - MMRadioThread_t scan; - /* seek */ - MMRadioThread_t seek; int prev_seek_freq; bool is_muted; bool seek_unmute; diff --git a/src/include/mm_radio_utils.h b/src/include/mm_radio_utils.h index b538b6d..c72da4a 100644 --- a/src/include/mm_radio_utils.h +++ b/src/include/mm_radio_utils.h @@ -63,6 +63,14 @@ do { \ } \ } while (0) +#define MMRADIO_GFREEIF(x) \ +do { \ + if (x) { \ + g_free(x); \ + x = NULL; \ + } \ +} while (0) + #define MMRADIO_CHECK_INSTANCE(x_radio) \ do { \ if (!x_radio) { \ @@ -88,6 +96,14 @@ do { \ } \ } while (0) +#define MMRADIO_CHECK_ARG_RETURN_VOID(x_radio) \ +do { \ + if (!x_radio) { \ + MMRADIO_LOG_ERROR("argument is NULL\n"); \ + return; \ + } \ +} while (0) + #define MMRADIO_CHECK_DEVICE_STATE(x_radio) \ do { \ if (x_radio->radio_fd < 0) { \ @@ -112,17 +128,11 @@ do { \ #define MMRADIO_VOLUME_LOCK(x_radio) pthread_mutex_lock(&((mm_radio_t *)x_radio)->volume_lock) #define MMRADIO_VOLUME_UNLOCK(x_radio) pthread_mutex_unlock(&((mm_radio_t *)x_radio)->volume_lock) -/* seek thread */ -#define MMRADIO_SEEK_THREAD_LOCK(x_radio) pthread_mutex_lock(&((mm_radio_t *)x_radio)->seek.mutex) -#define MMRADIO_SEEK_THREAD_UNLOCK(x_radio) pthread_mutex_unlock(&((mm_radio_t *)x_radio)->seek.mutex) -#define MMRADIO_SEEK_THREAD_WAIT(x_radio) pthread_cond_wait(&((mm_radio_t *)x_radio)->seek.cond, &((mm_radio_t *)x_radio)->seek.mutex) -#define MMRADIO_SEEK_THREAD_SIGNAL(x_radio) pthread_cond_signal(&((mm_radio_t *)x_radio)->seek.cond) - -/* scan thread */ -#define MMRADIO_SCAN_THREAD_LOCK(x_radio) pthread_mutex_lock(&((mm_radio_t *)x_radio)->scan.mutex) -#define MMRADIO_SCAN_THREAD_UNLOCK(x_radio) pthread_mutex_unlock(&((mm_radio_t *)x_radio)->scan.mutex) -#define MMRADIO_SCAN_THREAD_WAIT(x_radio) pthread_cond_wait(&((mm_radio_t *)x_radio)->scan.cond, &((mm_radio_t *)x_radio)->scan.mutex) -#define MMRADIO_SCAN_THREAD_SIGNAL(x_radio) pthread_cond_signal(&((mm_radio_t *)x_radio)->scan.cond) +/* msg/seek/scan thread */ +#define MMRADIO_THREAD_LOCK(x_thread_t) pthread_mutex_lock(&x_thread_t->mutex) +#define MMRADIO_THREAD_UNLOCK(x_thread_t) pthread_mutex_unlock(&x_thread_t->mutex) +#define MMRADIO_THREAD_WAIT(x_thread_t) pthread_cond_wait(&x_thread_t->cond, &x_thread_t->mutex) +#define MMRADIO_THREAD_SIGNAL(x_thread_t) pthread_cond_signal(&x_thread_t->cond) /* hal seek thread */ #define MMRADIO_HAL_SEEK_THREAD_LOCK(x_radio) pthread_mutex_lock(&((mm_radio_t *)x_radio)->hal_seek_mutex) diff --git a/src/mm_radio_priv_emulator.c b/src/mm_radio_priv_emulator.c index 21f0f11..6234fda 100644 --- a/src/mm_radio_priv_emulator.c +++ b/src/mm_radio_priv_emulator.c @@ -126,8 +126,10 @@ static bool __mmradio_set_state(mm_radio_t * radio, int new_state); static void __mmradio_seek_thread(mm_radio_t * radio); static void __mmradio_scan_thread(mm_radio_t * radio); static bool __is_tunable_frequency(mm_radio_t * radio, int freq); -static int __mmradio_create_thread(mm_radio_t *radio); -static void __mmradio_destroy_thread(mm_radio_t *radio); +static int __mmradio_create_threads(mm_radio_t *radio); +static void __mmradio_destroy_threads(mm_radio_t *radio); +static int __mmradio_create_thread_type(mm_radio_t *radio, MMRadioThreadTypes type); +static void __mmradio_destroy_thread_type(mm_radio_t *radio, MMRadioThreadTypes type); static int __mmradio_set_deemphasis(mm_radio_t * radio); static int __mmradio_set_band_range(mm_radio_t * radio); static int __mmradio_get_wave_num(mm_radio_t * radio); @@ -135,6 +137,14 @@ 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); + +typedef void (*thread_function)(mm_radio_t *); +thread_function __mmradio_thread_function[] = { + &__mmradio_msg_thread, + &__mmradio_seek_thread, + &__mmradio_scan_thread +}; + /*=========================================================================== FUNCTION DEFINITIONS ========================================================================== */ @@ -228,7 +238,7 @@ int _mmradio_create_radio(mm_radio_t * radio) } /* create mutex and thread */ - ret = __mmradio_create_thread(radio); + ret = __mmradio_create_threads(radio); if (ret) { MMRADIO_LOG_ERROR("failed to create threads"); goto ERROR_THREAD; @@ -250,7 +260,7 @@ int _mmradio_create_radio(mm_radio_t * radio) return MM_ERROR_NONE; ERROR_RESOURCE: - __mmradio_destroy_thread(radio); + __mmradio_destroy_threads(radio); ERROR_THREAD: if (radio->msg_queue) g_async_queue_unref(radio->msg_queue); @@ -350,7 +360,7 @@ int _mmradio_destroy(mm_radio_t * radio) _mmradio_unrealize(radio); /* destroy mutex and thread */ - __mmradio_destroy_thread(radio); + __mmradio_destroy_threads(radio); if (radio->msg_queue) g_async_queue_unref(radio->msg_queue); @@ -708,16 +718,12 @@ int _mmradio_start_pipeline(mm_radio_t * radio) if (gst_element_set_state(radio->pGstreamer_s->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { MMRADIO_LOG_ERROR("failed to change pipeline state"); - gst_object_unref(radio->pGstreamer_s->pipeline); - g_free(radio->pGstreamer_s); return MM_ERROR_RADIO_INVALID_STATE; } ret_state = gst_element_get_state(radio->pGstreamer_s->pipeline, NULL, NULL, RADIO_GST_STATE_CHANGE_TIMEOUT); if (ret_state == GST_STATE_CHANGE_FAILURE) { MMRADIO_LOG_ERROR("GST_STATE_CHANGE_FAILURE"); - gst_object_unref(radio->pGstreamer_s->pipeline); - g_free(radio->pGstreamer_s); return MM_ERROR_RADIO_INVALID_STATE; } else { MMRADIO_LOG_DEBUG("GST_STATE_NULL ret_state = %d (GST_STATE_CHANGE_SUCCESS)", ret_state); @@ -734,17 +740,13 @@ int _mmradio_stop_pipeline(mm_radio_t * radio) MMRADIO_LOG_FENTER(); if (gst_element_set_state(radio->pGstreamer_s->pipeline, GST_STATE_READY) == GST_STATE_CHANGE_FAILURE) { - MMRADIO_LOG_DEBUG("Fail to change pipeline state"); - gst_object_unref(radio->pGstreamer_s->pipeline); - g_free(radio->pGstreamer_s); + MMRADIO_LOG_ERROR("Fail to change pipeline state"); return MM_ERROR_RADIO_INVALID_STATE; } ret_state = gst_element_get_state(radio->pGstreamer_s->pipeline, NULL, NULL, RADIO_GST_STATE_CHANGE_TIMEOUT); if (ret_state == GST_STATE_CHANGE_FAILURE) { - MMRADIO_LOG_DEBUG("GST_STATE_CHANGE_FAILURE"); - gst_object_unref(radio->pGstreamer_s->pipeline); - g_free(radio->pGstreamer_s); + MMRADIO_LOG_ERROR("GST_STATE_CHANGE_FAILURE"); return MM_ERROR_RADIO_INVALID_STATE; } else { MMRADIO_LOG_DEBUG("GST_STATE_NULL ret_state = %d (GST_STATE_CHANGE_SUCCESS)", ret_state); @@ -759,10 +761,12 @@ int _mmradio_destroy_pipeline(mm_radio_t * radio) GstStateChangeReturn ret_state; MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_ARG(radio->pGstreamer_s); + if (gst_element_set_state(radio->pGstreamer_s->pipeline, GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE) { MMRADIO_LOG_DEBUG("failed to change pipeline state"); gst_object_unref(radio->pGstreamer_s->pipeline); - g_free(radio->pGstreamer_s); + MMRADIO_GFREEIF(radio->pGstreamer_s); return MM_ERROR_RADIO_INVALID_STATE; } @@ -770,14 +774,14 @@ int _mmradio_destroy_pipeline(mm_radio_t * radio) if (ret_state == GST_STATE_CHANGE_FAILURE) { MMRADIO_LOG_DEBUG("GST_STATE_CHANGE_FAILURE"); gst_object_unref(radio->pGstreamer_s->pipeline); - g_free(radio->pGstreamer_s); + MMRADIO_GFREEIF(radio->pGstreamer_s); return MM_ERROR_RADIO_INVALID_STATE; } else { MMRADIO_LOG_DEBUG("GST_STATE_NULL ret_state = %d (GST_STATE_CHANGE_SUCCESS)", ret_state); } gst_object_unref(radio->pGstreamer_s->pipeline); - g_free(radio->pGstreamer_s); + MMRADIO_GFREEIF(radio->pGstreamer_s); MMRADIO_LOG_FLEAVE(); return ret; } @@ -785,21 +789,26 @@ int _mmradio_destroy_pipeline(mm_radio_t * radio) int _mmradio_seek(mm_radio_t * radio, MMRadioSeekDirectionType direction) { + MMRadioThread_t *p_thread = NULL; + MMRADIO_LOG_FENTER(); MMRADIO_CHECK_INSTANCE(radio); MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SEEK); - if (radio->seek.is_running) { + p_thread = &radio->thread[MM_RADIO_THREAD_SEEK]; + MMRADIO_CHECK_ARG(p_thread); + + if (p_thread->is_running) { MMRADIO_LOG_ERROR("[RADIO_ERROR_INVALID_OPERATION]radio is seeking, can't serve another request try again"); return MM_ERROR_RADIO_INTERNAL; } MMRADIO_SLOG_DEBUG("trying to seek. direction[0:UP/1:DOWN) %d", direction); radio->seek_direction = direction; - radio->seek.is_running = true; - radio->seek.stop = false; - MMRADIO_SEEK_THREAD_SIGNAL(radio); + p_thread->is_running = true; + p_thread->stop = false; + MMRADIO_THREAD_SIGNAL(p_thread); MMRADIO_LOG_FLEAVE(); @@ -808,15 +817,20 @@ int _mmradio_seek(mm_radio_t * radio, MMRadioSeekDirectionType direction) int _mmradio_start_scan(mm_radio_t * radio) { + MMRadioThread_t *p_thread = NULL; + MMRADIO_LOG_FENTER(); MMRADIO_CHECK_INSTANCE(radio); MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START_SCAN); - radio->scan.stop = false; - radio->scan.is_running = true; + p_thread = &radio->thread[MM_RADIO_THREAD_SCAN]; + MMRADIO_CHECK_ARG(p_thread); + + p_thread->stop = false; + p_thread->is_running = true; - MMRADIO_SCAN_THREAD_SIGNAL(radio); + MMRADIO_THREAD_SIGNAL(p_thread); MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING); @@ -832,7 +846,7 @@ int _mmradio_stop_scan(mm_radio_t * radio) MMRADIO_CHECK_INSTANCE(radio); MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP_SCAN); - radio->scan.stop = true; + radio->thread[MM_RADIO_THREAD_SCAN].stop = true; MMRADIO_LOG_FLEAVE(); @@ -865,22 +879,31 @@ void __mmradio_scan_thread(mm_radio_t * radio) int prev_freq = 0; int emulatoridx = 0; int freq = 0; + MMRadioThread_t *p_thread = NULL; MMRADIO_LOG_FENTER(); MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); - MMRADIO_SCAN_THREAD_LOCK(radio); + p_thread = &radio->thread[MM_RADIO_THREAD_SCAN]; + MMRADIO_CHECK_ARG_RETURN_VOID(p_thread); + + MMRADIO_THREAD_LOCK(p_thread); + MMRADIO_THREAD_SIGNAL(p_thread); + MMRADIO_THREAD_UNLOCK(p_thread); + + MMRADIO_THREAD_LOCK(p_thread); - while (!radio->scan.thread_exit) { + while (!p_thread->thread_exit) { MMRADIO_LOG_DEBUG("scan thread started. waiting for signal."); - MMRADIO_SCAN_THREAD_WAIT(radio); + MMRADIO_THREAD_WAIT(p_thread); + MMRADIO_LOG_DEBUG("scan thread started. got signal."); - if (radio->scan.thread_exit) { + if (p_thread->thread_exit) { MMRADIO_LOG_DEBUG("exiting scan thread"); goto EXIT; } - if (radio->scan.stop) { + if (p_thread->stop) { MMRADIO_LOG_INFO("scan was stopped"); goto FINISHED; } @@ -897,19 +920,19 @@ void __mmradio_scan_thread(mm_radio_t * radio) prev_freq = 0; emulatoridx = 0; - while (!radio->scan.stop) { + while (!p_thread->stop) { freq = 0; MMRADIO_LOG_DEBUG("scanning...."); /* now we can get new frequency from radio device */ - if (radio->scan.thread_exit) { + if (p_thread->thread_exit) { MMRADIO_LOG_DEBUG("exiting scan thread"); goto EXIT; } - if (radio->scan.stop) + if (p_thread->stop) break; usleep(1000 * 1000); @@ -921,12 +944,12 @@ void __mmradio_scan_thread(mm_radio_t * radio) break; } - if (radio->scan.thread_exit) { + if (p_thread->thread_exit) { MMRADIO_LOG_DEBUG("exiting scan thread"); goto EXIT; } - if (radio->scan.stop) + if (p_thread->stop) break; if (freq == prev_freq) @@ -935,14 +958,14 @@ void __mmradio_scan_thread(mm_radio_t * radio) prev_freq = freq; MMRADIO_LOG_INFO("scanning : new frequency : [%d]", freq); - /* drop if max freq is scanned */ + /* drop if out of range freq is scanned */ 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) + if (p_thread->stop) break; /* doesn't need to post */ __mmradio_msg_push(radio, MM_RADIO_MSG_SCAN_INFO, freq); @@ -965,17 +988,17 @@ FINISHED: } } - if (!radio->scan.stop) + if (!p_thread->stop) __mmradio_msg_push(radio, MM_RADIO_MSG_SCAN_FINISHED, 0); else __mmradio_msg_push(radio, MM_RADIO_MSG_SCAN_STOPPED, 0); - radio->scan.is_running = false; - radio->scan.stop = false; + p_thread->is_running = false; + p_thread->stop = false; } EXIT: - MMRADIO_SCAN_THREAD_UNLOCK(radio); + MMRADIO_THREAD_UNLOCK(p_thread); MMRADIO_LOG_FLEAVE(); pthread_exit(NULL); return; @@ -1000,17 +1023,25 @@ void __mmradio_seek_thread(mm_radio_t * radio) int freq = 0; int i = 0; int emulatoridx = 0; + MMRadioThread_t *p_thread = NULL; MMRADIO_LOG_FENTER(); MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); - MMRADIO_SEEK_THREAD_LOCK(radio); + p_thread = &radio->thread[MM_RADIO_THREAD_SEEK]; + MMRADIO_CHECK_ARG_RETURN_VOID(p_thread); - while (!radio->seek.thread_exit) { + MMRADIO_THREAD_LOCK(p_thread); + MMRADIO_THREAD_SIGNAL(p_thread); + MMRADIO_THREAD_UNLOCK(p_thread); + + MMRADIO_THREAD_LOCK(p_thread); + + while (!p_thread->thread_exit) { MMRADIO_LOG_DEBUG("seek thread started. waiting for signal.\n"); - MMRADIO_SEEK_THREAD_WAIT(radio); + MMRADIO_THREAD_WAIT(p_thread); - if (radio->seek.thread_exit) { + if (p_thread->thread_exit) { MMRADIO_LOG_DEBUG("exiting seek thread"); break; } @@ -1018,7 +1049,7 @@ void __mmradio_seek_thread(mm_radio_t * radio) MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_START, NULL); MMRADIO_LOG_DEBUG("seeking...."); - if (radio->seek.stop) { + if (p_thread->stop) { MMRADIO_LOG_INFO("seek was canceled so we return failure to application"); goto SEEK_FAILED; } @@ -1076,18 +1107,18 @@ void __mmradio_seek_thread(mm_radio_t * radio) 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; + p_thread->stop = true; + p_thread->is_running = false; continue; SEEK_FAILED: /* freq -1 means it's failed to seek */ __mmradio_msg_push(radio, MM_RADIO_MSG_SEEK_FINISHED, -1); - radio->seek.stop = true; - radio->seek.is_running = false; + p_thread->stop = true; + p_thread->is_running = false; } - MMRADIO_SEEK_THREAD_UNLOCK(radio); + MMRADIO_THREAD_UNLOCK(p_thread); MMRADIO_LOG_FLEAVE(); pthread_exit(NULL); return; @@ -1451,125 +1482,146 @@ int _mmradio_get_volume(mm_radio_t *radio, float *pVolume) return MM_ERROR_NONE; } -static int __mmradio_create_thread(mm_radio_t *radio) +static int __mmradio_create_thread_type(mm_radio_t *radio, MMRadioThreadTypes type) { - int ret = MM_ERROR_NONE; + MMRadioThread_t *p_thread = NULL; MMRADIO_LOG_FENTER(); MMRADIO_CHECK_INSTANCE(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; + if (type >= MM_RADIO_THREAD_NUM) { + MMRADIO_LOG_WARNING("wrong argument thread type"); + return MM_ERROR_RADIO_INTERNAL; } - MMRADIO_INIT_MUTEX(radio->seek.mutex); - MMRADIO_INIT_COND(radio->seek.cond); + p_thread = &radio->thread[type]; + MMRADIO_CHECK_ARG(p_thread); + + MMRADIO_INIT_MUTEX(p_thread->mutex); + MMRADIO_INIT_COND(p_thread->cond); - radio->seek.thread_id = pthread_create(&radio->seek.thread, NULL, - (void *)__mmradio_seek_thread, (void *)radio); - if (radio->seek.thread_id) { - MMRADIO_LOG_DEBUG("failed to create thread : seek"); - goto ERROR; + MMRADIO_THREAD_LOCK(p_thread); + p_thread->thread_id = pthread_create(&p_thread->thread, NULL, + (void *)__mmradio_thread_function[type], (void *)radio); + if (p_thread->thread_id) { + MMRADIO_LOG_DEBUG("failed to create thread : [%d]", type); + MMRADIO_THREAD_UNLOCK(p_thread); + return MM_ERROR_RADIO_INTERNAL; } - MMRADIO_INIT_MUTEX(radio->scan.mutex); - MMRADIO_INIT_COND(radio->scan.cond); + MMRADIO_LOG_DEBUG("wait for [%d] thread", type); + MMRADIO_THREAD_WAIT(p_thread); + MMRADIO_LOG_DEBUG("[%d] thread started", type); + MMRADIO_THREAD_UNLOCK(p_thread); - radio->scan.thread_id = pthread_create(&radio->scan.thread, NULL, - (void *)__mmradio_scan_thread, (void *)radio); + return MM_ERROR_NONE; - if (radio->scan.thread_id) { - MMRADIO_LOG_ERROR("failed to create thread : scan"); - goto ERROR; - } +ERROR: + pthread_mutex_destroy(&p_thread->mutex); + pthread_cond_destroy(&p_thread->cond); + return MM_ERROR_RADIO_INTERNAL; - MMRADIO_LOG_FLEAVE(); - return ret; +} -ERROR: - if (radio->seek.thread) { - MMRADIO_SEEK_THREAD_LOCK(radio); - radio->seek.thread_exit = true; - MMRADIO_SEEK_THREAD_SIGNAL(radio); - MMRADIO_SEEK_THREAD_UNLOCK(radio); - pthread_join(radio->seek.thread, NULL); - radio->seek.thread = 0; - } +static int __mmradio_create_threads(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + int type = 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; + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + + MMRADIO_INIT_MUTEX(radio->cmd_lock); + + for (type = (int)MM_RADIO_THREAD_MSG; type < (int)MM_RADIO_THREAD_NUM; type++) { + ret = __mmradio_create_thread_type(radio, (MMRadioThreadTypes)type); + if (ret) { + MMRADIO_LOG_ERROR("failed to create thread(%d)", type); + while (--type >= (int)MM_RADIO_THREAD_MSG) + __mmradio_destroy_thread_type(radio, (MMRadioThreadTypes)type); + goto ERROR; } } - pthread_mutex_destroy(&radio->cmd_lock); - pthread_mutex_destroy(&radio->seek.mutex); - pthread_cond_destroy(&radio->seek.cond); - pthread_mutex_destroy(&radio->scan.mutex); - pthread_cond_destroy(&radio->scan.cond); + MMRADIO_LOG_FLEAVE(); + return ret; +ERROR: + pthread_mutex_destroy(&radio->cmd_lock); + MMRADIO_LOG_FLEAVE(); return MM_ERROR_RADIO_INTERNAL; } -static void __mmradio_destroy_thread(mm_radio_t *radio) +static void __mmradio_destroy_thread_type(mm_radio_t *radio, MMRadioThreadTypes type) { + MMRadioThread_t *p_thread = NULL; + mm_radio_msg_t *msg = NULL; MMRADIO_LOG_FENTER(); MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); - if (radio->seek.thread) { - MMRADIO_SEEK_THREAD_LOCK(radio); - radio->seek.thread_exit = true; - MMRADIO_SEEK_THREAD_SIGNAL(radio); - MMRADIO_SEEK_THREAD_UNLOCK(radio); - pthread_join(radio->seek.thread, NULL); - radio->seek.thread = 0; - } - - if (radio->scan.thread) { - MMRADIO_SCAN_THREAD_LOCK(radio); - radio->scan.thread_exit = true; - MMRADIO_SCAN_THREAD_SIGNAL(radio); - MMRADIO_SCAN_THREAD_UNLOCK(radio); - pthread_join(radio->scan.thread, NULL); - radio->scan.thread = 0; + if (type >= MM_RADIO_THREAD_NUM) { + MMRADIO_LOG_WARNING("wrong argument thread type"); + return; } - 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; + p_thread = &radio->thread[type]; + MMRADIO_CHECK_ARG_RETURN_VOID(p_thread); + + if (p_thread->thread) { + switch (type) { + case MM_RADIO_THREAD_MSG: + 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(p_thread->thread, NULL); + p_thread->thread = 0; + } + break; + case MM_RADIO_THREAD_SEEK: + case MM_RADIO_THREAD_SCAN: + MMRADIO_THREAD_LOCK(p_thread); + p_thread->thread_exit = true; + MMRADIO_THREAD_SIGNAL(p_thread); + MMRADIO_THREAD_UNLOCK(p_thread); + pthread_join(p_thread->thread, NULL); + p_thread->thread = 0; + break; + default: + MMRADIO_LOG_WARNING("(%d)type isn't handled", type); + break; } + } else { + MMRADIO_LOG_WARNING("(%d)thread is zero", type); } - pthread_mutex_destroy(&radio->cmd_lock); + pthread_mutex_destroy(&p_thread->mutex); + pthread_cond_destroy(&p_thread->cond); - pthread_mutex_destroy(&radio->seek.mutex); - pthread_cond_destroy(&radio->seek.cond); - pthread_mutex_destroy(&radio->scan.mutex); - pthread_cond_destroy(&radio->scan.cond); + MMRADIO_LOG_FLEAVE(); +} + +static void __mmradio_destroy_threads(mm_radio_t *radio) +{ + int type = (int)MM_RADIO_THREAD_NUM; + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); + + while (--type >= 0) + __mmradio_destroy_thread_type(radio, (MMRadioThreadTypes)type); + + pthread_mutex_destroy(&radio->cmd_lock); 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); @@ -1587,18 +1639,31 @@ void __mmradio_msg_push(mm_radio_t *radio, MMRadioMsgTypes msg_type, int msg_dat void __mmradio_msg_thread(mm_radio_t *radio) { - MMMessageParamType param = {0,}; mm_radio_msg_t *msg = NULL; - int exit_msg_thread = 0; + MMRadioThread_t *p_thread = NULL; + + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); + + p_thread = &radio->thread[MM_RADIO_THREAD_MSG]; + MMRADIO_CHECK_ARG_RETURN_VOID(p_thread); + + p_thread->thread_exit = false; + + MMRADIO_THREAD_LOCK(p_thread); + MMRADIO_THREAD_SIGNAL(p_thread); + MMRADIO_THREAD_UNLOCK(p_thread); /*we run a while one loop*/ - while (exit_msg_thread == 0) { + while (!p_thread->thread_exit) { msg = (mm_radio_msg_t *)g_async_queue_pop(radio->msg_queue); if (!msg) { MMRADIO_LOG_ERROR("poped message is NULL!"); break; } + MMMessageParamType param = {0,}; + switch (msg->msg_type) { case MM_RADIO_MSG_DESTROY: MMRADIO_LOG_INFO("get destroy msg. pop all event to finish this thread"); @@ -1609,7 +1674,7 @@ void __mmradio_msg_thread(mm_radio_t *radio) g_slice_free(mm_radio_msg_t, msg_pop); } } - exit_msg_thread = 1; + p_thread->thread_exit = true; break; case MM_RADIO_MSG_SCAN_INFO: MMRADIO_LOG_INFO("get scan info frequency: %d", msg->data); @@ -1647,4 +1712,6 @@ void __mmradio_msg_thread(mm_radio_t *radio) } MMRADIO_LOG_INFO("msg thread is finished"); + MMRADIO_LOG_FLEAVE(); + pthread_exit(NULL); } diff --git a/src/mm_radio_priv_hal.c b/src/mm_radio_priv_hal.c index 5dab31b..3d1f8d6 100644 --- a/src/mm_radio_priv_hal.c +++ b/src/mm_radio_priv_hal.c @@ -123,8 +123,10 @@ void _mmradio_seek_cancel(mm_radio_t *radio); static void __mmradio_seek_thread(mm_radio_t *radio); static void __mmradio_scan_thread(mm_radio_t *radio); static bool __is_tunable_frequency(mm_radio_t *radio, int freq); -static int __mmradio_create_thread(mm_radio_t *radio); -static void __mmradio_destroy_thread(mm_radio_t *radio); +static int __mmradio_create_threads(mm_radio_t *radio); +static void __mmradio_destroy_threads(mm_radio_t *radio); +static int __mmradio_create_thread_type(mm_radio_t *radio, MMRadioThreadTypes type); +static void __mmradio_destroy_thread_type(mm_radio_t *radio, MMRadioThreadTypes type); static void __mmradio_volume_changed_cb(volume_type_t type, unsigned int volume, void *user_data); static int __mmradio_set_media_volume(mm_radio_t *radio, unsigned int level); @@ -133,6 +135,13 @@ static int __resource_release_cb(mm_resource_manager_h rm, static void __mmradio_msg_thread(mm_radio_t *radio); static void __mmradio_msg_push(mm_radio_t *radio, MMRadioMsgTypes msg_type, int msg_data); +typedef void (*thread_function)(mm_radio_t *); +thread_function __mmradio_thread_function[] = { + &__mmradio_msg_thread, + &__mmradio_seek_thread, + &__mmradio_scan_thread +}; + int _mmradio_apply_region(mm_radio_t *radio, MMRadioRegionType region, bool update) { int ret = MM_ERROR_NONE; @@ -196,7 +205,7 @@ int _mmradio_create_radio(mm_radio_t *radio) } /* create mutex and thread */ - ret = __mmradio_create_thread(radio); + ret = __mmradio_create_threads(radio); if (ret) { MMRADIO_LOG_ERROR("failed to create threads"); goto ERROR_THREAD; @@ -226,7 +235,7 @@ int _mmradio_create_radio(mm_radio_t *radio) ERROR_HAL_INIT: mm_resource_manager_destroy(radio->resource_manager); ERROR_RESOURCE: - __mmradio_destroy_thread(radio); + __mmradio_destroy_threads(radio); ERROR_THREAD: if (radio->msg_queue) g_async_queue_unref(radio->msg_queue); @@ -342,7 +351,7 @@ int _mmradio_destroy(mm_radio_t *radio) _mmradio_unrealize(radio); /* destroy mutex and thread */ - __mmradio_destroy_thread(radio); + __mmradio_destroy_threads(radio); if (radio->msg_queue) g_async_queue_unref(radio->msg_queue); @@ -673,13 +682,17 @@ int _mmradio_stop(mm_radio_t *radio) int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction) { int ret = MM_ERROR_NONE; + MMRadioThread_t *p_thread = NULL; MMRADIO_LOG_FENTER(); MMRADIO_CHECK_INSTANCE(radio); MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SEEK); - if (radio->seek.is_running) { + p_thread = &radio->thread[MM_RADIO_THREAD_SEEK]; + MMRADIO_CHECK_ARG(p_thread); + + if (p_thread->is_running) { MMRADIO_LOG_ERROR("[RADIO_ERROR_INVALID_OPERATION]radio is seeking, can't serve another request try again"); return MM_ERROR_RADIO_INTERNAL; } @@ -699,10 +712,10 @@ int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction) MMRADIO_LOG_INFO("trying to seek. direction[0:UP/1:DOWN) %d", direction); radio->seek_direction = direction; - radio->seek.is_running = true; - radio->seek.stop = false; + p_thread->is_running = true; + p_thread->stop = false; - MMRADIO_SEEK_THREAD_SIGNAL(radio); + MMRADIO_THREAD_SIGNAL(p_thread); MMRADIO_LOG_FLEAVE(); @@ -716,7 +729,7 @@ void _mmradio_seek_cancel(mm_radio_t *radio) MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); /* cancel any outstanding seek request */ - radio->seek.stop = true; + radio->thread[MM_RADIO_THREAD_SEEK].stop = true; MMRADIO_LOG_FLEAVE(); } @@ -724,13 +737,17 @@ void _mmradio_seek_cancel(mm_radio_t *radio) int _mmradio_start_scan(mm_radio_t *radio) { int ret = MM_ERROR_NONE; + MMRadioThread_t *p_thread = NULL;; MMRADIO_LOG_FENTER(); MMRADIO_CHECK_INSTANCE(radio); MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START_SCAN); - radio->scan.stop = false; + p_thread = &radio->thread[MM_RADIO_THREAD_SCAN]; + MMRADIO_CHECK_ARG(p_thread); + + p_thread->stop = false; if (!radio->is_ready) { ret = mm_resource_manager_mark_for_acquire(radio->resource_manager, @@ -772,9 +789,9 @@ int _mmradio_start_scan(mm_radio_t *radio) MMRADIO_LOG_DEBUG("radio prepared and opened"); } - radio->scan.is_running = true; + p_thread->is_running = true; - MMRADIO_SCAN_THREAD_SIGNAL(radio); + MMRADIO_THREAD_SIGNAL(p_thread); MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING); @@ -790,7 +807,7 @@ int _mmradio_stop_scan(mm_radio_t *radio) MMRADIO_CHECK_INSTANCE(radio); MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP_SCAN); - radio->scan.stop = true; + radio->thread[MM_RADIO_THREAD_SCAN].stop = true; MMRADIO_LOG_FLEAVE(); @@ -826,26 +843,37 @@ void __mmradio_scan_thread(mm_radio_t *radio) int ret = MM_ERROR_NONE; int prev_freq = 0; + MMRadioThread_t *p_thread = NULL; + MMRADIO_LOG_FENTER(); MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); - MMRADIO_SCAN_THREAD_LOCK(radio); + p_thread = &radio->thread[MM_RADIO_THREAD_SCAN]; + MMRADIO_CHECK_ARG_RETURN_VOID(p_thread); + + MMRADIO_THREAD_LOCK(p_thread); + MMRADIO_THREAD_SIGNAL(p_thread); + MMRADIO_THREAD_UNLOCK(p_thread); - while (!radio->scan.thread_exit) { + MMRADIO_THREAD_LOCK(p_thread); + + while (!p_thread->thread_exit) { MMRADIO_LOG_DEBUG("scan thread started. waiting for signal."); - MMRADIO_SCAN_THREAD_WAIT(radio); + MMRADIO_THREAD_WAIT(p_thread); - if (radio->scan.thread_exit) { + if (p_thread->thread_exit) { MMRADIO_LOG_DEBUG("exiting scan thread"); goto EXIT; } - ret = radio_hal_mute(radio->hal_inf); - if (ret == MM_ERROR_NOT_SUPPORT_API) { - MMRADIO_LOG_WARNING("radio_hal_mute is not supported"); - } else if (ret != MM_ERROR_NONE) { - MMRADIO_LOG_ERROR("faied to set radio hal mute"); - goto FINISHED; + if (radio->old_state == MM_RADIO_STATE_PLAYING) { + ret = radio_hal_mute(radio->hal_inf); + if (ret == MM_ERROR_NOT_SUPPORT_API) { + MMRADIO_LOG_WARNING("radio_hal_mute is not supported"); + } else if (ret != MM_ERROR_NONE) { + MMRADIO_LOG_ERROR("faied to set radio hal mute"); + goto FINISHED; + } } ret = radio_hal_set_frequency(radio->hal_inf, radio->region_setting.band_min); @@ -856,17 +884,17 @@ void __mmradio_scan_thread(mm_radio_t *radio) MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING); prev_freq = 0; - while (!radio->scan.stop) { + while (!p_thread->stop) { uint32_t freq = 0; MMRADIO_LOG_DEBUG("scanning...."); - if (radio->scan.thread_exit) { + if (p_thread->thread_exit) { MMRADIO_LOG_DEBUG("exiting scan thread"); goto EXIT; } - if (radio->scan.stop) { + if (p_thread->stop) { MMRADIO_LOG_INFO("scan was canceled"); goto FINISHED; } @@ -879,12 +907,12 @@ void __mmradio_scan_thread(mm_radio_t *radio) break; } - if (radio->scan.thread_exit) { + if (p_thread->thread_exit) { MMRADIO_LOG_DEBUG("exiting scan thread"); goto EXIT; } - if (radio->scan.stop) { + if (p_thread->stop) { MMRADIO_LOG_INFO("scan was canceled"); goto FINISHED; } @@ -908,7 +936,7 @@ void __mmradio_scan_thread(mm_radio_t *radio) break; } - if (radio->scan.stop) { + if (p_thread->stop) { /* doesn't need to post */ break; } @@ -973,19 +1001,19 @@ FINISHED_ERR: MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); } - if (!radio->scan.stop) + if (!p_thread->stop) __mmradio_msg_push(radio, MM_RADIO_MSG_SCAN_FINISHED, 0); else __mmradio_msg_push(radio, MM_RADIO_MSG_SCAN_STOPPED, 0); - radio->scan.is_running = false; + p_thread->is_running = false; } EXIT: - radio->scan.is_running = false; + p_thread->is_running = false; - MMRADIO_SCAN_THREAD_UNLOCK(radio); + MMRADIO_THREAD_UNLOCK(p_thread); MMRADIO_LOG_FLEAVE(); @@ -1012,17 +1040,25 @@ void __mmradio_seek_thread(mm_radio_t *radio) { int ret = MM_ERROR_NONE; uint32_t freq = 0; + MMRadioThread_t *p_thread = NULL; MMRADIO_LOG_FENTER(); MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); - MMRADIO_SEEK_THREAD_LOCK(radio); + p_thread = &radio->thread[MM_RADIO_THREAD_SEEK]; + MMRADIO_CHECK_ARG_RETURN_VOID(p_thread); + + MMRADIO_THREAD_LOCK(p_thread); + MMRADIO_THREAD_SIGNAL(p_thread); + MMRADIO_THREAD_UNLOCK(p_thread); - while (!radio->seek.thread_exit) { + MMRADIO_THREAD_LOCK(p_thread); + + while (!p_thread->thread_exit) { MMRADIO_LOG_DEBUG("seek thread started. waiting for signal."); - MMRADIO_SEEK_THREAD_WAIT(radio); + MMRADIO_THREAD_WAIT(p_thread); - if (radio->seek.thread_exit) { + if (p_thread->thread_exit) { MMRADIO_LOG_DEBUG("exiting seek thread"); goto EXIT; } @@ -1030,7 +1066,7 @@ void __mmradio_seek_thread(mm_radio_t *radio) MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_START, NULL); MMRADIO_LOG_DEBUG("seeking...."); - if (radio->seek.stop) { + if (p_thread->stop) { MMRADIO_LOG_INFO("seek was canceled so we return failure to application"); goto SEEK_FAILED; } @@ -1045,12 +1081,12 @@ void __mmradio_seek_thread(mm_radio_t *radio) goto SEEK_FAILED; } - if (radio->seek.thread_exit) { + if (p_thread->thread_exit) { MMRADIO_LOG_DEBUG("exiting seek thread"); goto EXIT; } - if (radio->seek.stop) { + if (p_thread->stop) { MMRADIO_LOG_INFO("seek was canceled so we return failure to application"); goto SEEK_FAILED; } @@ -1098,7 +1134,7 @@ void __mmradio_seek_thread(mm_radio_t *radio) 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; + p_thread->is_running = false; continue; SEEK_FAILED: @@ -1114,12 +1150,12 @@ SEEK_FAILED: } /* freq -1 means it's failed to seek */ __mmradio_msg_push(radio, MM_RADIO_MSG_SEEK_FINISHED, -1); - radio->seek.is_running = false; + p_thread->is_running = false; } EXIT: - radio->seek.is_running = false; - MMRADIO_SEEK_THREAD_UNLOCK(radio); + p_thread->is_running = false; + MMRADIO_THREAD_UNLOCK(p_thread); MMRADIO_LOG_FLEAVE(); pthread_exit(NULL); } @@ -1488,128 +1524,149 @@ static int __resource_release_cb(mm_resource_manager_h rm, return FALSE; } -static int __mmradio_create_thread(mm_radio_t *radio) +static int __mmradio_create_thread_type(mm_radio_t *radio, MMRadioThreadTypes type) { - int ret = MM_ERROR_NONE; + MMRadioThread_t *p_thread = NULL; MMRADIO_LOG_FENTER(); MMRADIO_CHECK_INSTANCE(radio); - MMRADIO_INIT_MUTEX(radio->cmd_lock); - 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; + if (type >= MM_RADIO_THREAD_NUM) { + MMRADIO_LOG_WARNING("wrong argument thread type"); + return MM_ERROR_RADIO_INTERNAL; } - MMRADIO_INIT_MUTEX(radio->seek.mutex); - MMRADIO_INIT_COND(radio->seek.cond); - - radio->seek.thread_id = pthread_create(&radio->seek.thread, NULL, - (void *)__mmradio_seek_thread, (void *)radio); - if (radio->seek.thread_id) { - MMRADIO_LOG_DEBUG("failed to create thread : seek"); - goto ERROR; - } + p_thread = &radio->thread[type]; + MMRADIO_CHECK_ARG(p_thread); - MMRADIO_INIT_MUTEX(radio->scan.mutex); - MMRADIO_INIT_COND(radio->scan.cond); + MMRADIO_INIT_MUTEX(p_thread->mutex); + MMRADIO_INIT_COND(p_thread->cond); - radio->scan.thread_id = pthread_create(&radio->scan.thread, NULL, - (void *)__mmradio_scan_thread, (void *)radio); - if (radio->scan.thread_id) { - MMRADIO_LOG_ERROR("failed to create thread : scan"); - goto ERROR; + MMRADIO_THREAD_LOCK(p_thread); + p_thread->thread_id = pthread_create(&p_thread->thread, NULL, + (void *)__mmradio_thread_function[type], (void *)radio); + if (p_thread->thread_id) { + MMRADIO_LOG_DEBUG("failed to create thread : [%d]", type); + MMRADIO_THREAD_UNLOCK(p_thread); + return MM_ERROR_RADIO_INTERNAL; } - MMRADIO_LOG_FLEAVE(); - return ret; + MMRADIO_LOG_DEBUG("wait for [%d] thread", type); + MMRADIO_THREAD_WAIT(p_thread); + MMRADIO_LOG_DEBUG("[%d] thread started", type); + MMRADIO_THREAD_UNLOCK(p_thread); + + return MM_ERROR_NONE; ERROR: - if (radio->seek.thread) { - MMRADIO_SEEK_THREAD_LOCK(radio); - radio->seek.thread_exit = true; - MMRADIO_SEEK_THREAD_SIGNAL(radio); - MMRADIO_SEEK_THREAD_UNLOCK(radio); - pthread_join(radio->seek.thread, NULL); - radio->seek.thread = 0; - } + pthread_mutex_destroy(&p_thread->mutex); + pthread_cond_destroy(&p_thread->cond); + return MM_ERROR_RADIO_INTERNAL; - 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; +} + +static int __mmradio_create_threads(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + int type = 0; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + + MMRADIO_INIT_MUTEX(radio->cmd_lock); + MMRADIO_INIT_MUTEX(radio->volume_lock); + MMRADIO_INIT_MUTEX(radio->hal_seek_mutex); + + for (type = (int)MM_RADIO_THREAD_MSG; type < (int)MM_RADIO_THREAD_NUM; type++) { + ret = __mmradio_create_thread_type(radio, (MMRadioThreadTypes)type); + if (ret) { + MMRADIO_LOG_ERROR("failed to create thread(%d)", type); + while (--type >= (int)MM_RADIO_THREAD_MSG) + __mmradio_destroy_thread_type(radio, (MMRadioThreadTypes)type); + goto ERROR; } } + MMRADIO_LOG_FLEAVE(); + return ret; + +ERROR: pthread_mutex_destroy(&radio->cmd_lock); pthread_mutex_destroy(&radio->volume_lock); pthread_mutex_destroy(&radio->hal_seek_mutex); - pthread_mutex_destroy(&radio->seek.mutex); - pthread_cond_destroy(&radio->seek.cond); - pthread_mutex_destroy(&radio->scan.mutex); - pthread_cond_destroy(&radio->scan.cond); + MMRADIO_LOG_FLEAVE(); return MM_ERROR_RADIO_INTERNAL; } -static void __mmradio_destroy_thread(mm_radio_t *radio) +static void __mmradio_destroy_thread_type(mm_radio_t *radio, MMRadioThreadTypes type) { + MMRadioThread_t *p_thread = NULL; + mm_radio_msg_t *msg = NULL; MMRADIO_LOG_FENTER(); MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); - if (radio->seek.thread) { - MMRADIO_SEEK_THREAD_LOCK(radio); - radio->seek.thread_exit = true; - MMRADIO_SEEK_THREAD_SIGNAL(radio); - MMRADIO_SEEK_THREAD_UNLOCK(radio); - pthread_join(radio->seek.thread, NULL); - radio->seek.thread = 0; + if (type >= MM_RADIO_THREAD_NUM) { + MMRADIO_LOG_WARNING("wrong argument thread type"); + return; } - if (radio->scan.thread) { - MMRADIO_SCAN_THREAD_LOCK(radio); - radio->scan.thread_exit = true; - MMRADIO_SCAN_THREAD_SIGNAL(radio); - MMRADIO_SCAN_THREAD_UNLOCK(radio); - pthread_join(radio->scan.thread, NULL); - radio->scan.thread = 0; - } + p_thread = &radio->thread[type]; + MMRADIO_CHECK_ARG_RETURN_VOID(p_thread); - 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; + if (p_thread->thread) { + switch (type) { + case MM_RADIO_THREAD_MSG: + 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(p_thread->thread, NULL); + p_thread->thread = 0; + } + break; + case MM_RADIO_THREAD_SEEK: + case MM_RADIO_THREAD_SCAN: + MMRADIO_THREAD_LOCK(p_thread); + p_thread->thread_exit = true; + MMRADIO_THREAD_SIGNAL(p_thread); + MMRADIO_THREAD_UNLOCK(p_thread); + pthread_join(p_thread->thread, NULL); + p_thread->thread = 0; + break; + default: + MMRADIO_LOG_WARNING("(%d)type isn't handled", type); + break; } + } else { + MMRADIO_LOG_WARNING("(%d)thread is zero", type); } + pthread_mutex_destroy(&p_thread->mutex); + pthread_cond_destroy(&p_thread->cond); + + MMRADIO_LOG_FLEAVE(); +} + +static void __mmradio_destroy_threads(mm_radio_t *radio) +{ + int type = (int)MM_RADIO_THREAD_NUM; + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); + + while (--type >= 0) + __mmradio_destroy_thread_type(radio, (MMRadioThreadTypes)type); + pthread_mutex_destroy(&radio->cmd_lock); pthread_mutex_destroy(&radio->volume_lock); pthread_mutex_destroy(&radio->hal_seek_mutex); - pthread_mutex_destroy(&radio->seek.mutex); - pthread_cond_destroy(&radio->seek.cond); - - pthread_mutex_destroy(&radio->scan.mutex); - pthread_cond_destroy(&radio->scan.cond); - MMRADIO_LOG_FLEAVE(); } @@ -1630,18 +1687,33 @@ void __mmradio_msg_push(mm_radio_t *radio, MMRadioMsgTypes msg_type, int msg_dat void __mmradio_msg_thread(mm_radio_t *radio) { - MMMessageParamType param = {0,}; + mm_radio_msg_t *msg = NULL; - int exit_msg_thread = 0; + MMRadioThread_t *p_thread = NULL; + + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); + + p_thread = &radio->thread[MM_RADIO_THREAD_MSG]; + MMRADIO_CHECK_ARG_RETURN_VOID(p_thread); + + p_thread->thread_exit = false; - /*we run a while one loop*/ - while (exit_msg_thread == 0) { + + MMRADIO_THREAD_LOCK(p_thread); + MMRADIO_THREAD_SIGNAL(p_thread); + MMRADIO_THREAD_UNLOCK(p_thread); + + /* we run a while one loop*/ + while (!p_thread->thread_exit) { msg = (mm_radio_msg_t *)g_async_queue_pop(radio->msg_queue); if (!msg) { MMRADIO_LOG_ERROR("poped message is NULL!"); break; } + MMMessageParamType param = {0,}; + switch (msg->msg_type) { case MM_RADIO_MSG_DESTROY: MMRADIO_LOG_INFO("get destroy msg. pop all event to finish this thread"); @@ -1652,7 +1724,7 @@ void __mmradio_msg_thread(mm_radio_t *radio) g_slice_free(mm_radio_msg_t, msg_pop); } } - exit_msg_thread = 1; + p_thread->thread_exit = true; break; case MM_RADIO_MSG_SCAN_INFO: MMRADIO_LOG_INFO("get scan info frequency: %d", msg->data); @@ -1691,4 +1763,6 @@ void __mmradio_msg_thread(mm_radio_t *radio) } MMRADIO_LOG_INFO("msg thread is finished"); + MMRADIO_LOG_FLEAVE(); + pthread_exit(NULL); } |