From 6326a43d10302a0fa9785e9963d6d27f007d876c Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 20 Mar 2018 17:09:23 +0900 Subject: [PATCH] thread: sending the exit request instead of using pthread_cancel To ensure that all operations in the tdm thread are done Change-Id: I05aa6a1d187876522eeaaa2a694bdc2cc8673516 --- src/tdm_macro.h | 1 + src/tdm_private_types.h | 1 + src/tdm_thread.c | 50 ++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/tdm_macro.h b/src/tdm_macro.h index acdc9f3..14c0f7a 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -242,6 +242,7 @@ TDM_TYPE_NAME_FN(value_type) static struct tdm_type_name tdm_cb_type_names[] = { { TDM_THREAD_CB_NONE, "none" }, + { TDM_THREAD_CB_EXIT, "exit" }, { TDM_THREAD_CB_OUTPUT_COMMIT, "output-commit" }, { TDM_THREAD_CB_OUTPUT_VBLANK, "output-vblank" }, { TDM_THREAD_CB_OUTPUT_STATUS, "output-status" }, diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index a5b4423..d71664a 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -447,6 +447,7 @@ typedef struct _tdm_capture_private_buffer { typedef enum { TDM_THREAD_CB_NONE, + TDM_THREAD_CB_EXIT, /* special type to exit the tdm-thread */ TDM_THREAD_CB_OUTPUT_COMMIT, TDM_THREAD_CB_OUTPUT_VBLANK, TDM_THREAD_CB_OUTPUT_STATUS, diff --git a/src/tdm_thread.c b/src/tdm_thread.c index 4f4626f..20e995f 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -46,6 +46,8 @@ struct _tdm_private_thread { pthread_cond_t event_cond; pthread_t event_thread; + unsigned int event_thread_exit; + unsigned int event_thread_joined; pid_t display_tid; pid_t thread_tid; @@ -152,6 +154,9 @@ _tdm_thread_main(void *data) TDM_INFO("server flush"); tdm_event_loop_flush(private_loop->dpy); + if (private_thread->event_thread_exit) + break; + if (tdm_debug_module & TDM_DEBUG_EVENT) TDM_INFO("fd(%d) polling in", fd); @@ -181,6 +186,22 @@ exit_thread: pthread_exit(NULL); } +static tdm_error +_tdm_thread_exit(tdm_private_loop *private_loop) +{ + tdm_thread_cb_base cb_base; + tdm_error ret; + + memset(&cb_base, 0, sizeof cb_base); + cb_base.type = TDM_THREAD_CB_EXIT; + cb_base.length = sizeof cb_base; + + ret = tdm_thread_send_cb(private_loop, &cb_base); + TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); + + return ret; +} + /* NOTE: tdm thread doesn't care about multi-thread. */ INTERN tdm_error tdm_thread_init(tdm_private_loop *private_loop) @@ -269,20 +290,20 @@ tdm_thread_deinit(tdm_private_loop *private_loop) { tdm_private_display *private_display; tdm_private_thread_cb *cb = NULL, *hh = NULL; + tdm_error ret; int i; TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); - for (i = 0; i < TDM_THREAD_CB_MAX; i++) - find_funcs[i] = NULL; - - if (!private_loop->private_thread) + if (!private_loop->private_thread) { + for (i = 0; i < TDM_THREAD_CB_MAX; i++) + find_funcs[i] = NULL; return; + } - if (private_loop->private_thread->sub_event_source) - tdm_event_loop_source_remove(private_loop->private_thread->sub_event_source); - - pthread_cancel(private_loop->private_thread->event_thread); + ret = _tdm_thread_exit(private_loop); + if (ret != TDM_ERROR_NONE) + pthread_cancel(private_loop->private_thread->event_thread); private_display = private_loop->dpy; @@ -291,10 +312,15 @@ tdm_thread_deinit(tdm_private_loop *private_loop) */ _pthread_mutex_unlock(&private_display->lock); pthread_join(private_loop->private_thread->event_thread, NULL); + private_loop->private_thread->event_thread_joined = 1; + TDM_INFO("Joined a TDM event thread"); pthread_mutex_unlock(&cb_list_lock); tdm_log_reset(); + if (private_loop->private_thread->sub_event_source) + tdm_event_loop_source_remove(private_loop->private_thread->sub_event_source); + LIST_FOR_EACH_ENTRY_SAFE(cb, hh, &cb_list[0], link) { _tdm_thread_free_cb(cb); } @@ -318,6 +344,9 @@ tdm_thread_deinit(tdm_private_loop *private_loop) private_loop->private_thread = NULL; keep_private_thread = NULL; + for (i = 0; i < TDM_THREAD_CB_MAX; i++) + find_funcs[i] = NULL; + TDM_INFO("Finish a TDM event thread"); } @@ -442,6 +471,9 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) ret = tdm_thread_cb_call(NULL, base, 0); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); break; + case TDM_THREAD_CB_EXIT: + private_thread->event_thread_exit = 1; + break; default: break; } @@ -467,7 +499,7 @@ tdm_thread_is_running(void) { /* DON'T check TDM_MUTEX_IS_LOCKED here */ - return (keep_private_thread) ? 1 : 0; + return (keep_private_thread && !keep_private_thread->event_thread_joined) ? 1 : 0; } static void -- 2.7.4