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;
if (connection == TDM_OUTPUT_CONN_STATUS_MODE_SETTED) {
const tdm_output_mode *mode = NULL;
- tdm_output_get_mode(output, &mode);
- if (mode)
+ ret = tdm_output_get_mode(output, &mode);
+ if (ret == TDM_ERROR_NONE && mode)
vrefresh = mode->vrefresh;
else
VWR("mode not setted!!!");
tdm_vblank_set_client_vblank_fps(unsigned int pid, const char *name, unsigned int fps)
{
tdm_private_vblank *v = NULL;
+ tdm_error ret = TDM_ERROR_NONE;
TDM_RETURN_VAL_IF_FAIL(pid > 0, TDM_ERROR_INVALID_PARAMETER);
TDM_RETURN_VAL_IF_FAIL(fps > 0, TDM_ERROR_INVALID_PARAMETER);
continue;
}
- tdm_vblank_set_fps(v, fps);
-
- TDM_INFO("(pid:%u) '%s' fps changed: %d", pid, v->name, fps);
+ ret = tdm_vblank_set_fps(v, fps);
+ if (ret == TDM_ERROR_NONE)
+ TDM_INFO("(pid:%u) '%s' fps changed: %d", pid, v->name, fps);
+ else
+ TDM_ERR("(pid:%u) '%s' fps changing failed: %d", pid, v->name, fps);
}
pthread_mutex_unlock(&valid_list_lock);
tdm_vblank_set_client_ignore_global_fps(unsigned int pid, const char *name, unsigned int ignore)
{
tdm_private_vblank *v = NULL;
+ tdm_error ret = TDM_ERROR_NONE;
TDM_RETURN_VAL_IF_FAIL(pid > 0, TDM_ERROR_INVALID_PARAMETER);
continue;
}
- tdm_vblank_ignore_global_fps(v, ignore);
-
- TDM_INFO("(pid:%u) '%s' ignore changed: %u", pid, v->name, ignore);
+ ret = tdm_vblank_ignore_global_fps(v, ignore);
+ if (ret == TDM_ERROR_NONE)
+ TDM_INFO("(pid:%u) '%s' ignore changed: %u", pid, v->name, ignore);
+ else
+ TDM_ERR("(pid:%u) '%s' ignore changing failed: %u", pid, v->name, ignore);
}
pthread_mutex_unlock(&valid_list_lock);
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;
}
/* LCOV_EXCL_STOP */
}
- tdm_output_add_change_handler(output, _tdm_vblank_cb_output_change, private_vblank);
+ ret = tdm_output_add_change_handler(output, _tdm_vblank_cb_output_change, private_vblank);
+ if (ret != TDM_ERROR_NONE) {
+ free(private_vblank);
+ if (error)
+ *error = TDM_ERROR_OPERATION_FAILED;
+ TDM_ERR("tdm_output_add_change_handler failed");
+ return NULL;
+ }
private_vblank->stamp = ++stamp;
private_vblank->owner_tid = syscall(SYS_gettid);
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;
}
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;
}
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;
}
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;
}
tdm_private_vblank *private_vblank = vblank;
TDM_RETURN_VAL_IF_FAIL(tdm_vblank_is_valid(vblank), TDM_ERROR_INVALID_PARAMETER);
+ TDM_RETURN_VAL_IF_FAIL(offset >= 0, TDM_ERROR_INVALID_PARAMETER);
if (private_vblank->offset == offset)
return TDM_ERROR_NONE;
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;
}
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;
}
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");
wait_info->user_data = user_data;
wait_info->private_vblank = private_vblank;
- if (private_vblank->ignore_global_fps ||
+ if (!private_vblank->resource ||
+ private_vblank->ignore_global_fps ||
vblank_global_fps == 0 ||
private_vblank->fps < vblank_global_fps)
fps = private_vblank->fps;