Merge branch 'log_undispatched_queues' into 'main'

client: print a warning for undispatched queues when debugging

See merge request wayland/wayland!386
This commit is contained in:
Derek Foreman 2025-09-23 08:46:30 -05:00
commit ba19c5342f

View file

@ -78,6 +78,9 @@ struct wl_event_queue {
struct wl_list proxy_list; /**< struct wl_proxy::queue_link */
struct wl_display *display;
char *name;
uint64_t last_dispatch;
bool logged_stale_dispatch_warning;
struct wl_list link; /**< struct wl_display::queue_list */
};
struct wl_display {
@ -103,6 +106,7 @@ struct wl_display {
} protocol_error;
int fd;
struct wl_map objects;
struct wl_list queue_list; /**< struct wl_event_queue::link */
struct wl_event_queue display_queue;
struct wl_event_queue default_queue;
pthread_mutex_t mutex;
@ -117,6 +121,36 @@ struct wl_display {
static int debug_client = 0;
static int debug_color = 0;
static void
wl_display_debug_dispatch(struct wl_display *display)
{
struct wl_event_queue *queue;
struct timespec tp;
uint64_t now;
clock_gettime(CLOCK_MONOTONIC, &tp);
now = timespec_to_msec(&tp);
wl_list_for_each(queue, &display->queue_list, link) {
if (wl_list_empty(&queue->event_list) ||
queue->logged_stale_dispatch_warning)
continue;
if (now > queue->last_dispatch + 3000) {
struct timespec tp;
unsigned int realtime;
clock_gettime(CLOCK_REALTIME, &tp);
realtime = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
fprintf(stderr, "[%7u.%03u] {%s} has undispatched"
" events for more than 3 seconds\n",
realtime / 1000, realtime % 1000,
queue->name ? queue->name : "Unnamed queue");
queue->logged_stale_dispatch_warning = true;
}
}
}
/**
* This helper function wakes up all threads that are
* waiting for display->reader_cond (i. e. when reading is done,
@ -231,6 +265,16 @@ wl_event_queue_init(struct wl_event_queue *queue,
queue->display = display;
if (name)
queue->name = strdup(name);
if (debug_client) {
struct timespec tp;
clock_gettime(CLOCK_MONOTONIC, &tp);
queue->last_dispatch = timespec_to_msec(&tp);
queue->logged_stale_dispatch_warning = false;
}
wl_list_insert(&display->queue_list, &queue->link);
}
static void
@ -344,6 +388,8 @@ wl_event_queue_release(struct wl_event_queue *queue)
wl_list_remove(&closure->link);
destroy_queued_closure(closure);
}
wl_list_remove(&queue->link);
}
/** Destroy an event queue
@ -906,6 +952,9 @@ wl_proxy_marshal_array_flags(struct wl_proxy *proxy, uint32_t opcode,
pthread_mutex_lock(&disp->mutex);
if (debug_client)
wl_display_debug_dispatch(disp);
message = &proxy->object.interface->methods[opcode];
if (interface) {
new_proxy = create_outgoing_proxy(proxy, message,
@ -1256,6 +1305,7 @@ wl_display_connect_to_fd(int fd)
display->fd = fd;
wl_map_init(&display->objects, WL_MAP_CLIENT_SIDE);
wl_list_init(&display->queue_list);
wl_event_queue_init(&display->default_queue, display, "Default Queue");
wl_event_queue_init(&display->display_queue, display, "Display Queue");
pthread_mutex_init(&display->mutex, NULL);
@ -2235,6 +2285,15 @@ wl_display_dispatch_queue_pending(struct wl_display *display,
ret = dispatch_queue(display, queue);
if (debug_client) {
struct timespec tp;
clock_gettime(CLOCK_MONOTONIC, &tp);
queue->last_dispatch = timespec_to_msec(&tp);
queue->logged_stale_dispatch_warning = false;
wl_display_debug_dispatch(display);
}
pthread_mutex_unlock(&display->mutex);
return ret;