vblank: interval should be greater than 0
[platform/core/uifw/libtdm.git] / src / tdm_vblank.c
index e1ba393..0362d4e 100644 (file)
@@ -158,10 +158,10 @@ typedef struct _tdm_vblank_create_handler_info {
        void *user_data;
 } tdm_vblank_create_handler_info;
 
-/* valid_vblank_list and valid_wait_list should be protected by valid_list_lock because
- * tdm_vblank can be used in multi-thread.
+/* valid_vblank_list, valid_wait_list and create_handler_list should be protected
+ * by valid_list_lock because tdm_vblank can be used in multi-thread.
  */
-static pthread_mutex_t valid_list_lock;
+static pthread_mutex_t valid_list_lock = PTHREAD_MUTEX_INITIALIZER;
 static struct list_head valid_vblank_list;
 static struct list_head valid_wait_list;
 static struct list_head create_handler_list;
@@ -576,9 +576,10 @@ _tdm_vblank_thread_cb_create(tdm_private_display *private_display, void *object,
                return;
        }
 
-       /* use in_create_handler instead of mutext unlock/lock */
        private_vblank->in_create_handler = 1;
+       tdm_display_unlock(private_display);
        ch_info->func(private_vblank, ch_info->user_data);
+       tdm_display_lock(private_display);
        private_vblank->in_create_handler = 0;
 }
 
@@ -608,18 +609,25 @@ tdm_vblank_add_create_handler(tdm_display *dpy, tdm_vblank_create_handler func,
        tdm_vblank_create_handler_info *ch_info = NULL;
        tdm_error ret;
 
-       TDM_RETURN_VAL_IF_FAIL(!TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
+       TDM_RETURN_VAL_IF_FAIL(dpy != NULL, TDM_ERROR_INVALID_PARAMETER);
        TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
 
+       pthread_mutex_lock(&valid_list_lock);
+
        LIST_FOR_EACH_ENTRY(ch_info, &create_handler_list, link) {
                if (ch_info->func == func && ch_info->user_data == user_data) {
                        TDM_ERR("can't be added twice");
+                       pthread_mutex_unlock(&valid_list_lock);
                        return TDM_ERROR_BAD_REQUEST;
                }
        }
 
        ch_info = calloc(1, sizeof *ch_info);
-       TDM_RETURN_VAL_IF_FAIL(ch_info != NULL, TDM_ERROR_OUT_OF_MEMORY);
+       if (!ch_info) {
+               TDM_ERR("alloc failed: %m");
+               pthread_mutex_unlock(&valid_list_lock);
+               return TDM_ERROR_OUT_OF_MEMORY;
+       }
 
        tdm_display_lock(dpy);
        ret = tdm_thread_cb_add(dpy, TDM_THREAD_CB_VBLANK_CREATE, NULL, _tdm_vblank_thread_cb_create, ch_info);
@@ -628,6 +636,7 @@ tdm_vblank_add_create_handler(tdm_display *dpy, tdm_vblank_create_handler func,
        if (ret != TDM_ERROR_NONE) {
                TDM_ERR("tdm_thread_cb_add failed");
                free(ch_info);
+               pthread_mutex_unlock(&valid_list_lock);
                return ret;
        }
 
@@ -635,6 +644,9 @@ tdm_vblank_add_create_handler(tdm_display *dpy, tdm_vblank_create_handler func,
        ch_info->user_data = user_data;
 
        LIST_ADDTAIL(&ch_info->link, &create_handler_list);
+
+       pthread_mutex_unlock(&valid_list_lock);
+
        return TDM_ERROR_NONE;
 }
 
@@ -643,31 +655,24 @@ tdm_vblank_remove_create_handler(tdm_display *dpy, tdm_vblank_create_handler fun
 {
        tdm_vblank_create_handler_info *ch_info = NULL, *hh = NULL;
 
-       TDM_RETURN_IF_FAIL(!TDM_MUTEX_IS_LOCKED());
-
-       /* we don't allow adding a create handler in sub-thread because tdm_vblank_create()
-        * can be called in both threads and tdm_thread_send_cb supports only one-way
-        * communication now.
-        */
-       if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
-               TDM_ERR("remove_create_handler should be called in main thread");
-               return;
-       }
+       TDM_RETURN_IF_FAIL(dpy != NULL);
+       TDM_RETURN_IF_FAIL(func != NULL);
 
        tdm_display_lock(dpy);
-
+       pthread_mutex_lock(&valid_list_lock);
        LIST_FOR_EACH_ENTRY_SAFE(ch_info, hh, &create_handler_list, link) {
-               if (ch_info->func != func && ch_info->user_data != user_data)
+               if (ch_info->func != func || ch_info->user_data != user_data)
                        continue;
 
                tdm_thread_cb_remove(dpy, TDM_THREAD_CB_VBLANK_CREATE, NULL, _tdm_vblank_thread_cb_create, ch_info);
 
                LIST_DEL(&ch_info->link);
                free(ch_info);
+               pthread_mutex_unlock(&valid_list_lock);
                tdm_display_unlock(dpy);
                return;
        }
-
+       pthread_mutex_unlock(&valid_list_lock);
        tdm_display_unlock(dpy);
 }
 
@@ -683,11 +688,6 @@ tdm_vblank_init(tdm_display *dpy)
        if (vblank_list_inited)
                return TDM_ERROR_NONE;
 
-       if (pthread_mutex_init(&valid_list_lock, NULL)) {
-               TDM_ERR("mutex init failed: %m");
-               return TDM_ERROR_OUT_OF_MEMORY;
-       }
-
        LIST_INITHEAD(&valid_vblank_list);
        LIST_INITHEAD(&valid_wait_list);
        LIST_INITHEAD(&create_handler_list);
@@ -719,8 +719,6 @@ tdm_vblank_deinit(tdm_display *dpy)
                free(ch_info);
        }
 
-       pthread_mutex_destroy(&valid_list_lock);
-
        vblank_list_inited = 0;
 }
 
@@ -906,7 +904,7 @@ tdm_vblank_set_fps(tdm_vblank *vblank, unsigned int fps)
        TDM_RETURN_VAL_IF_FAIL(fps > 0, TDM_ERROR_INVALID_PARAMETER);
 
        if (private_vblank->fps_fixed) {
-               VIN("fps(%d) can't be changed", private_vblank->fps);
+               VIN("fps(%u) can't be changed", private_vblank->fps);
                return TDM_ERROR_NONE;
        }
 
@@ -918,7 +916,7 @@ tdm_vblank_set_fps(tdm_vblank *vblank, unsigned int fps)
        private_vblank->fps = fps;
        private_vblank->check_HW_or_SW = 1;
 
-       VIN("fps(%d) changed", fps);
+       VIN("fps(%u) changed", fps);
 
        return TDM_ERROR_NONE;
 }
