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; }
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; }
int WaylandNativeWindow::readQueue(bool block) { int ret = 0; if (++m_queueReads == 1) { if (block) { ret = wl_display_dispatch_queue(m_display, wl_queue); } else { ret = wl_display_dispatch_queue_pending(m_display, wl_queue); } // all threads waiting on the false branch will wake and return now, so we // can safely set m_queueReads to 0 here instead of relying on every thread // to decrement it. This prevents a race condition when a thread enters readQueue() // before the one in this thread returns. // The new thread would go in the false branch, and there would be no thread in the // true branch, blocking the new thread and any other that will call readQueue in // the future. m_queueReads = 0; pthread_cond_broadcast(&cond); if (ret < 0) { TRACE("wl_display_dispatch_queue returned an error"); check_fatal_error(m_display); return ret; } } else if (block) { while (m_queueReads > 0) { pthread_cond_wait(&cond, &mutex); } } return ret; }
void QWaylandDisplay::flushRequests() { int ret = wl_display_dispatch_queue_pending(mDisplay, mEventQueue); if (ret < 0) { qWarning("The wayland connection broke (error %d). Did the wayland compositor die?", errno); exit(1); } wl_display_flush(mDisplay); }
int wayland_roundtrip(struct wl_egl_display *display) { struct wl_callback *callback; int done = 0, ret = 0; wl_display_dispatch_queue_pending(display->display, display->queue); callback = wl_display_sync(display->display); wl_callback_add_listener(callback, &roundtrip_listener, &done); wl_proxy_set_queue((struct wl_proxy *)callback, display->queue); while (ret == 0 && !done) ret = wl_display_dispatch_queue(display->display, display->queue); return ret; }
int WaylandNativeWindow::wayland_roundtrip(WaylandNativeWindow *display) { struct wl_callback *callback; int done = 0, ret = 0; wl_display_dispatch_queue_pending(display->m_display, display->wl_queue); callback = wl_display_sync(display->m_display); wl_callback_add_listener(callback, &sync_listener, &done); wl_proxy_set_queue((struct wl_proxy *) callback, display->wl_queue); while (ret == 0 && !done) ret = wl_display_dispatch_queue(display->m_display, display->wl_queue); return ret; }
/** Dispatch main queue events without reading from the display fd * * \param display The display context object * \return The number of dispatched events or -1 on failure * * This function dispatches events on the main event queue. It does not * attempt to read the display fd and simply returns zero if the main * queue is empty, i.e., it doesn't block. * * This is necessary when a client's main loop wakes up on some fd other * than the display fd (network socket, timer fd, etc) and calls \ref * wl_display_dispatch_queue() from that callback. This may queue up * events in the main queue while reading all data from the display fd. * When the main thread returns to the main loop to block, the display fd * no longer has data, causing a call to \em poll(2) (or similar * functions) to block indefinitely, even though there are events ready * to dispatch. * * To proper integrate the wayland display fd into a main loop, the * client should always call \ref wl_display_dispatch_pending() and then * \ref wl_display_flush() prior to going back to sleep. At that point, * the fd typically doesn't have data so attempting I/O could block, but * events queued up on the main queue should be dispatched. * * A real-world example is a main loop that wakes up on a timerfd (or a * sound card fd becoming writable, for example in a video player), which * then triggers GL rendering and eventually eglSwapBuffers(). * eglSwapBuffers() may call wl_display_dispatch_queue() if it didn't * receive the frame event for the previous frame, and as such queue * events in the main queue. * * \note Calling this makes the current thread the main one. * * \sa wl_display_dispatch(), wl_display_dispatch_queue(), * wl_display_flush() * * \memberof wl_display */ WL_EXPORT int wl_display_dispatch_pending(struct wl_display *display) { return wl_display_dispatch_queue_pending(display, &display->queue); }
int DispatchQueuePending(struct wl_event_queue *queue){ return wl_display_dispatch_queue_pending(cobj, queue); }