X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Ftdm_thread.c;h=2cc2f135309dbcdbc06d666960dcce594c640d0d;hb=dc0f94dbd2d214c19b3811ed424647906be77f75;hp=2ca90a01fe8a91e2668ec103ede25194e23ec668;hpb=2adc0c96b4af5f88b3560e8ebd0b595a3f483578;p=platform%2Fcore%2Fuifw%2Flibtdm.git diff --git a/src/tdm_thread.c b/src/tdm_thread.c index 2ca90a0..2cc2f13 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -291,15 +291,11 @@ 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()); - if (!private_loop->private_thread) { - for (i = 0; i < TDM_THREAD_CB_MAX; i++) - find_funcs[i] = NULL; + if (!private_loop->private_thread) return; - } ret = _tdm_thread_exit(private_loop); if (ret != TDM_ERROR_NONE) @@ -344,9 +340,6 @@ 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"); } @@ -466,7 +459,7 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) case TDM_THREAD_CB_CAPTURE_DONE: case TDM_THREAD_CB_VBLANK_SW: case TDM_THREAD_CB_VBLANK_CREATE: - case TDM_THREAD_CB_NEED_VALIDATE: + case TDM_THREAD_CB_HWC_COMMIT: /* this event comes from other thread. so we don't need to propagate this to other thread */ ret = tdm_thread_cb_call(NULL, base, 0); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); @@ -647,16 +640,18 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base, unsigned int propa assert(find_funcs[cb_base->type] != NULL); + if (keep_private_thread && keep_private_thread->thread_tid != caller_tid) { + /* A sync-type event from display-thread to tdm-thread can't be handled. + * If sync-type events happen in both threads at the same time, + * it would make a deadlock issue. + */ + assert(cb_base->sync != 1); + } + if (tdm_debug_module & TDM_DEBUG_THREAD) TDM_INFO("'%s' thread_cb (sync:%d, propagation:%d) ------", tdm_cb_type_str(cb_base->type), cb_base->sync, propagation); - /* handling only output-status as sync. below logic can't handle two sync-type events */ - if (cb_base->type == TDM_THREAD_CB_OUTPUT_STATUS) - assert(cb_base->sync == 1); - else - assert(cb_base->sync == 0); - if (!object) { object = find_funcs[cb_base->type](private_display, cb_base->object_stamp); if (!object) { @@ -713,7 +708,12 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base, unsigned int propa if (!handler_in_other_thread) { if (keep_private_thread) { - if (cb_base->sync && waiting_tid != 0) { + /* NOTE quick fix + * In case of 'cb_base->sync = 0' and 'waiting_tid != 0', + * probably it means one thread is waiting for signal of + * pthread condition. + */ + if (!cb_base->sync && waiting_tid != 0) { waiting_tid = 0; pthread_cond_signal(&keep_private_thread->event_cond); if (tdm_debug_module & TDM_DEBUG_THREAD) @@ -731,11 +731,23 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base, unsigned int propa */ assert(keep_private_thread != NULL); - ret = tdm_thread_send_cb(private_display->private_loop, cb_base); - TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, TDM_ERROR_OPERATION_FAILED); - + if (!cb_base->sync) { + ret = tdm_thread_send_cb(private_display->private_loop, cb_base); + TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, TDM_ERROR_OPERATION_FAILED); + } /* waiting until all cb are done in another thread */ - if (cb_base->sync) { + else { + /* NOTE quick fix + * Sync type event from display-thread(main thread) can't be + * handled. In this way, if we call tdm_thread_send_cb() with + * 'cb_base->sync = 1', then libtdm will eveventually raise + * abort(). Please see commit '4abfab36' for more detail. + */ + cb_base->sync = 0; + ret = tdm_thread_send_cb(private_display->private_loop, cb_base); + TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, TDM_ERROR_OPERATION_FAILED); + cb_base->sync = 1; + /* if waiting_tid is not 0, it means there are two sync-type events at the same time. * and it would make deadlock issue. */