@@ -953,7 +951,7 @@ tdm_vblank_set_fixed_fps(tdm_vblank *vblank, unsigned int fps)
        private_vblank->fps = fps;
        private_vblank->check_HW_or_SW = 1;
 
-       VIN("fps(%d) fixed", fps);
+       VIN("fps(%u) fixed", fps);
 
        return TDM_ERROR_NONE;
 }
@@ -971,7 +969,7 @@ tdm_vblank_ignore_global_fps(tdm_vblank *vblank, unsigned int ignore)
        private_vblank->ignore_global_fps = ignore;
        private_vblank->check_HW_or_SW = 1;
 
-       VIN("ignore_global_fps(%d)", private_vblank->ignore_global_fps);
+       VIN("ignore_global_fps(%u)", private_vblank->ignore_global_fps);
 
        return TDM_ERROR_NONE;
 }
@@ -989,7 +987,7 @@ tdm_vblank_set_offset(tdm_vblank *vblank, int offset)
        private_vblank->offset = offset;
        private_vblank->check_HW_or_SW = 1;
 
-       VIN("offset(%d)", private_vblank->offset);
+       VIN("offset(%u)", private_vblank->offset);
 
        return TDM_ERROR_NONE;
 }
@@ -1019,7 +1017,7 @@ tdm_vblank_set_enable_fake(tdm_vblank *vblank, unsigned int enable_fake)
 
        private_vblank->enable_fake = enable_fake;
 
-       VIN("enable_fake(%d)", private_vblank->enable_fake);
+       VIN("enable_fake(%u)", private_vblank->enable_fake);
 
        return TDM_ERROR_NONE;
 }
@@ -1484,6 +1482,7 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec,
 
        TDM_RETURN_VAL_IF_FAIL(tdm_vblank_is_valid(vblank), TDM_ERROR_INVALID_PARAMETER);
        TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
+       TDM_RETURN_VAL_IF_FAIL(interval > 0, TDM_ERROR_INVALID_PARAMETER);
 
        if (private_vblank->in_create_handler) {
                TDM_ERR("NOT allowed to be called in a create handler");