static gpointer gst_wl_display_thread_run (gpointer data) { GstWlDisplay *self = data; GstPollFD pollfd = GST_POLL_FD_INIT; pollfd.fd = wl_display_get_fd (self->display); gst_poll_add_fd (self->wl_fd_poll, &pollfd); gst_poll_fd_ctl_read (self->wl_fd_poll, &pollfd, TRUE); /* main loop */ while (1) { while (wl_display_prepare_read_queue (self->display, self->queue) != 0) wl_display_dispatch_queue_pending (self->display, self->queue); wl_display_flush (self->display); if (gst_poll_wait (self->wl_fd_poll, GST_CLOCK_TIME_NONE) < 0) { gboolean normal = (errno == EBUSY); wl_display_cancel_read (self->display); if (normal) break; else goto error; } else { wl_display_read_events (self->display); wl_display_dispatch_queue_pending (self->display, self->queue); } } return NULL; error: GST_ERROR ("Error communicating with the wayland server"); return NULL; }
/** Dispatch events in an event queue * * \param display The display context object * \param queue The event queue to dispatch * \return The number of dispatched events on success or -1 on failure * * Dispatch all incoming events for objects assigned to the given * event queue. On failure -1 is returned and errno set appropriately. * * This function blocks if there are no events to dispatch. If calling from * the main thread, it will block reading data from the display fd. For other * threads this will block until the main thread queues events on the queue * passed as argument. * * \memberof wl_display */ WL_EXPORT int wl_display_dispatch_queue(struct wl_display *display, struct wl_event_queue *queue) { struct pollfd pfd[2]; int ret; pthread_mutex_lock(&display->mutex); ret = dispatch_queue(display, queue); if (ret == -1) goto err_unlock; if (ret > 0) { pthread_mutex_unlock(&display->mutex); return ret; } /* We ignore EPIPE here, so that we try to read events before * returning an error. When the compositor sends an error it * will close the socket, and if we bail out here we don't get * a chance to process the error. */ ret = wl_connection_flush(display->connection); if (ret < 0 && errno != EAGAIN && errno != EPIPE) { display_fatal_error(display, errno); goto err_unlock; } display->reader_count++; pthread_mutex_unlock(&display->mutex); pfd[0].fd = display->fd; pfd[0].events = POLLIN; do { ret = poll(pfd, 1, -1); } while (ret == -1 && errno == EINTR); if (ret == -1) { wl_display_cancel_read(display); return -1; } pthread_mutex_lock(&display->mutex); if (read_events(display) == -1) goto err_unlock; ret = dispatch_queue(display, queue); if (ret == -1) goto err_unlock; pthread_mutex_unlock(&display->mutex); return ret; err_unlock: pthread_mutex_unlock(&display->mutex); return -1; }
/** Dispatch events in an event queue * * \param display The display context object * \param queue The event queue to dispatch * \return The number of dispatched events on success or -1 on failure * * Dispatch all incoming events for objects assigned to the given * event queue. On failure -1 is returned and errno set appropriately. * * This function blocks if there are no events to dispatch. If calling from * the main thread, it will block reading data from the display fd. For other * threads this will block until the main thread queues events on the queue * passed as argument. * * \memberof wl_display */ WL_EXPORT int wl_display_dispatch_queue(struct wl_display *display, struct wl_event_queue *queue) { struct pollfd pfd[2]; int ret; pthread_mutex_lock(&display->mutex); ret = dispatch_queue(display, queue); if (ret == -1) goto err_unlock; if (ret > 0) { pthread_mutex_unlock(&display->mutex); return ret; } ret = wl_connection_flush(display->connection); if (ret < 0 && errno != EAGAIN) { display_fatal_error(display, errno); goto err_unlock; } display->reader_count++; pthread_mutex_unlock(&display->mutex); pfd[0].fd = display->fd; pfd[0].events = POLLIN; do { ret = poll(pfd, 1, -1); } while (ret == -1 && errno == EINTR); if (ret == -1) { wl_display_cancel_read(display); return -1; } pthread_mutex_lock(&display->mutex); if (read_events(display) == -1) goto err_unlock; ret = dispatch_queue(display, queue); if (ret == -1) goto err_unlock; pthread_mutex_unlock(&display->mutex); return ret; err_unlock: pthread_mutex_unlock(&display->mutex); return -1; }
static gboolean gst_vaapi_window_wayland_sync (GstVaapiWindow * window) { GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); struct wl_display *const wl_display = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); if (priv->sync_failed) return FALSE; if (priv->pollfd.fd < 0) { priv->pollfd.fd = wl_display_get_fd (wl_display); gst_poll_add_fd (priv->poll, &priv->pollfd); gst_poll_fd_ctl_read (priv->poll, &priv->pollfd, TRUE); } while (g_atomic_int_get (&priv->num_frames_pending) > 0) { while (wl_display_prepare_read_queue (wl_display, priv->event_queue) < 0) { if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0) goto error; } if (wl_display_flush (wl_display) < 0) goto error; again: if (gst_poll_wait (priv->poll, GST_CLOCK_TIME_NONE) < 0) { int saved_errno = errno; if (saved_errno == EAGAIN || saved_errno == EINTR) goto again; if (saved_errno == EBUSY) { /* closing */ wl_display_cancel_read (wl_display); return FALSE; } goto error; } if (wl_display_read_events (wl_display) < 0) goto error; if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0) goto error; } return TRUE; /* ERRORS */ error: { priv->sync_failed = TRUE; GST_ERROR ("Error on dispatching events: %s", g_strerror (errno)); return FALSE; } }
static gpointer gst_mfx_window_wayland_thread_run (gpointer window) { GstMfxWindowWaylandPrivate *const priv = GST_MFX_WINDOW_WAYLAND_GET_PRIVATE (window); struct wl_display *const wl_display = GST_MFX_DISPLAY_HANDLE (GST_MFX_WINDOW_DISPLAY (window)); if (priv->sync_failed) return NULL; if (priv->pollfd.fd < 0) { priv->pollfd.fd = wl_display_get_fd (wl_display); gst_poll_add_fd (priv->poll, &priv->pollfd); gst_poll_fd_ctl_read (priv->poll, &priv->pollfd, TRUE); } while (1) { while (wl_display_prepare_read_queue (wl_display, priv->event_queue) < 0) { if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0) goto error; } if (wl_display_flush (wl_display) < 0) goto error; again: if (gst_poll_wait (priv->poll, GST_CLOCK_TIME_NONE) < 0) { int saved_errno = errno; if (saved_errno == EAGAIN || saved_errno == EINTR) goto again; wl_display_cancel_read (wl_display); if (saved_errno == EBUSY) /* flushing */ return NULL; else goto error; } if (wl_display_read_events (wl_display) < 0) goto error; if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0) goto error; } return NULL; error: priv->sync_failed = TRUE; GST_ERROR ("Error on dispatching events: %s", g_strerror (errno)); return NULL; }
static void handleEvents(int timeout) { struct wl_display* display = _glfw.wl.display; struct pollfd fds[] = { { wl_display_get_fd(display), POLLIN }, }; while (wl_display_prepare_read(display) != 0) wl_display_dispatch_pending(display); // If an error different from EAGAIN happens, we have likely been // disconnected from the Wayland session, try to handle that the best we // can. if (wl_display_flush(display) < 0 && errno != EAGAIN) { _GLFWwindow* window = _glfw.windowListHead; while (window) { _glfwInputWindowCloseRequest(window); window = window->next; } wl_display_cancel_read(display); return; } if (poll(fds, 1, timeout) > 0) { wl_display_read_events(display); wl_display_dispatch_pending(display); } else { wl_display_cancel_read(display); } }
void _glfwPlatformWaitEvents(void) { struct wl_display* display = _glfw.wl.display; struct pollfd fds[] = { { wl_display_get_fd(display), POLLIN }, }; while (wl_display_prepare_read(display) != 0) wl_display_dispatch_pending(display); wl_display_flush(display); if (poll(fds, 1, -1) > 0) { wl_display_read_events(display); wl_display_dispatch_pending(display); } else { wl_display_cancel_read(display); } }
void WaylandCore::pollEvents() { if( mDisplay == NULL || mRegistry == NULL ) { mShouldClose = true; return; } pollfd fds[] = { { wl_display_get_fd(mDisplay), POLLIN }, }; while( wl_display_prepare_read(mDisplay) != 0 ) { wl_display_dispatch_pending(mDisplay); } wl_display_flush(mDisplay); if( poll(fds,1,0) > 0 ) { wl_display_read_events(mDisplay); wl_display_dispatch_pending(mDisplay); } else { wl_display_cancel_read(mDisplay); } }
static void cleanup_wl_display_read(void *data) { struct wl_display *display = data; wl_display_cancel_read(display); }
void CancelRead(){ wl_display_cancel_read(cobj); }