From 012f7c5249364cb40683f0807b976ac1a4470e68 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Fri, 30 Nov 2018 15:42:30 +0900 Subject: [PATCH] introduce tbm_surface_queue_can_dequeue_wait_timeout Change-Id: I6761775bf105b9b6fff8ee1a4af64562b1fdea88 --- include/tbm_surface_queue.h | 4 +++ include/tbm_type_common.h | 1 + src/tbm_surface_queue.c | 70 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) 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) { -- 2.7.4