#include "tdm_private.h"
#include "tdm_helper.h"
+pthread_mutex_t tdm_mutex_check_lock = PTHREAD_MUTEX_INITIALIZER;
+int tdm_mutex_locked;
+
static tdm_private_layer *
_tdm_display_find_private_layer(tdm_private_output *private_output,
tdm_layer *layer_backend)
goto failed_mutex_init;
}
+ _pthread_mutex_lock(&private_display->lock);
+
ret = tdm_event_loop_init(private_display);
if (ret != TDM_ERROR_NONE)
goto failed_event;
if (error)
*error = TDM_ERROR_NONE;
+ _pthread_mutex_unlock(&private_display->lock);
_pthread_mutex_unlock(&gLock);
return (tdm_display *)private_display;
failed_load:
tdm_event_loop_deinit(private_display);
failed_event:
+ _pthread_mutex_unlock(&private_display->lock);
pthread_mutex_destroy(&private_display->lock);
failed_mutex_init:
free(private_display);
tdm_debug_buffer = 0;
_pthread_mutex_unlock(&gLock);
+
+ TDM_INFO("done");
}
{
tdm_backend_module *module;
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
+
BACKEND_FUNC_ENTRY();
TDM_RETURN_VAL_IF_FAIL(func_display != NULL, TDM_ERROR_INVALID_PARAMETER);
if (_check_abi_version(module, 1, 1) < 0)
return TDM_ERROR_BAD_MODULE;
- _pthread_mutex_lock(&private_display->lock);
private_display->func_display = *func_display;
- _pthread_mutex_unlock(&private_display->lock);
return TDM_ERROR_NONE;
}
{
tdm_backend_module *module;
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
+
BACKEND_FUNC_ENTRY();
TDM_RETURN_VAL_IF_FAIL(func_output != NULL, TDM_ERROR_INVALID_PARAMETER);
if (_check_abi_version(module, 1, 1) < 0)
return TDM_ERROR_BAD_MODULE;
- _pthread_mutex_lock(&private_display->lock);
private_display->func_output = *func_output;
- _pthread_mutex_unlock(&private_display->lock);
return TDM_ERROR_NONE;
}
{
tdm_backend_module *module;
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
+
BACKEND_FUNC_ENTRY();
TDM_RETURN_VAL_IF_FAIL(func_layer != NULL, TDM_ERROR_INVALID_PARAMETER);
if (_check_abi_version(module, 1, 1) < 0)
return TDM_ERROR_BAD_MODULE;
- _pthread_mutex_lock(&private_display->lock);
private_display->func_layer = *func_layer;
- _pthread_mutex_unlock(&private_display->lock);
return TDM_ERROR_NONE;
}
EXTERN tdm_error
tdm_backend_register_func_pp(tdm_display *dpy, tdm_func_pp *func_pp)
{
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
+
BACKEND_FUNC_ENTRY();
if (!func_pp)
return TDM_ERROR_NONE;
- _pthread_mutex_lock(&private_display->lock);
private_display->capabilities |= TDM_DISPLAY_CAPABILITY_PP;
private_display->func_pp = *func_pp;
- _pthread_mutex_unlock(&private_display->lock);
return TDM_ERROR_NONE;
}
tdm_backend_register_func_capture(tdm_display *dpy,
tdm_func_capture *func_capture)
{
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
+
BACKEND_FUNC_ENTRY();
if (!func_capture)
return TDM_ERROR_NONE;
- _pthread_mutex_lock(&private_display->lock);
private_display->capabilities |= TDM_DISPLAY_CAPABILITY_CAPTURE;
private_display->func_capture = *func_capture;
- _pthread_mutex_unlock(&private_display->lock);
return TDM_ERROR_NONE;
}
return;
}
+ if (!tdm_thread_in_display_thread(syscall(SYS_gettid)))
+ TDM_NEVER_GET_HERE();
+
LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) {
tbm_surface_internal_ref(buffer);
func_info->release_func(buffer, func_info->user_data);
tdm_private_display *private_display = private_capture->private_display;
tdm_buffer_info *buf_info;
tbm_surface_h first_entry;
- int lock_after_cb_done = 0;
- int ret;
+
+ TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
if (private_capture->owner_tid != syscall(SYS_gettid)) {
tdm_thread_cb_capture_done capture_done;
if ((buf_info = tdm_buffer_get_info(buffer)))
LIST_DEL(&buf_info->link);
- ret = pthread_mutex_trylock(&private_display->lock);
- if (ret == 0)
- _pthread_mutex_unlock(&private_display->lock);
- else if (ret == EBUSY) {
- _pthread_mutex_unlock(&private_display->lock);
- lock_after_cb_done = 1;
- }
-
+ _pthread_mutex_unlock(&private_display->lock);
tdm_buffer_unref_backend(buffer);
-
- if (lock_after_cb_done)
- _pthread_mutex_lock(&private_display->lock);
+ _pthread_mutex_lock(&private_display->lock);
}
INTERN tdm_private_capture *
{
tdm_private_capture *private_capture = NULL;
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL);
+
LIST_FOR_EACH_ENTRY(private_capture, &private_display->capture_list, link) {
if (private_capture->stamp == stamp)
return private_capture;
tdm_capture *capture_backend = NULL;
tdm_error ret = TDM_ERROR_NONE;
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL);
+
if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
TDM_ERR("no capture capability");
if (error)
tdm_capture *capture_backend = NULL;
tdm_error ret = TDM_ERROR_NONE;
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL);
+
if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
TDM_ERR("no capture capability");
if (error)
tdm_func_capture *func_capture;
tdm_buffer_info *b = NULL, *bb = NULL;
+ TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
+
if (!private_capture)
return;
func_capture->capture_destroy(private_capture->capture_backend);
if (!LIST_IS_EMPTY(&private_capture->pending_buffer_list)) {
- TDM_ERR("capture(%p) not finished:", private_capture);
+ TDM_WRN("capture(%p) not finished:", private_capture);
tdm_buffer_list_dump(&private_capture->pending_buffer_list);
LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_capture->pending_buffer_list, link) {
}
if (!LIST_IS_EMPTY(&private_capture->buffer_list)) {
- TDM_ERR("capture(%p) not finished:", private_capture);
+ TDM_WRN("capture(%p) not finished:", private_capture);
tdm_buffer_list_dump(&private_capture->buffer_list);
LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_capture->buffer_list, link) {
_pthread_mutex_lock(&private_display->lock);
- if (private_display->private_loop->private_thread) {
- _pthread_mutex_unlock(&private_display->lock);
+ if (tdm_thread_is_running())
*fd = tdm_thread_get_fd(private_display->private_loop);
- _pthread_mutex_lock(&private_display->lock);
- }
else
*fd = tdm_event_loop_get_fd(private_display);
if (tdm_debug_thread)
TDM_INFO("fd(%d) polling out", fd);
- _pthread_mutex_lock(&private_display->lock);
-
- if (private_display->private_loop->private_thread) {
- _pthread_mutex_unlock(&private_display->lock);
+ if (tdm_thread_is_running())
ret = tdm_thread_handle_cb(private_display->private_loop);
- _pthread_mutex_lock(&private_display->lock);
- }
else
ret = tdm_event_loop_dispatch(private_display);
- _pthread_mutex_unlock(&private_display->lock);
-
return ret;
}
tdm_private_display *private_display;
tdm_private_output *private_output = user_data;
tdm_value value;
- int lock_after_cb_done = 0;
- int ret;
+ TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
TDM_RETURN_IF_FAIL(private_output);
private_display = private_output->private_display;
- if (!tdm_thread_in_display_thread(private_display->private_loop,
- syscall(SYS_gettid))) {
+ if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
tdm_thread_cb_output_status output_status;
tdm_error ret;
return;
}
- ret = pthread_mutex_trylock(&private_display->lock);
- if (ret == 0)
- _pthread_mutex_unlock(&private_display->lock);
- else if (ret == EBUSY) {
- _pthread_mutex_unlock(&private_display->lock);
- lock_after_cb_done = 1;
- }
-
value.u32 = status;
tdm_output_call_change_handler_internal(private_output,
&private_output->change_handler_list_main,
TDM_OUTPUT_CHANGE_CONNECTION,
value);
-
- if (lock_after_cb_done)
- _pthread_mutex_lock(&private_display->lock);
}
EXTERN tdm_error
change_handler->user_data = user_data;
change_handler->owner_tid = syscall(SYS_gettid);
- if (!tdm_thread_in_display_thread(private_display->private_loop,
- change_handler->owner_tid))
+ if (!tdm_thread_in_display_thread(change_handler->owner_tid))
LIST_ADD(&change_handler->link, &private_output->change_handler_list_sub);
else
LIST_ADD(&change_handler->link, &private_output->change_handler_list_main);
tdm_private_vblank_handler *vblank_handler = user_data;
tdm_private_display *private_display;
+ TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
TDM_RETURN_IF_FAIL(vblank_handler);
private_display = vblank_handler->private_output->private_display;
TDM_NEVER_GET_HERE();
if (vblank_handler->func) {
- int lock_after_cb_done = 0;
- int ret;
-
- ret = pthread_mutex_trylock(&private_display->lock);
- if (ret == 0)
- _pthread_mutex_unlock(&private_display->lock);
- else if (ret == EBUSY) {
- _pthread_mutex_unlock(&private_display->lock);
- lock_after_cb_done = 1;
- }
-
+ _pthread_mutex_unlock(&private_display->lock);
vblank_handler->func(vblank_handler->private_output, sequence,
tv_sec, tv_usec, vblank_handler->user_data);
-
- if (lock_after_cb_done)
- _pthread_mutex_lock(&private_display->lock);
+ _pthread_mutex_lock(&private_display->lock);
}
LIST_DEL(&vblank_handler->link);
tdm_private_display *private_display;
tdm_private_output *private_output;
tdm_private_layer *private_layer = NULL;
- int lock_after_cb_done = 0;
- int ret;
+ TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
TDM_RETURN_IF_FAIL(commit_handler);
private_output = commit_handler->private_output;
return;
}
- ret = pthread_mutex_trylock(&private_display->lock);
- if (ret == 0)
- _pthread_mutex_unlock(&private_display->lock);
- else if (ret == EBUSY) {
- _pthread_mutex_unlock(&private_display->lock);
- lock_after_cb_done = 1;
- }
-
LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
if (!private_layer->waiting_buffer)
continue;
if (private_layer->showing_buffer) {
+ _pthread_mutex_unlock(&private_display->lock);
tdm_buffer_unref_backend(private_layer->showing_buffer);
+ _pthread_mutex_lock(&private_display->lock);
if (private_layer->buffer_queue) {
tbm_surface_queue_release(private_layer->buffer_queue,
}
if (commit_handler->func) {
+ _pthread_mutex_unlock(&private_display->lock);
commit_handler->func(private_output, sequence,
tv_sec, tv_usec, commit_handler->user_data);
- }
-
- if (lock_after_cb_done)
_pthread_mutex_lock(&private_display->lock);
+ }
LIST_DEL(&commit_handler->link);
free(commit_handler);
tdm_private_display *private_display;
tdm_private_change_handler *change_handler;
+ TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
TDM_RETURN_IF_FAIL(private_output);
private_display = private_output->private_display;
- if (!tdm_thread_in_display_thread(private_display->private_loop,
- syscall(SYS_gettid))) {
+ if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
if (type & TDM_OUTPUT_CHANGE_CONNECTION)
TDM_INFO("output(%d) changed: %s (%d)",
private_output->pipe, status_str(value.u32), value.u32);
if (change_handler->owner_tid != syscall(SYS_gettid))
TDM_NEVER_GET_HERE();
+ _pthread_mutex_unlock(&private_display->lock);
change_handler->func(private_output, type,
value, change_handler->user_data);
+ _pthread_mutex_lock(&private_display->lock);
}
}
tdm_func_display *func_display;
tdm_error ret;
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
TDM_RETURN_VAL_IF_FAIL(private_display != NULL, TDM_ERROR_OPERATION_FAILED);
TDM_RETURN_VAL_IF_FAIL(private_display->private_loop != NULL, TDM_ERROR_OPERATION_FAILED);
tdm_private_loop *private_loop;
tdm_error ret;
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
+
if (private_display->private_loop)
return TDM_ERROR_NONE;
INTERN void
tdm_event_loop_deinit(tdm_private_display *private_display)
{
+ TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
+
if (!private_display->private_loop)
return;
tdm_error ret;
int fd = -1;
+ TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
TDM_RETURN_IF_FAIL(private_loop != NULL);
func_display = &private_display->func_display;
{
tdm_private_loop *private_loop = private_display->private_loop;
+ /* DON'T check TDM_MUTEX_IS_LOCKED here */
+
TDM_RETURN_VAL_IF_FAIL(private_loop->wl_loop != NULL, -1);
return wl_event_loop_get_fd(private_loop->wl_loop);
{
tdm_private_loop *private_loop = private_display->private_loop;
+ /* DON'T check TDM_MUTEX_IS_LOCKED here */
+
TDM_RETURN_VAL_IF_FAIL(private_loop->wl_loop != NULL, TDM_ERROR_OPERATION_FAILED);
if (tdm_debug_thread)
{
tdm_private_loop *private_loop = private_display->private_loop;
+ /* DON'T check TDM_MUTEX_IS_LOCKED here */
+
TDM_RETURN_IF_FAIL(private_loop->wl_display != NULL);
wl_display_flush_clients(private_loop->wl_display);
_tdm_event_loop_fd_func(int fd, uint32_t wl_mask, void *data)
{
tdm_event_loop_source_fd *fd_source = (tdm_event_loop_source_fd*)data;
+ tdm_private_display *private_display;
tdm_event_loop_mask mask = 0;
+ /* DON'T check TDM_MUTEX_IS_LOCKED here */
+
TDM_RETURN_VAL_IF_FAIL(fd_source, 1);
TDM_RETURN_VAL_IF_FAIL(fd_source->func, 1);
+ private_display = fd_source->private_display;
+
if (wl_mask & WL_EVENT_READABLE)
mask |= TDM_EVENT_LOOP_READABLE;
if (wl_mask & WL_EVENT_WRITABLE)
if (wl_mask & WL_EVENT_ERROR)
mask |= TDM_EVENT_LOOP_ERROR;
+ _pthread_mutex_lock(&private_display->lock);
fd_source->func(fd, mask, fd_source->user_data);
+ _pthread_mutex_unlock(&private_display->lock);
return 1;
}
uint32_t wl_mask = 0;
tdm_error ret;
+ TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED, NULL);
TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(dpy, TDM_ERROR_INVALID_PARAMETER, NULL);
TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(fd >= 0, TDM_ERROR_INVALID_PARAMETER, NULL);
TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(func, TDM_ERROR_INVALID_PARAMETER, NULL);
tdm_event_loop_source_fd *fd_source = source;
uint32_t wl_mask = 0;
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
TDM_RETURN_VAL_IF_FAIL(fd_source, TDM_ERROR_INVALID_PARAMETER);
if (mask & TDM_EVENT_LOOP_READABLE)
_tdm_event_loop_timer_func(void *data)
{
tdm_event_loop_source_timer *timer_source = (tdm_event_loop_source_timer*)data;
+ tdm_private_display *private_display;
+
+ /* DON'T check TDM_MUTEX_IS_LOCKED here */
TDM_RETURN_VAL_IF_FAIL(timer_source, 1);
TDM_RETURN_VAL_IF_FAIL(timer_source->func, 1);
+ private_display = timer_source->private_display;
+
+ _pthread_mutex_lock(&private_display->lock);
timer_source->func(timer_source->user_data);
+ _pthread_mutex_unlock(&private_display->lock);
return 1;
}
tdm_event_loop_source_timer *timer_source;
tdm_error ret;
+ TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED, NULL);
TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(dpy, TDM_ERROR_INVALID_PARAMETER, NULL);
TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(func, TDM_ERROR_INVALID_PARAMETER, NULL);
{
tdm_event_loop_source_timer *timer_source = source;
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
TDM_RETURN_VAL_IF_FAIL(timer_source, TDM_ERROR_INVALID_PARAMETER);
if (wl_event_source_timer_update(timer_source->base.wl_source, ms_delay) < 0) {
{
tdm_event_loop_source_base *base = (tdm_event_loop_source_base*)source;
+ TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
+
if (!base)
return;
static int *tdm_helper_dump_count;
static char *tdm_helper_dump_path;
-INTERN int
-tdm_helper_unlock_in_cb(tdm_private_display *private_display)
-{
- int ret = pthread_mutex_trylock(&private_display->lock);
- int need_lock = 0;
-
- if (ret == 0)
- _pthread_mutex_unlock(&private_display->lock);
- else if (ret == EBUSY) {
- _pthread_mutex_unlock(&private_display->lock);
- need_lock = 1;
- }
-
- return need_lock;
-}
-
-INTERN void
-tdm_helper_lock_in_cb(tdm_private_display *private_display, int need_lock)
-{
- if (!need_lock)
- return;
-
- _pthread_mutex_lock(&private_display->lock);
-}
-
INTERN unsigned long
tdm_helper_get_time_in_millis(void)
{
tdm_private_display *private_display = private_pp->private_display;
tdm_buffer_info *buf_info;
tbm_surface_h first_entry;
- int lock_after_cb_done = 0;
- int ret;
+
+ TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
if (private_pp->owner_tid != syscall(SYS_gettid)) {
tdm_thread_cb_pp_done pp_done;
if ((buf_info = tdm_buffer_get_info(dst)))
LIST_DEL(&buf_info->link);
- ret = pthread_mutex_trylock(&private_display->lock);
- if (ret == 0)
- _pthread_mutex_unlock(&private_display->lock);
- else if (ret == EBUSY) {
- _pthread_mutex_unlock(&private_display->lock);
- lock_after_cb_done = 1;
- }
-
+ _pthread_mutex_unlock(&private_display->lock);
tdm_buffer_unref_backend(src);
tdm_buffer_unref_backend(dst);
-
- if (lock_after_cb_done)
- _pthread_mutex_lock(&private_display->lock);
+ _pthread_mutex_lock(&private_display->lock);
}
INTERN tdm_private_pp *
{
tdm_private_pp *private_pp = NULL;
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL);
+
LIST_FOR_EACH_ENTRY(private_pp, &private_display->pp_list, link) {
if (private_pp->stamp == stamp)
return private_pp;
tdm_pp *pp_backend = NULL;
tdm_error ret = TDM_ERROR_NONE;
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL);
+
func_display = &private_display->func_display;
func_pp = &private_display->func_pp;
tdm_func_pp *func_pp;
tdm_buffer_info *b = NULL, *bb = NULL;
+ TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
+
if (!private_pp)
return;
func_pp->pp_destroy(private_pp->pp_backend);
if (!LIST_IS_EMPTY(&private_pp->src_pending_buffer_list)) {
- TDM_ERR("pp(%p) not finished:", private_pp);
+ TDM_WRN("pp(%p) not finished:", private_pp);
tdm_buffer_list_dump(&private_pp->src_pending_buffer_list);
LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->src_pending_buffer_list, link) {
}
if (!LIST_IS_EMPTY(&private_pp->dst_pending_buffer_list)) {
- TDM_ERR("pp(%p) not finished:", private_pp);
+ TDM_WRN("pp(%p) not finished:", private_pp);
tdm_buffer_list_dump(&private_pp->dst_pending_buffer_list);
LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->dst_pending_buffer_list, link) {
}
if (!LIST_IS_EMPTY(&private_pp->src_buffer_list)) {
- TDM_ERR("pp(%p) not finished:", private_pp);
+ TDM_WRN("pp(%p) not finished:", private_pp);
tdm_buffer_list_dump(&private_pp->src_buffer_list);
LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->src_buffer_list, link) {
}
if (!LIST_IS_EMPTY(&private_pp->dst_buffer_list)) {
- TDM_ERR("pp(%p) not finished:", private_pp);
+ TDM_WRN("pp(%p) not finished:", private_pp);
tdm_buffer_list_dump(&private_pp->dst_buffer_list);
LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->dst_buffer_list, link) {
};
/* CAUTION:
- * Note that this structure is not thread-safe. If there is no TDM thread, all
- * TDM resources are protected by private_display's lock. If there is a TDM
- * thread, this struct will be used only in a TDM thread. So, we don't need to
- * protect this structure.
+ * Note that we don't need to (un)lock mutex to use this structure. If there is
+ * no TDM thread, all TDM resources are protected by private_display's mutex.
+ * If there is a TDM thread, this struct will be used only in a TDM thread.
+ * So, we don't need to protect this structure by mutex. Not thread-safe.
*/
struct _tdm_private_loop {
/* TDM uses wl_event_loop to handle various event sources including the TDM
/* In event loop, all resources are accessed by this dpy.
* CAUTION:
* - DO NOT include other private structure in this structure because this
- * struct is not thread-safe.
+ * struct is not protected by mutex.
*/
tdm_display *dpy;
tdm_error
tdm_thread_handle_cb(tdm_private_loop *private_loop);
int
-tdm_thread_in_display_thread(tdm_private_loop *private_loop, pid_t tid);
+tdm_thread_in_display_thread(pid_t tid);
+int
+tdm_thread_is_running(void);
tdm_error
tdm_server_init(tdm_private_loop *private_loop);
unsigned long
tdm_helper_get_time_in_millis(void);
-int
-tdm_helper_unlock_in_cb(tdm_private_display *private_display);
-void
-tdm_helper_lock_in_cb(tdm_private_display *private_display, int need_lock);
+
+extern pthread_mutex_t tdm_mutex_check_lock;
+extern int tdm_mutex_locked;
int
tdm_helper_get_dump_count(void);
tdm_helper_get_dump_path(void);
#define _pthread_mutex_lock(l) \
- do {if (tdm_debug_mutex) TDM_INFO("mutex lock"); pthread_mutex_lock(l);} while (0)
+ do { \
+ if (tdm_debug_mutex) \
+ TDM_INFO("mutex lock"); \
+ pthread_mutex_lock(l); \
+ pthread_mutex_lock(&tdm_mutex_check_lock); \
+ tdm_mutex_locked = 1; \
+ pthread_mutex_unlock(&tdm_mutex_check_lock); \
+ } while (0)
+
#define _pthread_mutex_unlock(l) \
- do {if (tdm_debug_mutex) TDM_INFO("mutex unlock"); pthread_mutex_unlock(l);} while (0)
+ do { \
+ if (tdm_debug_mutex) \
+ TDM_INFO("mutex unlock"); \
+ pthread_mutex_lock(&tdm_mutex_check_lock); \
+ tdm_mutex_locked = 0; \
+ pthread_mutex_unlock(&tdm_mutex_check_lock); \
+ pthread_mutex_unlock(l); \
+ } while (0)
+
+//#define TDM_MUTEX_IS_LOCKED() (tdm_mutex_locked == 1)
+static inline int TDM_MUTEX_IS_LOCKED(void)
+{
+ int ret;
+ pthread_mutex_lock(&tdm_mutex_check_lock);
+ ret = (tdm_mutex_locked == 1);
+ pthread_mutex_unlock(&tdm_mutex_check_lock);
+ return ret;
+}
#ifdef __cplusplus
}
#include "tdm-server-protocol.h"
/* CAUTION:
- * - tdm server doesn't care about multi-thread.
+ * - tdm server doesn't care about thread things.
* - DO NOT use the TDM internal functions here.
*/
tdm_private_server *private_server;
} tdm_server_vblank_info;
-static tdm_private_loop *keep_private_loop;
+static tdm_private_server *keep_private_server;
static void
_tdm_server_cb_output_vblank(tdm_output *output, unsigned int sequence,
tdm_server_vblank_info *vblank_info = (tdm_server_vblank_info*)user_data;
tdm_server_vblank_info *found;
- if (!keep_private_loop || !keep_private_loop->private_server)
+ if (!keep_private_server)
return;
- LIST_FIND_ITEM(vblank_info, &keep_private_loop->private_server->vblank_list,
+ LIST_FIND_ITEM(vblank_info, &keep_private_server->vblank_list,
tdm_server_vblank_info, link, found);
if (!found) {
TDM_DBG("vblank_info(%p) is destroyed", vblank_info);
}
private_loop->private_server = private_server;
- keep_private_loop = private_loop;
+ keep_private_server = private_server;
return TDM_ERROR_NONE;
}
free(private_server);
private_loop->private_server = NULL;
- keep_private_loop = NULL;
+ keep_private_server = NULL;
}
#include "tdm_private.h"
#include "tdm_list.h"
+static tdm_private_thread *keep_private_thread;
+
struct _tdm_private_thread {
tdm_private_loop *private_loop;
tdm_private_thread *private_thread;
const char *thread;
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
TDM_RETURN_VAL_IF_FAIL(private_loop->dpy, TDM_ERROR_OPERATION_FAILED);
private_display = private_loop->dpy;
pthread_create(&private_thread->event_thread, NULL, _tdm_thread_main,
private_thread);
+ keep_private_thread = private_thread;
+
TDM_INFO("using a TDM event thread. pipe(%d,%d)",
private_thread->pipe[0], private_thread->pipe[1]);
INTERN void
tdm_thread_deinit(tdm_private_loop *private_loop)
{
+ TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
+
if (!private_loop->private_thread)
return;
free(private_loop->private_thread);
private_loop->private_thread = NULL;
+ keep_private_thread = NULL;
TDM_INFO("Finish a TDM event thread");
}
{
tdm_private_thread *private_thread;
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
TDM_RETURN_VAL_IF_FAIL(private_loop, -1);
TDM_RETURN_VAL_IF_FAIL(private_loop->private_thread, -1);
tdm_private_thread *private_thread;
ssize_t len;
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
TDM_RETURN_VAL_IF_FAIL(base, TDM_ERROR_INVALID_PARAMETER);
TDM_RETURN_VAL_IF_FAIL(private_loop, TDM_ERROR_INVALID_PARAMETER);
TDM_RETURN_VAL_IF_FAIL(private_loop->private_thread, TDM_ERROR_INVALID_PARAMETER);
INTERN tdm_error
tdm_thread_handle_cb(tdm_private_loop *private_loop)
{
+ tdm_private_display *private_display;
tdm_private_thread *private_thread;
tdm_thread_cb_base *base;
char buffer[1024];
int len, i;
+ /* DON'T check TDM_MUTEX_IS_LOCKED here */
+
TDM_RETURN_VAL_IF_FAIL(private_loop, TDM_ERROR_INVALID_PARAMETER);
TDM_RETURN_VAL_IF_FAIL(private_loop->private_thread, TDM_ERROR_INVALID_PARAMETER);
private_thread = private_loop->private_thread;
+ private_display = private_loop->dpy;
len = read(private_thread->pipe[0], buffer, sizeof buffer);
return TDM_ERROR_OPERATION_FAILED;
}
+ _pthread_mutex_lock(&private_display->lock);
+
i = 0;
while (i < len) {
base = (tdm_thread_cb_base*)&buffer[i];
i += base->length;
}
+ _pthread_mutex_unlock(&private_display->lock);
+
tdm_event_loop_flush(private_loop->dpy);
return TDM_ERROR_NONE;
}
INTERN int
-tdm_thread_in_display_thread(tdm_private_loop *private_loop, pid_t tid)
+tdm_thread_in_display_thread(pid_t tid)
{
- tdm_private_thread *private_thread;
+ if (!keep_private_thread)
+ return 1;
- TDM_RETURN_VAL_IF_FAIL(private_loop, 1);
+ /* DON'T check TDM_MUTEX_IS_LOCKED here */
- if (!private_loop->private_thread)
- return 1;
+ return (keep_private_thread->display_tid == tid) ? 1 : 0;
+}
- private_thread = private_loop->private_thread;
+INTERN int
+tdm_thread_is_running(void)
+{
+ /* DON'T check TDM_MUTEX_IS_LOCKED here */
- return (private_thread->display_tid == tid) ? 1 : 0;
+ return (keep_private_thread) ? 1 : 0;
}