pkgsrc-WIP-changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

wayland: switch from using epoll-shim to kqueue natively



Module Name:	pkgsrc-wip
Committed By:	nia <nia%netbsd.org@localhost>
Pushed By:	nee
Date:		Sun Aug 18 16:53:12 2019 +0100
Changeset:	b1d7bd2104b6c241e5410994a89c4acb608d7c78

Modified Files:
	wayland/DESCR
	wayland/Makefile
	wayland/buildlink3.mk
	wayland/distinfo
	wayland/patches/patch-Makefile.am
	wayland/patches/patch-configure.ac
	wayland/patches/patch-src_event-loop.c
	wayland/patches/patch-src_wayland-os.c
	wayland/patches/patch-src_wayland-os.h
	wayland/patches/patch-src_wayland-shm.c
	wayland/patches/patch-tests_os-wrappers-test.c
	wayland/patches/patch-tests_sanity-test.c
	wayland/patches/patch-tests_test-helpers.c
	wayland/patches/patch-tests_test-runner.c
Added Files:
	wayland/files/event-loop-kqueue.c

Log Message:
wayland: switch from using epoll-shim to kqueue natively

based on a few patches on the wayland mailing list.

To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=b1d7bd2104b6c241e5410994a89c4acb608d7c78

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

diffstat:
 wayland/DESCR                                  |  19 +-
 wayland/Makefile                               |  20 +-
 wayland/buildlink3.mk                          |   4 -
 wayland/distinfo                               |  20 +-
 wayland/files/event-loop-kqueue.c              | 800 +++++++++++++++++++++++++
 wayland/patches/patch-Makefile.am              |  28 +-
 wayland/patches/patch-configure.ac             |  41 +-
 wayland/patches/patch-src_event-loop.c         |  21 +-
 wayland/patches/patch-src_wayland-os.c         |  33 +-
 wayland/patches/patch-src_wayland-os.h         |  21 +-
 wayland/patches/patch-src_wayland-shm.c        |   6 +-
 wayland/patches/patch-tests_os-wrappers-test.c | 114 +++-
 wayland/patches/patch-tests_sanity-test.c      |   2 +
 wayland/patches/patch-tests_test-helpers.c     |   6 +-
 wayland/patches/patch-tests_test-runner.c      |   2 +
 15 files changed, 1039 insertions(+), 98 deletions(-)

diffs:
diff --git a/wayland/DESCR b/wayland/DESCR
index 4cb85b2233..b11876feeb 100644
--- a/wayland/DESCR
+++ b/wayland/DESCR
@@ -1,16 +1,5 @@
-Wayland is a project to define a protocol for a compositor to talk to
-its clients as well as a library implementation of the protocol.  The
-compositor can be a standalone display server running on Linux kernel
-modesetting and evdev input devices, an X application, or a wayland
-client itself.  The clients can be traditional applications, X servers
-(rootless or fullscreen) or other display servers.
+Wayland is intended to be simpler replacement for the X window
+system, easier to develop and maintain.
 
-The wayland protocol is essentially only about input handling and
-buffer management.  The compositor receives input events and forwards
-them to the relevant client.  The clients creates buffers and renders
-into them and notifies the compositor when it needs to redraw.  The
-protocol also handles drag and drop, selections, window management and
-other interactions that must go through the compositor.  However, the
-protocol does not handle rendering, which is one of the features that
-makes wayland so simple.  All clients are expected to handle rendering
-themselves, typically through cairo or OpenGL.
+Wayland is a protocol for a compositor to talk to its clients as
+well as a C library implementation of that protocol.
diff --git a/wayland/Makefile b/wayland/Makefile
index 5700ff95bb..023e62f3c7 100644
--- a/wayland/Makefile
+++ b/wayland/Makefile
@@ -1,14 +1,13 @@
 # $NetBSD$
-#
 
 DISTNAME=	wayland-1.17.0
-CATEGORIES=	graphics
-MASTER_SITES=	http://wayland.freedesktop.org/releases/
+CATEGORIES=	devel
+MASTER_SITES=	https://wayland.freedesktop.org/releases/
 EXTRACT_SUFX=	.tar.xz
 
 MAINTAINER=	pkgsrc-users%NetBSD.org@localhost
-HOMEPAGE=	http://wayland.freedesktop.org
-COMMENT=	Computer display server protocol
+HOMEPAGE=	https://wayland.freedesktop.org/
+COMMENT=	Display server protocol - development libraries
 LICENSE=	mit
 
 USE_TOOLS+=		autoconf automake autoreconf gmake pkg-config
@@ -22,18 +21,11 @@ PKGCONFIG_OVERRIDE+=	src/wayland-cursor.pc.in
 PKGCONFIG_OVERRIDE+=	src/wayland-scanner.pc.in
 PKGCONFIG_OVERRIDE+=	src/wayland-server.pc.in
 
-
 pre-configure:
+	# https://lists.freedesktop.org/archives/wayland-devel/2019-February/040024.html
+	${CP} ${FILESDIR}/event-loop-kqueue.c ${WRKSRC}/src
 	cd ${WRKSRC} && autoreconf -fvi
 
-.include "../../mk/bsd.prefs.mk"
-
-.if ${OPSYS} != "Linux"
-CFLAGS+=	-I${BUILDLINK_PREFIX.libepoll-shim}/include/libepoll-shim
-.include "../../wip/libepoll-shim/buildlink3.mk"
-.else
-BUILDLINK_TRANSFORM+=    rm:-lepoll-shim
-.endif
 .include "../../devel/libffi/buildlink3.mk"
 .include "../../textproc/expat/buildlink3.mk"
 .include "../../textproc/libxslt/buildlink3.mk"
diff --git a/wayland/buildlink3.mk b/wayland/buildlink3.mk
index 411fffd704..80b1819763 100644
--- a/wayland/buildlink3.mk
+++ b/wayland/buildlink3.mk
@@ -8,10 +8,6 @@ WAYLAND_BUILDLINK3_MK:=
 BUILDLINK_API_DEPENDS.wayland+=	wayland>=1.9.90
 BUILDLINK_PKGSRCDIR.wayland?=	../../wip/wayland
 
-.include "../../mk/bsd.prefs.mk"
-.if ${OPSYS} != "Linux"
-.  include "../../wip/libepoll-shim/buildlink3.mk"
-.endif
 .include "../../devel/libffi/buildlink3.mk"
 .endif	# WAYLAND_BUILDLINK3_MK
 
diff --git a/wayland/distinfo b/wayland/distinfo
index f903e41abe..babeca2be6 100644
--- a/wayland/distinfo
+++ b/wayland/distinfo
@@ -4,18 +4,18 @@ SHA1 (wayland-1.17.0.tar.xz) = 4d9e08a7a4a07fa37a25d7aa3ef83f08edec0600
 RMD160 (wayland-1.17.0.tar.xz) = 635494fb0f5d9eb1e782f98e08c3e0e26ff44268
 SHA512 (wayland-1.17.0.tar.xz) = c5051aab5ff078b368c196ecfedb33ccd961265bb914845d7ed81de361bb86ae18299575baa6c4eceb0d82cf8b495e8293f31b51d1cbc05d84af0a199ab3f946
 Size (wayland-1.17.0.tar.xz) = 437680 bytes
