if (disp_source->prepared)
return FALSE;
+ /* If there is a last_error, there is no need to poll,
+ * so skip directly to dispatch.
+ * prepare -> dispatch */
+ if (disp_source->last_error)
+ return TRUE;
+
while (wl_display_prepare_read_queue(disp_source->disp,
disp_source->ev_queue) != 0) {
if (wl_display_dispatch_queue_pending(disp_source->disp,
if (!disp_source->prepared)
return ret;
+ /* If prepared, but last_error is set,
+ * cancel_read is executed and FALSE is returned.
+ * That can lead to G_SOURCE_REMOVE by calling disp_prepare again
+ * and skipping disp_check from prepare to disp_dispatch.
+ * check -> prepare -> dispatch -> G_SOURCE_REMOVE */
+ if (disp_source->prepared && disp_source->last_error) {
+ wl_display_cancel_read(disp_source->disp);
+ return ret;
+ }
+
if (disp_source->gfd.revents & G_IO_IN) {
if (wl_display_read_events(disp_source->disp) == -1)
_twe_display_print_err(disp_source, "read_event.");
{
twe_wl_disp_source *disp_source = (twe_wl_disp_source *)source;
+ /* If there is last_error, G_SOURCE_REMOVE should be returned
+ * to remove the gsource from the main loop.
+ * This is because disp_source is not valid since last_error was set.*/
+ if (disp_source->last_error) {
+ return G_SOURCE_REMOVE;
+ }
+
g_mutex_lock(&disp_source->wl_event_mutex);
if (disp_source->gfd.revents & G_IO_IN) {
if (wl_display_dispatch_queue_pending(disp_source->disp,