From: Changyeon Lee Date: Fri, 30 Nov 2018 06:42:30 +0000 (+0900) Subject: introduce tbm_surface_queue_can_dequeue_wait_timeout X-Git-Tag: accepted/tizen/unified/20190107.065427~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F28%2F194228%2F5;p=platform%2Fcore%2Fuifw%2Flibtbm.git introduce tbm_surface_queue_can_dequeue_wait_timeout Change-Id: I6761775bf105b9b6fff8ee1a4af64562b1fdea88 --- diff --git a/include/tbm_surface_queue.h b/include/tbm_surface_queue.h index 33c500c..b6dc405 100644 --- a/include/tbm_surface_queue.h +++ b/include/tbm_surface_queue.h @@ -966,6 +966,10 @@ tbm_surface_queue_error_e tbm_surface_queue_remove_trace_cb( tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb, void *data); +tbm_surface_queue_error_e +tbm_surface_queue_can_dequeue_wait_timeout( + tbm_surface_queue_h surface_queue, int ms_timeout); + #ifdef __cplusplus } #endif diff --git a/include/tbm_type_common.h b/include/tbm_type_common.h index 8f43737..5a2d82c 100644 --- a/include/tbm_type_common.h +++ b/include/tbm_type_common.h @@ -126,6 +126,7 @@ typedef enum { TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST = TBM_ERROR_BASE | 0x0305, /**< Already existed surface */ TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE = TBM_ERROR_BASE | 0x0306, /**< Unknown surface */ TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE = TBM_ERROR_BASE | 0x0307, /**< Invalid sequence */ + TBM_SURFACE_QUEUE_ERROR_TIMEOUT = TBM_ERROR_BASE | 0x0308, /**< Timeout */ } tbm_error_e; typedef tbm_error_e tbm_surface_queue_error_e; diff --git a/src/tbm_surface_queue.c b/src/tbm_surface_queue.c index 764192d..2377a3f 100644 --- a/src/tbm_surface_queue.c +++ b/src/tbm_surface_queue.c @@ -1307,6 +1307,76 @@ tbm_surface_queue_dequeue(tbm_surface_queue_h return TBM_SURFACE_QUEUE_ERROR_NONE; } +tbm_surface_queue_error_e +tbm_surface_queue_can_dequeue_wait_timeout(tbm_surface_queue_h surface_queue, int ms_timeout) +{ + int ret; + struct timespec tp; + + _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); + + TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), + TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); + + _tbm_surf_queue_mutex_unlock(); + + _notify_emit(surface_queue, &surface_queue->can_dequeue_noti); + + _tbm_surf_queue_mutex_lock(); + + TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), + TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); + + pthread_mutex_lock(&surface_queue->lock); + + TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue); + + if (_queue_is_empty(&surface_queue->free_queue)) { + if (surface_queue->impl && surface_queue->impl->need_attach) + surface_queue->impl->need_attach(surface_queue); + + if (!_tbm_surface_queue_is_valid(surface_queue)) { + TBM_ERR("surface_queue:%p is invalid", surface_queue); + pthread_mutex_unlock(&surface_queue->lock); + _tbm_surf_queue_mutex_unlock(); + return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE; + } + } + + if (!_queue_is_empty(&surface_queue->free_queue)) { + pthread_mutex_unlock(&surface_queue->lock); + _tbm_surf_queue_mutex_unlock(); + return TBM_SURFACE_QUEUE_ERROR_NONE; + } + + _tbm_surf_queue_mutex_unlock(); + + while (1) { + clock_gettime(CLOCK_REALTIME, &tp); + + if (ms_timeout > 1000) + tp.tv_sec += ms_timeout / 1000; + + tp.tv_nsec += (ms_timeout % 1000) * 1000000; + + ret = pthread_cond_timedwait(&surface_queue->free_cond, &surface_queue->lock, &tp); + if (ret) { + if (ret == ETIMEDOUT) { + TBM_ERR("surface_queue:%p can dequeue wait timeout", surface_queue); + pthread_mutex_unlock(&surface_queue->lock); + return TBM_SURFACE_QUEUE_ERROR_TIMEOUT; + } else { + TBM_INFO("surface_queue:%p timedwait error retry wait", surface_queue); + } + } + else { + pthread_mutex_unlock(&surface_queue->lock); + return TBM_SURFACE_QUEUE_ERROR_NONE; + } + } +} + int tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait) {