-SHA1 (patch-Makefile.am) = f48d5acd6d1dd4f17a22ebe951ec621790efcff1
-SHA1 (patch-configure.ac) = 0d1b289b9b4ecfecf8c3aa1314b2fbd66b86d38a
-SHA1 (patch-src_event-loop.c) = 99bd6717302044430732cff21ede40e0849f026e
-SHA1 (patch-src_wayland-os.c) = 8d88cc2712b9ce8a4df8b05b6a2182d964c77ef1
-SHA1 (patch-src_wayland-os.h) = 0a8d2c7c4cbc68bedf78a924b9919158de540721
+SHA1 (patch-Makefile.am) = af2c47eb2e1a4924ea842aeea1d0f00832762ec0
+SHA1 (patch-configure.ac) = df15013a1639d673e5f0a86433a074f6201dbbc4
+SHA1 (patch-src_event-loop.c) = 04d0eed4ba0708518201ec630dab97d52735fb0c
+SHA1 (patch-src_wayland-os.c) = fc1a70d4baf8311afce92a081368104b7a732e27
+SHA1 (patch-src_wayland-os.h) = 2e8fb20d4adfb3666adffe48104205488b4a1c7b
 SHA1 (patch-src_wayland-server.c) = 335de8f5390eb337dfbde26f523162bd44c06baf
-SHA1 (patch-src_wayland-shm.c) = 1eb094125b13f4c5fcaaa058d86d246d867dcdba
+SHA1 (patch-src_wayland-shm.c) = a59ddce3a161bb21fedb04737ff502da608b1da9
 SHA1 (patch-tests_client-test.c) = 6ffe18dfd64176a92f6f795eb757c54a3cf0ad10
 SHA1 (patch-tests_connection-test.c) = af53116c99cbb8d6570bcec66bfd895c1ae01700
 SHA1 (patch-tests_event-loop-test.c) = 79909fdce7b73a7b19c58d3711329f6288fe7204
-SHA1 (patch-tests_os-wrappers-test.c) = df3605d6dfd2f8da3b62ea73b0255f6ce6b4a66a
+SHA1 (patch-tests_os-wrappers-test.c) = 0b45e6952d23589e4991149143331fdb9e0386e1
 SHA1 (patch-tests_queue-test.c) = 3ee8433faa50b033ab880d3c5b6a9846063d6bd6
