thread_state state;
pthread_t thread_id;
// END
+ struct wl_display *display;
};
struct wl_display {
// TIZEN_ONLY(20190716) : wayland-client : force sync of display when threads are waiting for over WL_PTHREAD_COND_TIMEDWAIT_TIMEOUT
uint32_t force_sync_count;
// END
+ uint32_t threads_count;
};
/** \endcond */
static void
destroy_thread_data(void *data)
{
+ struct wl_display *display = NULL;
struct wl_thread_data *thread_data = data;
+ display = thread_data->display;
+ assert(display);
+
wl_list_remove(&thread_data->link);
- wl_log("Thread removed[%p pid:%d tid: %d]\n", thread_data, thread_data->pid, thread_data->tid);
+ display->threads_count--;
+ wl_log("Thread removed[%p pid:%d tid: %d] from display:%p, threads_cnt=%d\n",
+ thread_data, thread_data->pid, thread_data->tid, display, display->threads_count);
+
+ if (thread_data->reader_count_in_thread > 0)
+ wl_display_cancel_read(display);
free(thread_data);
}
thread_data->pid = (int)getpid();
thread_data->tid = (int)syscall(SYS_gettid);
+ thread_data->display = display;
// TIZEN_ONLY(20190716) : wayland-client : force sync of display when threads are waiting for over WL_PTHREAD_COND_TIMEDWAIT_TIMEOUT
thread_data->state = WL_THREAD_STATE_INITIAL;
thread_data->thread_id = pthread_self();
// END
wl_list_insert(&display->threads, &thread_data->link);
- wl_log("Thread added[%p, pid:%d tid: %d] to display:%p\n", thread_data, thread_data->pid, thread_data->tid, display);
+ display->threads_count++;
+ wl_log("Thread added[%p, pid:%d tid: %d] to display:%p, threads_cnt=%d\n",
+ thread_data, thread_data->pid, thread_data->tid, display, display->threads_count);
}
return thread_data;
if (display->connection == NULL)
goto err_connection;
+ display->threads_count = 0;
wl_list_init(&display->threads);
if (pthread_key_create(&display->thread_data_key, destroy_thread_data) < 0)
goto err_connection;
destroy_queued_closure(closure);
}
+static int
+_check_reader_counts(struct wl_display *display)
+{
+ struct wl_thread_data *thread_data;
+ struct wl_thread_data *th_data, *th_data_next;
+
+ int cnt = 0;
+ int threads_reader_counts = 0;
+
+ thread_data = get_thread_data(display);
+ assert(thread_data);
+
+ wl_log("[check_reader_counts] Number of threads=%d, reader_count=%d\n", display->threads_count, display->reader_count);
+
+ wl_list_for_each_safe(th_data, th_data_next, &display->threads, link) {
+ wl_log("... thread[%d]:reader_count_in_thread=%d\n", cnt++, th_data->reader_count_in_thread);
+
+ if (th_data->reader_count_in_thread > 0)
+ threads_reader_counts++;
+ }
+
+ if (threads_reader_counts < display->reader_count)
+ {
+ wl_log("[check_reader_counts] Abnormal reader_count !\n");
+ wl_log("... reader_count=%d, total reader counts of threads=%d\n", display->reader_count, threads_reader_counts);
+
+ return 1;
+ }
+
+ return 0;
+}
+
// TIZEN_ONLY(20190716) : wayland-client : force sync of display when threads are waiting for over WL_PTHREAD_COND_TIMEDWAIT_TIMEOUT
static void
log_threads_reader_info(struct wl_display *display)
struct timespec ts;
int ret = 0, res = 0;
// END
+ uint32_t _force_sync_count = 0;
thread_data = get_thread_data(display);
assert(thread_data);
wl_log("[read events] display->read_serial : %d, serial : %d\n", display->read_serial, serial);
wl_log("=== Timeout on pthread_cond_timedwait. End of data leaving !===\n");
+ /* After having waited for two times by calling pthread_cond_timedwait() and
+ * if the last reader (thread) doesn't wake the waiting threads up, it is considered to be an abnormal situation.
+ * Do wl_abort().
+ */
+ if (_force_sync_count > 1 && display->read_serial == serial)
+ {
+ if (_check_reader_counts(display))
+ {
+ if (!errno)
+ errno = display->last_error;
+
+ wl_abort("Invalid reader count ! Abort !(reader_count=%d, errno=%d, last_error=%d)\n", display->reader_count, errno, display->last_error);
+ }
+ }
+
thread_data->state |= WL_THREAD_STATE_FORCE_DISPLAY_SYNC_BEGIN;
wl_log("=== FORCE_DISPLAY_SYNC BEGIN ===\n");
res = force_display_sync(display);
display->force_sync_count++;
+ _force_sync_count++;
thread_data->state |= WL_THREAD_STATE_FORCE_DISPLAY_SYNC_DONE;
wl_log("=== FORCE_DISPLAY_SYNC DONE (res=%d, force_sync_count=%d) ===\n", res, display->force_sync_count);