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;
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;
}
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);
if (ret != TDM_ERROR_NONE) {
TDM_ERR("tdm_thread_cb_add failed");
free(ch_info);
+ pthread_mutex_unlock(&valid_list_lock);
return ret;
}
ch_info->user_data = user_data;
LIST_ADDTAIL(&ch_info->link, &create_handler_list);
+
+ pthread_mutex_unlock(&valid_list_lock);
+
return TDM_ERROR_NONE;
}
{
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);
}
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);
free(ch_info);
}
- pthread_mutex_destroy(&valid_list_lock);
-
vblank_list_inited = 0;
}
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");