-SHA1 (patch-tests_sanity-test.c) = c06e78ec19326a14386972a4dc56584f712c836e
-SHA1 (patch-tests_test-helpers.c) = d0e80087f03897761bb000a4a83a7f5979518a24
-SHA1 (patch-tests_test-runner.c) = 5e2c993a07403ebd46a27c5939ae5cc141b4027c
+SHA1 (patch-tests_sanity-test.c) = 80e06834ccf344fda16a6a8f85e062f2b4a744ec
+SHA1 (patch-tests_test-helpers.c) = 59f75ac60e9bcbe7877f96628f2a6c6f31955334
+SHA1 (patch-tests_test-runner.c) = 35d911064c1b65537ef2276797b8041fd6b023f7
diff --git a/wayland/files/event-loop-kqueue.c b/wayland/files/event-loop-kqueue.c
new file mode 100644
index 0000000000..7d07d194bd
--- /dev/null
+++ b/wayland/files/event-loop-kqueue.c
@@ -0,0 +1,800 @@
+/*
+ * Copyright © 2008 Kristian Høgsberg
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "config.h"
+
+#ifdef HAVE_SYS_EVENT_H
+#include <stddef.h>
+#include <stdio.h>
+#include <err.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include "wayland-util.h"
+#include "wayland-private.h"
+#include "wayland-server-core.h"
+#include "wayland-os.h"
+
+/** \cond INTERNAL */
+
+struct wl_event_loop {
+	int event_fd;
+	struct wl_list check_list;
+	struct wl_list idle_list;
+	struct wl_list destroy_list;
+
+	struct wl_signal destroy_signal;
+};
+
+struct wl_event_source_interface {
+	int (*dispatch)(struct wl_event_source *source,
+			struct kevent *ev);
+};
+
+struct wl_event_source {
+	struct wl_event_source_interface *interface;
+	struct wl_event_loop *loop;
+	struct wl_list link;
+	void *data;
+	int fd;
+};
+
+struct wl_event_source_fd {
+	struct wl_event_source base;
+	wl_event_loop_fd_func_t func;
+	int fd;
+};
+
+/** \endcond */
+
+static int
+wl_event_source_fd_dispatch(struct wl_event_source *source,
+			    struct kevent *ev)
+{
+	struct wl_event_source_fd *fd_source = (struct wl_event_source_fd *) source;
+	uint32_t mask;
+
+	mask = 0;
+	if (ev->filter == EVFILT_READ)
+		mask |= WL_EVENT_READABLE;
+	if (ev->filter == EVFILT_WRITE)
+		mask |= WL_EVENT_WRITABLE;
+	if (ev->flags & EV_EOF)
+		mask |= WL_EVENT_HANGUP;
+	if (ev->flags & EV_ERROR)
+		mask |= WL_EVENT_ERROR;
+
+	return fd_source->func(source->fd, mask, source->data);
+}
+
+struct wl_event_source_interface fd_source_interface = {
+	wl_event_source_fd_dispatch,
+};
+
+static struct wl_event_source *
+add_source(struct wl_event_loop *loop,
+	   struct wl_event_source *source, uint32_t mask, void *data)
+{
+	source->loop = loop;
+	source->data = data;
+	wl_list_init(&source->link);
+
+	return source;
+}
+
+/** Create a file descriptor event source
+ *
+ * \param loop The event loop that will process the new source.
+ * \param fd The file descriptor to watch.
+ * \param mask A bitwise-or of which events to watch for: \c WL_EVENT_READABLE,
+ * \c WL_EVENT_WRITABLE.
+ * \param func The file descriptor dispatch function.
+ * \param data User data.
+ * \return A new file descriptor event source.
+ *
+ * The given file descriptor is initially watched for the events given in
+ * \c mask. This can be changed as needed with wl_event_source_fd_update().
+ *
+ * If it is possible that program execution causes the file descriptor to be
+ * read while leaving the data in a buffer without actually processing it,
+ * it may be necessary to register the file descriptor source to be re-checked,
+ * see wl_event_source_check(). This will ensure that the dispatch function
+ * gets called even if the file descriptor is not readable or writable
+ * anymore. This is especially useful with IPC libraries that automatically
+ * buffer incoming data, possibly as a side-effect of other operations.
+ *
+ * \sa wl_event_loop_fd_func_t
+ * \memberof wl_event_source
+ */
+WL_EXPORT struct wl_event_source *
+wl_event_loop_add_fd(struct wl_event_loop *loop,
+		     int fd, uint32_t mask,
+		     wl_event_loop_fd_func_t func,
+		     void *data)
+{
+	struct wl_event_source_fd *source;
+
+	struct kevent events[2];
+	unsigned int num_events = 0;
+
+	source = malloc(sizeof *source);
+	if (source == NULL)
+		return NULL;
+
+	source->base.interface = &fd_source_interface;
+	source->base.fd = wl_os_dupfd_cloexec(fd, 0);
+	source->func = func;
+	source->fd = fd;
+	add_source(loop, &source->base, mask, data);
+
+	if (source->base.fd < 0) {
+		fprintf(stderr, "could not add source\n: %m");
+		free(source);
+		return NULL;
+	}
+
+	if (mask & WL_EVENT_READABLE) {
+		EV_SET(&events[num_events], source->base.fd, EVFILT_READ,
+		      EV_ADD | EV_ENABLE, 0, 0, &source->base);
+		num_events++;
+	}
+
+	if (mask & WL_EVENT_WRITABLE) {
+		EV_SET(&events[num_events], source->base.fd, EVFILT_WRITE,
+		      EV_ADD | EV_ENABLE, 0, 0, &source->base);
+		num_events++;
+	}
+
+	if (kevent(loop->event_fd, events, num_events, NULL, 0, NULL) < 0) {
+		fprintf(stderr, "error adding source %i (%p) to loop %p: %s\n",
+		       source->fd, source, loop, strerror(errno));
+		close(source->base.fd);
+		free(source);
+		return NULL;
+	}
+
+	return &source->base;
+}
+
+/** Update a file descriptor source's event mask
+ *
+ * \param source The file descriptor event source to update.
+ * \param mask The new mask, a bitwise-or of: \c WL_EVENT_READABLE,
+ * \c WL_EVENT_WRITABLE.
+ * \return 0 on success, -1 on failure.
+ *
+ * This changes which events, readable and/or writable, cause the dispatch
+ * callback to be called on.
+ *
+ * File descriptors are usually writable to begin with, so they do not need to
+ * be polled for writable until a write actually fails. When a write fails,
+ * the event mask can be changed to poll for readable and writable, delivering
+ * a dispatch callback when it is possible to write more. Once all data has
+ * been written, the mask can be changed to poll only for readable to avoid
+ * busy-looping on dispatch.
+ *
+ * \sa wl_event_loop_add_fd()
+ * \memberof wl_event_source
+ */
+WL_EXPORT int
+wl_event_source_fd_update(struct wl_event_source *source, uint32_t mask)
+{
+	struct wl_event_loop *loop = source->loop;
+	struct kevent events[2];
+	unsigned int num_events = 0;
+
+	if (mask & WL_EVENT_READABLE) {
+		EV_SET(&events[num_events], source->fd, EVFILT_READ,
+		       EV_ADD | EV_ENABLE, 0, 0, source);
+		num_events++;
+	}
+
+	if (mask & WL_EVENT_WRITABLE) {
+		EV_SET(&events[num_events], source->fd, EVFILT_WRITE,
+		       EV_ADD | EV_ENABLE, 0, 0, source);
+		num_events++;
+	}
+
+	return kevent(loop->event_fd, events, num_events, NULL, 0, NULL);
+}
+
+/** \cond INTERNAL */
+
+struct wl_event_source_timer {
+	struct wl_event_source base;
+	wl_event_loop_timer_func_t func;
+};
+
+/** \endcond */
+
+static int
+wl_event_source_timer_dispatch(struct wl_event_source *source,
+			       struct kevent *ev)
+{
+	struct wl_event_source_timer *timer_source =
+		(struct wl_event_source_timer *) source;
+	uint64_t expires;
+
+	expires = ev->data;    /* XXX unused?! */
+	return timer_source->func(timer_source->base.data);
+}
+
+struct wl_event_source_interface timer_source_interface = {
+	wl_event_source_timer_dispatch,
+};
+
+/** Create a timer event source
+ *
+ * \param loop The event loop that will process the new source.
+ * \param func The timer dispatch function.
+ * \param data User data.
+ * \return A new timer event source.
+ *
+ * The timer is initially disarmed. It needs to be armed with a call to
+ * wl_event_source_timer_update() before it can trigger a dispatch call.
+ *
+ * \sa wl_event_loop_timer_func_t
+ * \memberof wl_event_source
+ */
+WL_EXPORT struct wl_event_source *
+wl_event_loop_add_timer(struct wl_event_loop *loop,
+			wl_event_loop_timer_func_t func,
+			void *data)
+{
+	static int next_timer_id = 0;
+	struct wl_event_source_timer *source;
+
+	source = malloc(sizeof *source);
+	if (source == NULL)
+		return NULL;
+	source->base.interface = &timer_source_interface;
+	source->base.fd = next_timer_id++;
+	source->base.loop = loop;
+	source->base.data = data;
+	source->func = func;
+	wl_list_init(&source->base.link);
+
+	return &source->base;
+}
+
+/** Arm or disarm a timer
+ *
+ * \param source The timer event source to modify.
+ * \param ms_delay The timeout in milliseconds.
+ * \return 0 on success, -1 on failure.
+ *
+ * If the timeout is zero, the timer is disarmed.
+ *
+ * If the timeout is non-zero, the timer is set to expire after the given
+ * timeout in milliseconds. When the timer expires, the dispatch function
+ * set with wl_event_loop_add_timer() is called once from
+ * wl_event_loop_dispatch(). If another dispatch is desired after another
+ * expiry, wl_event_source_timer_update() needs to be called again.
+ *
+ * \memberof wl_event_source
+ */
+WL_EXPORT int
+wl_event_source_timer_update(struct wl_event_source *source, int ms_delay)
+{
+	struct kevent ev;
+
+	if (ms_delay == 0) {
+		EV_SET(&ev, source->fd, EVFILT_TIMER, EV_DISABLE, 0,
+		       ms_delay, source);
+	} else {
+		EV_SET(&ev, source->fd, EVFILT_TIMER,
+		       EV_ADD | EV_ENABLE | EV_DISPATCH, 0, ms_delay, source);
+	}
+
+	if (kevent(source->loop->event_fd, &ev, 1, NULL, 0, NULL) < 0) {
+		fprintf(stderr, "could not set kqueue timer: %s",
+		        strerror(errno));
+		return -1;
+	}
+
+	return 0;
+}
+
+/** \cond INTERNAL */
+
+struct wl_event_source_signal {
+	struct wl_event_source base;
+	int signal_number;
+	wl_event_loop_signal_func_t func;
+};
+
+/** \endcond */
+
+static int
+wl_event_source_signal_dispatch(struct wl_event_source *source,
+				struct kevent *ev)
+{
+	struct wl_event_source_signal *signal_source;
+
+	signal_source = (struct wl_event_source_signal *) source;
+
+	return signal_source->func(signal_source->base.fd,
+	                           signal_source->base.data);
+}
+
+struct wl_event_source_interface signal_source_interface = {
+	wl_event_source_signal_dispatch,
+};
+
+/** Create a POSIX signal event source
+ *
+ * \param loop The event loop that will process the new source.
+ * \param signal_number Number of the signal to watch for.
+ * \param func The signal dispatch function.
+ * \param data User data.
+ * \return A new signal event source.
+ *
+ * This function blocks the normal delivery of the given signal in the calling
+ * thread, and creates a "watch" for it. Signal delivery no longer happens
+ * asynchronously, but by wl_event_loop_dispatch() calling the dispatch
+ * callback function \c func.
+ *
+ * It is the caller's responsibility to ensure that all other threads have
+ * also blocked the signal.
+ *
+ * \sa wl_event_loop_signal_func_t
+ * \memberof wl_event_source
+ */
+WL_EXPORT struct wl_event_source *
+wl_event_loop_add_signal(struct wl_event_loop *loop,
+			int signal_number,
+			wl_event_loop_signal_func_t func,
+			void *data)
+{
+	struct wl_event_source_signal *source;
+	sigset_t mask;
+	struct kevent ev;
+
+	source = malloc(sizeof *source);
+	if (source == NULL)
+		return NULL;
+
+	source->base.interface = &signal_source_interface;
+	source->signal_number = signal_number;
+	source->func = func;
+
+	sigemptyset(&mask);
+	sigaddset(&mask, signal_number);
+	sigprocmask(SIG_BLOCK, &mask, NULL);
+
+	source->base.fd = 0;
+	add_source(loop, &source->base, WL_EVENT_READABLE, data);
+
+	EV_SET(&ev, signal_number, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0,
+	       source);
+
+	if (kevent(loop->event_fd, &ev, 1, NULL, 0, NULL) < 0) {
+		fprintf(stderr, "error adding signal for %i (%p), %p: %s\n",
+			signal_number, source, loop, strerror(errno));
+		free(source);
+		return NULL;
+	}
+
+	return &source->base;
+}
+
+/** \cond INTERNAL */
+
+struct wl_event_source_idle {
+	struct wl_event_source base;
+	wl_event_loop_idle_func_t func;
+};
+
+/** \endcond */
+
+struct wl_event_source_interface idle_source_interface = {
+	NULL,
+};
+
+/** Create an idle task
+ *
+ * \param loop The event loop that will process the new task.
+ * \param func The idle task dispatch function.
+ * \param data User data.
+ * \return A new idle task (an event source).
+ *
+ * Idle tasks are dispatched before wl_event_loop_dispatch() goes to sleep.
+ * See wl_event_loop_dispatch() for more details.
+ *
+ * Idle tasks fire once, and are automatically destroyed right after the
+ * callback function has been called.
+ *
+ * An idle task can be cancelled before the callback has been called by
+ * wl_event_source_remove(). Calling wl_event_source_remove() after or from
+ * within the callback results in undefined behaviour.
+ *
+ * \sa wl_event_loop_idle_func_t
+ * \memberof wl_event_source
+ */
+WL_EXPORT struct wl_event_source *
+wl_event_loop_add_idle(struct wl_event_loop *loop,
+		       wl_event_loop_idle_func_t func,
+		       void *data)
+{
+	struct wl_event_source_idle *source;
+
+	source = malloc(sizeof *source);
+	if (source == NULL)
+		return NULL;
+
+	source->base.interface = &idle_source_interface;
+	source->base.loop = loop;
+	source->base.fd = -1;
+
+	source->func = func;
+	source->base.data = data;
+
+	wl_list_insert(loop->idle_list.prev, &source->base.link);
+
+	return &source->base;
+}
+
+/** Mark event source to be re-checked
+ *
+ * \param source The event source to be re-checked.
+ *
+ * This function permanently marks the event source to be re-checked after
+ * the normal dispatch of sources in wl_event_loop_dispatch(). Re-checking
+ * will keep iterating over all such event sources until the dispatch
+ * function for them all returns zero.
+ *
+ * Re-checking is used on sources that may become ready to dispatch as a
+ * side-effect of dispatching themselves or other event sources, including idle
+ * sources. Re-checking ensures all the incoming events have been fully drained
+ * before wl_event_loop_dispatch() returns.
+ *
+ * \memberof wl_event_source
+ */
+WL_EXPORT void
+wl_event_source_check(struct wl_event_source *source)
+{
+	wl_list_insert(source->loop->check_list.prev, &source->link);
+}
+
+/** Remove an event source from its event loop
+ *
+ * \param source The event source to be removed.
+ * \return Zero.
+ *
+ * The event source is removed from the event loop it was created for,
+ * and is effectively destroyed. This invalidates \c source .
+ * The dispatch function of the source will no longer be called through this
+ * source.
+ *
+ * \memberof wl_event_source
+ */
+WL_EXPORT int
+wl_event_source_remove(struct wl_event_source *source)
+{
+	struct wl_event_loop *loop = source->loop;
+	int ret = 0, saved_errno = 0;
+
+	/*
+	 * Since BSD doesn't treat all event sources as FDs, we need to
+	 * differentiate by source interface.
+	 */
+	if (source->interface == &fd_source_interface && source->fd >= 0) {
+		struct kevent ev[2];
+		int _ret[2], _saved_errno[2];
+
+		/*
+		 * We haven't stored state about the mask used when adding the
+		 * source, so we have to try and remove both READ and WRITE
+		 * filters. One may fail, which is OK. Removal of the source has
+		 * only failed if _both_ kevent() calls fail. We have to do two
+		 * kevent() calls so that we can get independent return values
+		 * for the two kevents.
+		 */
+		EV_SET(&ev[0], source->fd, EVFILT_READ, EV_DELETE, 0, 0,
+		      source);
+		EV_SET(&ev[1], source->fd, EVFILT_WRITE, EV_DELETE, 0, 0,
+		      source);
+
+		_ret[0] = kevent(loop->event_fd, &ev[0], 1, NULL, 0, NULL);
+		_saved_errno[0] = errno;
+		_ret[1] = kevent(loop->event_fd, &ev[1], 1, NULL, 0, NULL);
+		_saved_errno[1] = errno;
+
+		if (_ret[0] >= _ret[1]) {
+			ret = _ret[0];
+			saved_errno = _saved_errno[0];
+		} else {
+			ret = _ret[1];
+			saved_errno = _saved_errno[1];
+		}
+
+		close(source->fd);
+	} else if (source->interface == &timer_source_interface) {
+		struct kevent ev;
+
+		EV_SET(&ev, source->fd, EVFILT_TIMER, EV_DELETE, 0, 0, source);
+		ret = kevent(loop->event_fd, &ev, 1, NULL, 0, NULL);
+		saved_errno = errno;
+	} else if (source->interface == &signal_source_interface) {
+		struct kevent ev;
+		int signal_number;
+		struct wl_event_source_signal *_source;
+
+		/* Only one kevent() call needed. */
+		_source = (struct wl_event_source_signal *) source;
+		signal_number = _source->signal_number;
+
+		EV_SET(&ev, signal_number, EVFILT_SIGNAL, EV_DELETE, 0, 0,
+		      source);
+		ret = kevent(loop->event_fd, &ev, 1, NULL, 0, NULL);
+		saved_errno = errno;
+	}
+
+	/* Handle any errors from kevent() calls. */
+	if (ret < 0) {
+		fprintf(stderr,
+		        "error removing event (%i) from kqueue: %s\n",
+		        source->fd, strerror(saved_errno));
+	}
+
+	/* Tidy up the source. */
+	source->fd = -1;
+
+	wl_list_remove(&source->link);
+	wl_list_insert(&loop->destroy_list, &source->link);
+
+	return 0;
+}
+
+static void
+wl_event_loop_process_destroy_list(struct wl_event_loop *loop)
+{
+	struct wl_event_source *source, *next;
+
+	wl_list_for_each_safe(source, next, &loop->destroy_list, link)
+		free(source);
+
+	wl_list_init(&loop->destroy_list);
+}
+
+/** Create a new event loop context
+ *
+ * \return A new event loop context object.
+ *
+ * This creates a new event loop context. Initially this context is empty.
+ * Event sources need to be explicitly added to it.
+ *
+ * Normally the event loop is run by calling wl_event_loop_dispatch() in
+ * a loop until the program terminates. Alternatively, an event loop can be
+ * embedded in another event loop by its file descriptor, see
+ * wl_event_loop_get_fd().
+ *
+ * \memberof wl_event_loop
+ */
+WL_EXPORT struct wl_event_loop *
+wl_event_loop_create(void)
+{
+	struct wl_event_loop *loop;
+
+	loop = malloc(sizeof *loop);
+	if (loop == NULL)
+		return NULL;
+
+	loop->event_fd = wl_os_queue_create_cloexec();
+	if (loop->event_fd < 0) {
+		free(loop);
+		return NULL;
+	}
+	wl_list_init(&loop->check_list);
+	wl_list_init(&loop->idle_list);
+	wl_list_init(&loop->destroy_list);
+
+	wl_signal_init(&loop->destroy_signal);
+
+	return loop;
+}
+
+/** Destroy an event loop context
+ *
+ * \param loop The event loop to be destroyed.
+ *
+ * This emits the event loop destroy signal, closes the event loop file
+ * descriptor, and frees \c loop.
+ *
+ * If the event loop has existing sources, those cannot be safely removed
+ * afterwards. Therefore one must call wl_event_source_remove() on all
+ * event sources before destroying the event loop context.
+ *
+ * \memberof wl_event_loop
+ */
+WL_EXPORT void
+wl_event_loop_destroy(struct wl_event_loop *loop)
+{
+	wl_signal_emit(&loop->destroy_signal, loop);
+
+	wl_event_loop_process_destroy_list(loop);
+	close(loop->event_fd);
+	free(loop);
+}
+
+static bool
+post_dispatch_check(struct wl_event_loop *loop)
+{
+	struct kevent ev;
+	struct wl_event_source *source, *next;
+	bool needs_recheck = false;
+
+	wl_list_for_each_safe(source, next, &loop->check_list, link) {
+		int dispatch_result;
+
+		dispatch_result = source->interface->dispatch(source, &ev);
+		if (dispatch_result < 0) {
+			wl_log("Source dispatch function returned negative value!");
+			wl_log("This would previously accidentally suppress a follow-up dispatch");
+		}
+		needs_recheck |= dispatch_result != 0;
+	}
+
+	return needs_recheck;
+}
+
+/** Dispatch the idle sources
+ *
+ * \param loop The event loop whose idle sources are dispatched.
+ *
+ * \sa wl_event_loop_add_idle()
+ * \memberof wl_event_loop
+ */
+WL_EXPORT void
+wl_event_loop_dispatch_idle(struct wl_event_loop *loop)
+{
+	struct wl_event_source_idle *source;
+
+	while (!wl_list_empty(&loop->idle_list)) {
+		source = container_of(loop->idle_list.next,
+				      struct wl_event_source_idle, base.link);
+		source->func(source->base.data);
+		wl_event_source_remove(&source->base);
+	}
+}
+
+/** Wait for events and dispatch them
+ *
+ * \param loop The event loop whose sources to wait for.
+ * \param timeout The polling timeout in milliseconds.
+ * \return 0 for success, -1 for polling error.
+ *
+ * All the associated event sources are polled. This function blocks until
+ * any event source delivers an event (idle sources excluded), or the timeout
+ * expires. A timeout of -1 disables the timeout, causing the function to block
+ * indefinitely. A timeout of zero causes the poll to always return immediately.
+ *
+ * All idle sources are dispatched before blocking. An idle source is destroyed
+ * when it is dispatched. After blocking, all other ready sources are
+ * dispatched. Then, idle sources are dispatched again, in case the dispatched
+ * events created idle sources. Finally, all sources marked with
+ * wl_event_source_check() are dispatched in a loop until their dispatch
+ * functions all return zero.
+ *
+ * \memberof wl_event_loop
+ */
+WL_EXPORT int
+wl_event_loop_dispatch(struct wl_event_loop *loop, int timeout)
+{
+	struct kevent ev[64];
+	struct wl_event_source *source;
+	int i, count;
+	struct timespec timeout_spec;
+
+	wl_event_loop_dispatch_idle(loop);
+
+	/* timeout is provided in milliseconds */
+	timeout_spec.tv_sec = timeout / 1000;
+	timeout_spec.tv_nsec = (timeout % 1000) * 1000000;
+
+	count = kevent(loop->event_fd, NULL, 0, ev, ARRAY_LENGTH(ev),
+	               (timeout != -1) ? &timeout_spec : NULL);
+	if (count < 0)
+		return -1;
+
+	for (i = 0; i < count; i++) {
+		source = ev[i].udata;
+		if (source->fd != -1) {
+		       source->interface->dispatch(source, &ev[i]);
+		}
+	}
+
+	wl_event_loop_process_destroy_list(loop);
+
+	wl_event_loop_dispatch_idle(loop);
+
+	while (post_dispatch_check(loop));
+
+	return 0;
+}
+
+/** Get the event loop file descriptor
+ *
+ * \param loop The event loop context.
+ * \return The aggregate file descriptor.
+ *
+ * This function returns the aggregate file descriptor, that represents all
+ * the event sources (idle sources excluded) associated with the given event
+ * loop context. When any event source makes an event available, it will be
+ * reflected in the aggregate file descriptor.
+ *
+ * When the aggregate file descriptor delivers an event, one can call
+ * wl_event_loop_dispatch() on the event loop context to dispatch all the
+ * available events.
+ *
+ * \memberof wl_event_loop
+ */
+WL_EXPORT int
+wl_event_loop_get_fd(struct wl_event_loop *loop)
+{
+	return loop->event_fd;
+}
+
+/** Register a destroy listener for an event loop context
+ *
+ * \param loop The event loop context whose destruction to listen for.
+ * \param listener The listener with the callback to be called.
+ *
+ * \sa wl_listener
+ * \memberof wl_event_loop
+ */
+WL_EXPORT void
+wl_event_loop_add_destroy_listener(struct wl_event_loop *loop,
+				   struct wl_listener *listener)
+{
+	wl_signal_add(&loop->destroy_signal, listener);
+}
+
+/** Get the listener struct for the specified callback
+ *
+ * \param loop The event loop context to inspect.
+ * \param notify The destroy callback to find.
+ * \return The wl_listener registered to the event loop context with
+ * the given callback pointer.
+ *
+ * \memberof wl_event_loop
+ */
+WL_EXPORT struct wl_listener *
+wl_event_loop_get_destroy_listener(struct wl_event_loop *loop,
+				   wl_notify_func_t notify)
+{
+	return wl_signal_get(&loop->destroy_signal, notify);
+}
+#endif
diff --git a/wayland/patches/patch-Makefile.am b/wayland/patches/patch-Makefile.am
index d592256bd6..041717930f 100644
--- a/wayland/patches/patch-Makefile.am
+++ b/wayland/patches/patch-Makefile.am
@@ -1,31 +1,25 @@
 $NetBSD$
 
