#include "internal/stream_cb_manager.h"
static gpointer __sound_pool_callback_isolator(gpointer user_data);
-static void __thread_cancel_cleanup();
static void __queue_destroy_item(gpointer data);
static void __queue_destroy_item(gpointer data)
SP_DEBUG_FLEAVE();
}
-static void __thread_cancel_cleanup(void *user_data)
-{
- SP_DEBUG_FENTER();
-
- stream_cb_manager_t *cbmgr = (stream_cb_manager_t *)user_data;
- g_async_queue_unref(cbmgr->isolator_callback_queue);
-
- pthread_cond_broadcast(&cbmgr->isolator_data_cond);
- pthread_cond_destroy(&cbmgr->isolator_data_cond);
- pthread_mutex_destroy(&cbmgr->isolator_data_mutex);
-
- SP_SAFE_GFREE(cbmgr);
-
- SP_DEBUG_FLEAVE();
-}
-
sound_pool_error_e _stream_cb_manager_process_pending_events(stream_cb_manager_t *cbmgr)
{
SP_DEBUG_FENTER();
static gpointer __sound_pool_callback_isolator(gpointer user_data)
{
SP_DEBUG_FENTER();
- int err = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
- if (err != 0)
- SP_INFO("Can't setup cancel type for isolation thread with error [%d].", err);
- err = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
- if (err != 0)
- SP_INFO("Can't setup cancel state for isolation thread with error [%d].", err);
SP_RETVM_IF(!user_data, NULL, "User data is NULL. Terminate callback thread");
stream_cb_manager_t *cbmgr = (stream_cb_manager_t *)user_data;
- pthread_cleanup_push(__thread_cancel_cleanup, user_data);
pthread_mutex_lock(&cbmgr->isolator_data_mutex);
- gboolean runing = cbmgr->isolator_loop_run;
- pthread_mutex_unlock(&cbmgr->isolator_data_mutex);
- while (runing) {
- pthread_mutex_lock(&cbmgr->isolator_data_mutex);
- while (!cbmgr->isolator_state_changed)
+ while (cbmgr->isolator_loop_run) {
+ while (!cbmgr->isolator_state_changed) {
pthread_cond_wait(&cbmgr->isolator_data_cond, &cbmgr->isolator_data_mutex);
+ if (!cbmgr->isolator_loop_run) {
+ SP_INFO("terminating loop");
+ goto exit;
+ }
+ }
pthread_mutex_unlock(&cbmgr->isolator_data_mutex);
/* Iterate streams have been pushed to the queue and call for each
}
SP_SAFE_GFREE(event_data);
}
+
/* Signal indicating isolator callback thread completed the events */
_stream_cb_manager_signal_completed_events(cbmgr);
-
pthread_mutex_lock(&cbmgr->isolator_data_mutex);
- runing = cbmgr->isolator_loop_run;
- pthread_mutex_unlock(&cbmgr->isolator_data_mutex);
}
- pthread_cleanup_pop(0);
+exit:
+ pthread_mutex_unlock(&cbmgr->isolator_data_mutex);
SP_DEBUG_FLEAVE();
return NULL;
}
/* Wait for completing the isolator callback thread events */
_stream_cb_manager_process_pending_events(cbmgr);
- err = pthread_kill(thread, 0);
- if (0 == err) {
- err = pthread_cancel(thread);
- if (0 != err) {
- SP_ERROR("Error while cancelling of isolation thread[%d].", err);
- ret = SOUND_POOL_ERROR_INVALID_OPERATION;
- GOTO_FAIL("", creturn);
- }
- } else {
- SP_ERROR("Invalid isolation thread[%d].", err);
- ret = SOUND_POOL_ERROR_INVALID_OPERATION;
- GOTO_FAIL("", creturn);
- }
+
+ /* stop thread and wait join */
+ pthread_mutex_lock(&cbmgr->isolator_data_mutex);
+ cbmgr->isolator_loop_run = FALSE;
+ pthread_cond_signal(&cbmgr->isolator_data_cond);
+ pthread_mutex_unlock(&cbmgr->isolator_data_mutex);
err = pthread_join(thread, &return_val);
- if (0 != err)
+ if (0 != err) {
SP_ERROR("Error while joining of isolation thread[%d].", err);
- if (return_val == PTHREAD_CANCELED)
- SP_INFO("Isolation thread canceled.");
- else {
- ret = SOUND_POOL_ERROR_NONE;
- GOTO_FAIL("Routine joining of isolation thread.", creturn);
+ ret = SOUND_POOL_ERROR_INVALID_OPERATION;
}
- SP_DEBUG_FLEAVE();
- return ret;
-
-creturn:
g_async_queue_unref(cbmgr->isolator_callback_queue);
- pthread_mutex_destroy(&cbmgr->isolator_data_mutex);
pthread_cond_destroy(&cbmgr->isolator_data_cond);
+ pthread_mutex_destroy(&cbmgr->isolator_data_mutex);
+
SP_SAFE_GFREE(cbmgr);
+
SP_DEBUG_FLEAVE();
return ret;
}