introduce tbm_surface_queue_can_dequeue_wait_timeout 28/194228/5
authorChangyeon Lee <cyeon.lee@samsung.com>
Fri, 30 Nov 2018 06:42:30 +0000 (15:42 +0900)
committerChangyeon Lee <cyeon.lee@samsung.com>
Fri, 28 Dec 2018 07:21:45 +0000 (16:21 +0900)
Change-Id: I6761775bf105b9b6fff8ee1a4af64562b1fdea88

include/tbm_surface_queue.h
include/tbm_type_common.h
src/tbm_surface_queue.c

index 33c500c..b6dc405 100644 (file)
@@ -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
index 8f43737..5a2d82c 100644 (file)
@@ -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;
index 764192d..2377a3f 100644 (file)
@@ -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)
 {