+https://lists.freedesktop.org/archives/wayland-devel/2019-February/040024.html
+
 --- Makefile.am.orig	2019-03-21 00:55:25.000000000 +0000
 +++ Makefile.am
-@@ -71,7 +71,7 @@ nodist_include_HEADERS =			\
- 	protocol/wayland-client-protocol.h
- 
- libwayland_server_la_CFLAGS = $(FFI_CFLAGS) $(AM_CFLAGS) -pthread
--libwayland_server_la_LIBADD = $(FFI_LIBS) libwayland-private.la libwayland-util.la -lrt -lm
-+libwayland_server_la_LIBADD = $(FFI_LIBS) $(EPOLLSHIM_LIBS) libwayland-private.la libwayland-util.la -lrt -lm
- libwayland_server_la_LDFLAGS = -version-info 1:0:1
+@@ -76,7 +76,8 @@ libwayland_server_la_LDFLAGS = -version-
  libwayland_server_la_SOURCES =			\
  	src/wayland-server.c			\
-@@ -83,7 +83,7 @@ nodist_libwayland_server_la_SOURCES =		\
- 	protocol/wayland-protocol.c
+ 	src/wayland-shm.c			\
+-	src/event-loop.c
++	src/event-loop.c 			\
++	src/event-loop-kqueue.c 
  
- libwayland_client_la_CFLAGS = $(FFI_CFLAGS) $(AM_CFLAGS) -pthread
--libwayland_client_la_LIBADD = $(FFI_LIBS) libwayland-private.la libwayland-util.la -lrt -lm
-+libwayland_client_la_LIBADD = $(FFI_LIBS) $(EPOLLSHIM_LIBS) libwayland-private.la libwayland-util.la -lrt -lm
- libwayland_client_la_LDFLAGS = -version-info 3:0:3
- libwayland_client_la_SOURCES =			\
- 	src/wayland-client.c
-@@ -227,7 +227,7 @@ libtest_runner_la_LIBADD =			\
+ nodist_libwayland_server_la_SOURCES =		\
+ 	protocol/wayland-server-protocol.h	\
+@@ -227,7 +228,7 @@ libtest_runner_la_LIBADD =			\
  	libwayland-client.la			\
  	libwayland-server.la			\
  	libtest-helpers.la			\
 -	-lrt -ldl $(FFI_LIBS)
-+	-lrt $(DL_LIBS) $(FFI_LIBS) $(EPOLLSHIM_LIBS)
++	-lrt $(DL_LIBS) $(FFI_LIBS)
  
  array_test_SOURCES = tests/array-test.c
  array_test_LDADD = libtest-runner.la
diff --git a/wayland/patches/patch-configure.ac b/wayland/patches/patch-configure.ac
index b4357acd5d..bc1bcf7000 100644
--- a/wayland/patches/patch-configure.ac
+++ b/wayland/patches/patch-configure.ac
@@ -1,15 +1,22 @@
---- configure.ac.orig	2018-08-24 18:04:36 UTC
-+++ configure.ac
+$NetBSD$
+
+BSD support from FreeBSD
+
+https://lists.freedesktop.org/archives/wayland-devel/2019-February/040024.html
+
 --- configure.ac.orig	2019-03-21 00:55:25.000000000 +0000
 +++ configure.ac
-@@ -65,6 +65,25 @@ AC_SUBST(GCC_CFLAGS)
+@@ -65,6 +65,28 @@ AC_SUBST(GCC_CFLAGS)
  AC_CHECK_HEADERS([sys/prctl.h])
  AC_CHECK_FUNCS([accept4 mkostemp posix_fallocate prctl])
  
-+AC_CHECK_HEADERS([sys/signalfd.h sys/timerfd.h])
 +
-+# Use epoll on Linux and epoll-shim (kqueue) on BSD
-+AC_CHECK_HEADERS([sys/epoll.h])
++AC_CHECK_HEADERS([sys/epoll.h sys/event.h])
++if test "x$ac_cv_header_sys_epoll_h" != "xyes" && test "x$ac_cv_header_sys_event_h" != "xyes"; then
++	AC_MSG_ERROR([Can't find sys/epoll.h or sys/event.h. Please ensure either epoll or kqueue is available.])
++fi
++
++AC_CHECK_HEADERS([sys/signalfd.h sys/timerfd.h])
 +
 +# Credential support on FreeBSD
 +AC_CHECK_HEADERS([sys/ucred.h])
@@ -28,19 +35,25 @@
  AC_ARG_ENABLE([libraries],
  	      [AC_HELP_STRING([--disable-libraries],
  			      [Disable compilation of wayland libraries])],
-@@ -100,17 +119,21 @@ AC_SUBST([ICONDIR])
+@@ -100,17 +122,23 @@ AC_SUBST([ICONDIR])
  
  if test "x$enable_libraries" = "xyes"; then
  	PKG_CHECK_MODULES(FFI, [libffi])
-+dnl convert SFD_CLOEXEC and TFD_CLOEXEC to warning while figuring out how to do this.
- 	AC_CHECK_DECL(SFD_CLOEXEC,[],
+-	AC_CHECK_DECL(SFD_CLOEXEC,[],
 -		      [AC_MSG_ERROR("SFD_CLOEXEC is needed to compile wayland libraries")],
-+		      [AC_MSG_WARN("SFD_CLOEXEC is needed to compile wayland libraries")],
- 		      [[#include <sys/signalfd.h>]])
- 	AC_CHECK_DECL(TFD_CLOEXEC,[],
+-		      [[#include <sys/signalfd.h>]])
+-	AC_CHECK_DECL(TFD_CLOEXEC,[],
 -		      [AC_MSG_ERROR("TFD_CLOEXEC is needed to compile wayland libraries")],
-+		      [AC_MSG_WARN("TFD_CLOEXEC is needed to compile wayland libraries")],
- 		      [[#include <sys/timerfd.h>]])
+-		      [[#include <sys/timerfd.h>]])
++dnl convert SFD_CLOEXEC and TFD_CLOEXEC to warning while figuring out how to do this.
++	if test "x$ac_cv_header_sys_epoll_h" = "xyes"; then
++		AC_CHECK_DECL(SFD_CLOEXEC,[],
++			      [AC_MSG_WARN("SFD_CLOEXEC is needed to compile wayland libraries")],
++			      [[#include <sys/signalfd.h>]])
++		AC_CHECK_DECL(TFD_CLOEXEC,[],
++			      [AC_MSG_WARN("TFD_CLOEXEC is needed to compile wayland libraries")],
++			      [[#include <sys/timerfd.h>]])
++	fi
  	AC_CHECK_DECL(CLOCK_MONOTONIC,[],
  		      [AC_MSG_ERROR("CLOCK_MONOTONIC is needed to compile wayland libraries")],
  		      [[#include <time.h>]])
diff --git a/wayland/patches/patch-src_event-loop.c b/wayland/patches/patch-src_event-loop.c
index 518306ed00..90ad400fc8 100644
--- a/wayland/patches/patch-src_event-loop.c
+++ b/wayland/patches/patch-src_event-loop.c
@@ -1,8 +1,20 @@
 $NetBSD$
 
---- event-loop.c.orig	2017-08-08 18:20:52.000000000 +0000
+https://lists.freedesktop.org/archives/wayland-devel/2019-February/040024.html
+
+--- src/event-loop.c.orig	2019-03-21 00:55:25.000000000 +0000
 +++ src/event-loop.c
-@@ -34,9 +34,9 @@
+@@ -22,7 +22,8 @@
+  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  * SOFTWARE.
+  */
+-
++#include "config.h"
++#ifdef HAVE_SYS_EPOLL_H
+ #include <stddef.h>
+ #include <stdio.h>
+ #include <errno.h>
+@@ -35,9 +36,9 @@
  #include <sys/socket.h>
  #include <sys/un.h>
  #include <sys/epoll.h>
@@ -13,3 +25,8 @@ $NetBSD$
  #include "wayland-util.h"
  #include "wayland-private.h"
  #include "wayland-server-core.h"
+@@ -702,3 +703,4 @@ wl_event_loop_get_destroy_listener(struc
+ {
+ 	return wl_signal_get(&loop->destroy_signal, notify);
+ }
++#endif /* HAVE_SYS_EPOLL_H */
diff --git a/wayland/patches/patch-src_wayland-os.c b/wayland/patches/patch-src_wayland-os.c
index eccea49077..8bc5391aa7 100644
--- a/wayland/patches/patch-src_wayland-os.c
+++ b/wayland/patches/patch-src_wayland-os.c
@@ -2,9 +2,11 @@ $NetBSD$
 
 BSD support from FreeBSD
 
---- src/wayland-os.c.orig	2017-08-08 18:20:52 UTC
+https://lists.freedesktop.org/archives/wayland-devel/2019-February/040024.html
+
+--- src/wayland-os.c.orig	2019-03-21 00:55:25.000000000 +0000
 +++ src/wayland-os.c
-@@ -25,6 +25,8 @@
+@@ -25,14 +25,20 @@
  
  #define _GNU_SOURCE
  
@@ -13,15 +15,20 @@ BSD support from FreeBSD
  #include <sys/types.h>
  #include <sys/socket.h>
  #include <unistd.h>
-@@ -32,7 +34,6 @@
+ #include <fcntl.h>
  #include <errno.h>
++#ifdef HAVE_SYS_EPOLL_H
  #include <sys/epoll.h>
++#endif
++#ifdef HAVE_SYS_EVENT_H
++#include <sys/event.h>
++#endif
  
 -#include "../config.h"
  #include "wayland-os.h"
  
  static int
-@@ -62,26 +63,50 @@ wl_os_socket_cloexec(int domain, int type, int protoco
+@@ -62,26 +68,50 @@ wl_os_socket_cloexec(int domain, int typ
  {
  	int fd;
  
@@ -72,7 +79,7 @@ BSD support from FreeBSD
  
  	newfd = fcntl(fd, F_DUPFD, minfd);
  	return set_cloexec_or_close(newfd);
-@@ -123,15 +148,18 @@ wl_os_recvmsg_cloexec(int sockfd, struct msghdr *msg, 
+@@ -123,17 +153,20 @@ wl_os_recvmsg_cloexec(int sockfd, struct
  {
  	ssize_t len;
  
@@ -89,12 +96,24 @@ BSD support from FreeBSD
  
 +#ifdef HAVE_SYS_EPOLL_H
  int
- wl_os_epoll_create_cloexec(void)
+-wl_os_epoll_create_cloexec(void)
++wl_os_queue_create_cloexec(void)
  {
-@@ -148,6 +176,7 @@ wl_os_epoll_create_cloexec(void)
+ 	int fd;
+ 
+@@ -148,6 +181,16 @@ wl_os_epoll_create_cloexec(void)
  	fd = epoll_create(1);
  	return set_cloexec_or_close(fd);
  }
++#elif defined(HAVE_SYS_EVENT_H)
++int
++wl_os_queue_create_cloexec(void)
++{
++	int fd;
++
++	fd = kqueue();
++	return set_cloexec_or_close(fd);
++}
 +#endif
  
  int
diff --git a/wayland/patches/patch-src_wayland-os.h b/wayland/patches/patch-src_wayland-os.h
index 20da3d741d..5bfe2c2e38 100644
--- a/wayland/patches/patch-src_wayland-os.h
+++ b/wayland/patches/patch-src_wayland-os.h
@@ -2,9 +2,17 @@ $NetBSD$
 
 BSD support from FreeBSD
 
---- src/wayland-os.h.orig	2017-08-08 18:20:52 UTC
+https://lists.freedesktop.org/archives/wayland-devel/2019-February/040024.html
+
+--- src/wayland-os.h.orig	2019-03-21 00:55:25.000000000 +0000
 +++ src/wayland-os.h
-@@ -30,6 +30,9 @@ int
+@@ -26,17 +26,23 @@
+ #ifndef WAYLAND_OS_H
+ #define WAYLAND_OS_H
+ 
++#include "../config.h"
++
+ int
  wl_os_socket_cloexec(int domain, int type, int protocol);
  
  int
@@ -14,3 +22,12 @@ BSD support from FreeBSD
  wl_os_dupfd_cloexec(int fd, long minfd);
  
  ssize_t
+ wl_os_recvmsg_cloexec(int sockfd, struct msghdr *msg, int flags);
+ 
++
+ int
+-wl_os_epoll_create_cloexec(void);
++wl_os_queue_create_cloexec(void);
+ 
+ int
+ wl_os_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
diff --git a/wayland/patches/patch-src_wayland-shm.c b/wayland/patches/patch-src_wayland-shm.c
index 716fff861e..1332bf1e51 100644
--- a/wayland/patches/patch-src_wayland-shm.c
+++ b/wayland/patches/patch-src_wayland-shm.c
@@ -1,5 +1,7 @@
---- src/wayland-shm.c.orig	2018-04-09 17:19:26 UTC
-+++ src/wayland-shm.c
+$NetBSD$
+
+BSD support from FreeBSD
+
 --- src/wayland-shm.c.orig	2019-03-21 00:55:25.000000000 +0000
 +++ src/wayland-shm.c
 @@ -30,6 +30,8 @@
diff --git a/wayland/patches/patch-tests_os-wrappers-test.c b/wayland/patches/patch-tests_os-wrappers-test.c
index af6080e042..49c2963134 100644
--- a/wayland/patches/patch-tests_os-wrappers-test.c
+++ b/wayland/patches/patch-tests_os-wrappers-test.c
@@ -2,7 +2,9 @@ $NetBSD$
 
 BSD support from FreeBSD
 
---- tests/os-wrappers-test.c.orig	2017-08-08 18:20:52 UTC
+https://lists.freedesktop.org/archives/wayland-devel/2019-February/040024.html
+
+--- tests/os-wrappers-test.c.orig	2019-03-21 00:55:25.000000000 +0000
 +++ tests/os-wrappers-test.c
 @@ -26,6 +26,8 @@
  
@@ -13,7 +15,46 @@ BSD support from FreeBSD
  #include <stdlib.h>
  #include <stdint.h>
  #include <assert.h>
-@@ -73,10 +75,12 @@ socket(int domain, int type, int protocol)
+@@ -38,7 +40,12 @@
+ #include <stdarg.h>
+ #include <fcntl.h>
+ #include <stdio.h>
++
++#ifdef HAVE_SYS_EPOLL_H
+ #include <sys/epoll.h>
++#elif defined(HAVE_SYS_EVENT_H)
++#include <sys/event.h>
++#endif
+ 
+ #include "wayland-private.h"
+ #include "test-runner.h"
+@@ -55,8 +62,13 @@ static int wrapped_calls_fcntl;
+ static ssize_t (*real_recvmsg)(int, struct msghdr *, int);
+ static int wrapped_calls_recvmsg;
+ 
++#ifdef HAVE_SYS_EPOLL_H
+ static int (*real_epoll_create1)(int);
+ static int wrapped_calls_epoll_create1;
++#elif defined(HAVE_SYS_EVENT_H)
++static int (*real_kqueue)(void);
++static int wrapped_calls_kqueue;
++#endif
+ 
+ static void
+ init_fallbacks(int do_fallbacks)
+@@ -65,7 +77,11 @@ init_fallbacks(int do_fallbacks)
+ 	real_socket = dlsym(RTLD_NEXT, "socket");
+ 	real_fcntl = dlsym(RTLD_NEXT, "fcntl");
+ 	real_recvmsg = dlsym(RTLD_NEXT, "recvmsg");
++#ifdef HAVE_SYS_EPOLL_H
+ 	real_epoll_create1 = dlsym(RTLD_NEXT, "epoll_create1");
++#elif defined(HAVE_SYS_EVENT_H)
++	real_kqueue = dlsym(RTLD_NEXT, "kqueue");
++#endif
+ }
+ 
+ __attribute__ ((visibility("default"))) int
+@@ -73,10 +89,12 @@ socket(int domain, int type, int protoco
  {
  	wrapped_calls_socket++;
  
@@ -26,7 +67,7 @@ BSD support from FreeBSD
  
  	return real_socket(domain, type, protocol);
  }
-@@ -89,10 +93,12 @@ fcntl(int fd, int cmd, ...)
+@@ -89,10 +107,12 @@ fcntl(int fd, int cmd, ...)
  
  	wrapped_calls_fcntl++;
  
@@ -39,7 +80,7 @@ BSD support from FreeBSD
  
  	va_start(ap, cmd);
  	arg = va_arg(ap, void*);
-@@ -106,10 +112,12 @@ recvmsg(int sockfd, struct msghdr *msg, int flags)
+@@ -106,14 +126,17 @@ recvmsg(int sockfd, struct msghdr *msg, 
  {
  	wrapped_calls_recvmsg++;
  
@@ -52,7 +93,34 @@ BSD support from FreeBSD
  
  	return real_recvmsg(sockfd, msg, flags);
  }
-@@ -156,12 +164,14 @@ TEST(os_wrappers_socket_cloexec)
+ 
++#ifdef HAVE_SYS_EPOLL_H
+ __attribute__ ((visibility("default"))) int
+ epoll_create1(int flags)
+ {
+@@ -127,6 +150,21 @@ epoll_create1(int flags)
+ 
+ 	return real_epoll_create1(flags);
+ }
++#elif defined(HAVE_SYS_EVENT_H)
++__attribute__ ((visibility("default"))) int
++kqueue(void)
++{
++	wrapped_calls_kqueue++;
++
++	if (fall_back) {
++		wrapped_calls_kqueue++; /* kqueue() not wrapped */
++		errno = EINVAL;
++		return -1;
++	}
++
++	return real_kqueue();
++}
++#endif
+ 
+ static void
+ do_os_wrappers_socket_cloexec(int n)
+@@ -156,12 +194,14 @@ TEST(os_wrappers_socket_cloexec)
  	do_os_wrappers_socket_cloexec(0);
  }
  
@@ -67,7 +135,7 @@ BSD support from FreeBSD
  
  static void
  do_os_wrappers_dupfd_cloexec(int n)
-@@ -195,11 +205,13 @@ TEST(os_wrappers_dupfd_cloexec)
+@@ -195,11 +235,13 @@ TEST(os_wrappers_dupfd_cloexec)
  	do_os_wrappers_dupfd_cloexec(0);
  }
  
@@ -81,7 +149,7 @@ BSD support from FreeBSD
  
  struct marshal_data {
  	struct wl_connection *read_connection;
-@@ -218,8 +230,7 @@ struct marshal_data {
+@@ -218,8 +260,7 @@ struct marshal_data {
  static void
  setup_marshal_data(struct marshal_data *data)
  {
@@ -91,7 +159,7 @@ BSD support from FreeBSD
  
  	data->read_connection = wl_connection_create(data->s[0]);
  	assert(data->read_connection);
-@@ -328,11 +339,13 @@ TEST(os_wrappers_recvmsg_cloexec)
+@@ -328,21 +369,23 @@ TEST(os_wrappers_recvmsg_cloexec)
  	do_os_wrappers_recvmsg_cloexec(0);
  }
  
@@ -104,4 +172,32 @@ BSD support from FreeBSD
 +#endif
  
  static void
- do_os_wrappers_epoll_create_cloexec(int n)
+-do_os_wrappers_epoll_create_cloexec(int n)
++do_os_wrappers_queue_create_cloexec(int n)
+ {
+ 	int fd;
+ 	int nr_fds;
+ 
+ 	nr_fds = count_open_fds();
+ 
+-	fd = wl_os_epoll_create_cloexec();
++	fd = wl_os_queue_create_cloexec();
+ 	assert(fd >= 0);
+ 
+ #ifdef EPOLL_CLOEXEC
+@@ -357,13 +400,13 @@ do_os_wrappers_epoll_create_cloexec(int 
+ TEST(os_wrappers_epoll_create_cloexec)
+ {
+ 	init_fallbacks(0);
+-	do_os_wrappers_epoll_create_cloexec(1);
++	do_os_wrappers_queue_create_cloexec(1);
+ }
+ 
+ TEST(os_wrappers_epoll_create_cloexec_fallback)
+ {
+ 	init_fallbacks(1);
+-	do_os_wrappers_epoll_create_cloexec(2);
++	do_os_wrappers_queue_create_cloexec(2);
+ }
+ 
+ /* FIXME: add tests for wl_os_accept_cloexec() */
diff --git a/wayland/patches/patch-tests_sanity-test.c b/wayland/patches/patch-tests_sanity-test.c
index 13aef248c2..e77d6e887e 100644
--- a/wayland/patches/patch-tests_sanity-test.c
+++ b/wayland/patches/patch-tests_sanity-test.c
@@ -1,5 +1,7 @@
 $NetBSD$
 
+BSD support from FreeBSD
+
 --- tests/sanity-test.c.orig	2019-03-21 00:55:25.000000000 +0000
 +++ tests/sanity-test.c
 @@ -87,7 +87,8 @@ FAIL_TEST(sanity_fd_leak)
diff --git a/wayland/patches/patch-tests_test-helpers.c b/wayland/patches/patch-tests_test-helpers.c
index 917f92066e..ab074d42b5 100644
--- a/wayland/patches/patch-tests_test-helpers.c
+++ b/wayland/patches/patch-tests_test-helpers.c
@@ -1,5 +1,7 @@
---- tests/test-helpers.c.orig	2018-08-24 18:04:36 UTC
-+++ tests/test-helpers.c
+$NetBSD$
+
+SBD support for FreeBSD
+
 --- tests/test-helpers.c.orig	2019-03-21 00:55:25.000000000 +0000
 +++ tests/test-helpers.c
 @@ -25,6 +25,12 @@
diff --git a/wayland/patches/patch-tests_test-runner.c b/wayland/patches/patch-tests_test-runner.c
index 0e6cbd6cf1..1a49d9aee6 100644
--- a/wayland/patches/patch-tests_test-runner.c
+++ b/wayland/patches/patch-tests_test-runner.c
@@ -1,5 +1,7 @@
 $NetBSD$
 
+BSD support from FreeBSD
+
 --- tests/test-runner.c.orig	2019-03-21 00:55:25.000000000 +0000
 +++ tests/test-runner.c
 @@ -25,6 +25,12 @@



Home | Main Index | Thread Index | Old Index