# Buildsheet autogenerated by ravenadm tool -- Do not edit. NAMEBASE= wayland VERSION= 1.22.0 REVISION= 1 KEYWORDS= graphics VARIANTS= standard SDESC[standard]= Wayland Display Protocol implementation HOMEPAGE= https://wayland.freedesktop.org/ CONTACT= Peeter_Must[karu.pruun@gmail.com] DOWNLOAD_GROUPS= main SITES[main]= https://gitlab.freedesktop.org/wayland/wayland/-/releases/1.22.0/downloads/ DISTFILE[1]= wayland-1.22.0.tar.xz:main DF_INDEX= 1 SPKGS[standard]= complete primary dev tools OPTIONS_AVAILABLE= EPOLLSHIM OPTIONS_STANDARD= EPOLLSHIM OPT_ON[freebsd]= EPOLLSHIM ONLY_FOR_OPSYS= dragonfly freebsd linux BUILD_DEPENDS= libxslt:primary:standard libffi:dev:standard BUILDRUN_DEPENDS= libffi:primary:standard EXRUN[tools]= wayland:primary:standard USES= cpe meson pkgconfig expat GNOME_COMPONENTS= libxml2 LICENSE= MIT:primary LICENSE_FILE= MIT:{{WRKSRC}}/COPYING LICENSE_SCHEME= solo FPC_EQUIVALENT= graphics/wayland MESON_ARGS= -Ddocumentation=false INSTALL_TARGET= install-strip INSTALL_REQ_TOOLCHAIN= yes SOVERSION= 0.22.0 PLIST_SUB= EGLSOVERSION=1.22.0 EGLSOMAJOR=1 [EPOLLSHIM].DESCRIPTION= Platform depends on libepoll-shim [EPOLLSHIM].BUILDRUN_DEPENDS_ON= libepoll-shim:primary:standard [EPOLLSHIM].BUILD_DEPENDS_ON= libepoll-shim:dev:standard [FILE:131:descriptions/desc.primary] Wayland is intended as a simpler replacement for X, easier to develop and maintain. GNOME and KDE are expected to be ported to it. [FILE:48:descriptions/desc.tools] This package contains the wayland scanner tool. [FILE:100:distinfo] 1540af1ea698a471c2d8e9d288332c7e0fd360c8f1d12936ebb7e7cbc2425842 229544 wayland-1.22.0.tar.xz [FILE:285:manifests/plist.primary] lib/ libwayland-client.so.%%SOMAJOR%% libwayland-client.so.%%SOVERSION%% libwayland-cursor.so.%%SOMAJOR%% libwayland-cursor.so.%%SOVERSION%% libwayland-egl.so.%%EGLSOMAJOR%% libwayland-egl.so.%%EGLSOVERSION%% libwayland-server.so.%%SOMAJOR%% libwayland-server.so.%%SOVERSION%% [FILE:511:manifests/plist.dev] include/ wayland-client-core.h wayland-client-protocol.h wayland-client.h wayland-cursor.h wayland-egl-backend.h wayland-egl-core.h wayland-egl.h wayland-server-core.h wayland-server-protocol.h wayland-server.h wayland-util.h wayland-version.h lib/ libwayland-client.so libwayland-cursor.so libwayland-egl.so libwayland-server.so lib/pkgconfig/ wayland-client.pc wayland-cursor.pc wayland-egl-backend.pc wayland-egl.pc wayland-scanner.pc wayland-server.pc share/aclocal/wayland-scanner.m4 [FILE:81:manifests/plist.tools] bin/wayland-scanner share/wayland/ wayland-scanner.mk wayland.dtd wayland.xml [FILE:1565:dragonfly/patch-meson.build] --- meson.build.orig 2023-04-04 07:58:31 UTC +++ meson.build @@ -16,7 +16,7 @@ config_h.set_quoted('PACKAGE', meson.pro config_h.set_quoted('PACKAGE_VERSION', meson.project_version()) cc_args = [] -if host_machine.system() != 'freebsd' +if host_machine.system() != 'dragonfly' cc_args += ['-D_POSIX_C_SOURCE=200809L'] endif add_project_arguments(cc_args, language: 'c') @@ -43,7 +43,6 @@ have_funcs = [ 'mkostemp', 'posix_fallocate', 'prctl', - 'memfd_create', 'mremap', 'strndup', ] @@ -52,11 +51,11 @@ foreach f: have_funcs endforeach config_h.set10('HAVE_XUCRED_CR_PID', cc.has_member('struct xucred', 'cr_pid', prefix : '#include ')) have_broken_msg_cmsg_cloexec = false -if host_machine.system() == 'freebsd' +if host_machine.system() == 'freebsd' or host_machine.system() == 'dragonfly' have_broken_msg_cmsg_cloexec = not cc.compiles(''' #include /* To get __FreeBSD_version. */ #if __FreeBSD_version < 1300502 || \ - (__FreeBSD_version >= 1400000 && __FreeBSD_version < 1400006) + (__FreeBSD_version >= 1400000 && __FreeBSD_version < 1400006) || defined(__DragonFly__) /* * FreeBSD had a broken implementation of MSG_CMSG_CLOEXEC between 2015 and * 2021. Check if we are compiling against a version that includes the fix @@ -80,8 +79,6 @@ if get_option('libraries') ffi_dep = dependency('libffi') decls = [ - { 'header': 'sys/signalfd.h', 'symbol': 'SFD_CLOEXEC' }, - { 'header': 'sys/timerfd.h', 'symbol': 'TFD_CLOEXEC' }, { 'header': 'time.h', 'symbol': 'CLOCK_MONOTONIC' }, ] [FILE:1347:dragonfly/patch-src_connection.c] --- src/connection.c.orig 2023-04-04 07:58:31 UTC +++ src/connection.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include "wayland-util.h" @@ -306,7 +307,10 @@ wl_connection_flush(struct wl_connection msg.msg_iov = iov; msg.msg_iovlen = count; - msg.msg_control = (clen > 0) ? cmsg : NULL; + if (clen == 0) + msg.msg_control = NULL; + else + msg.msg_control = cmsg; msg.msg_controllen = clen; do { @@ -376,11 +380,25 @@ int wl_connection_write(struct wl_connection *connection, const void *data, size_t count) { - if (connection->out.head - connection->out.tail + + struct pollfd pfd; + + while (connection->out.head - connection->out.tail + count > ARRAY_LENGTH(connection->out.data)) { - connection->want_flush = 1; - if (wl_connection_flush(connection) < 0) - return -1; + if (wl_connection_flush(connection) < 0) { + if (errno == EAGAIN) { + pfd.fd = connection->fd; + pfd.events = POLLWRNORM; + pfd.revents = 0; + int ret; + do { + ret = poll(&pfd, 1, -1); + } while (ret == -1 && errno == EINTR); + } else { + wl_log("%s: wl_connection_flush failed: %s\n", + __func__, strerror(errno)); + return -1; + } + } } if (ring_buffer_put(&connection->out, data, count) < 0) [FILE:17660:dragonfly/patch-src_event-loop.c] --- src/event-loop.c.orig 2023-04-04 07:58:31 UTC +++ src/event-loop.c @@ -34,10 +34,9 @@ #include #include #include +#include +#include #include -#include -#include -#include #include #include "wayland-util.h" #include "wayland-private.h" @@ -68,7 +67,7 @@ struct wl_timer_heap { }; struct wl_event_loop { - int epoll_fd; + int event_fd; struct wl_list check_list; struct wl_list idle_list; struct wl_list destroy_list; @@ -80,7 +79,7 @@ struct wl_event_loop { struct wl_event_source_interface { int (*dispatch)(struct wl_event_source *source, - struct epoll_event *ep); + struct kevent *kv); }; @@ -94,22 +93,22 @@ struct wl_event_source_fd { static int wl_event_source_fd_dispatch(struct wl_event_source *source, - struct epoll_event *ep) + struct kevent *ev) { struct wl_event_source_fd *fd_source = (struct wl_event_source_fd *) source; uint32_t mask; mask = 0; - if (ep->events & EPOLLIN) + if (ev->filter == EVFILT_READ) mask |= WL_EVENT_READABLE; - if (ep->events & EPOLLOUT) + if (ev->filter == EVFILT_WRITE) mask |= WL_EVENT_WRITABLE; - if (ep->events & EPOLLHUP) + if (ev->flags & EV_EOF) mask |= WL_EVENT_HANGUP; - if (ep->events & EPOLLERR) + if (ev->flags & EV_ERROR) mask |= WL_EVENT_ERROR; - return fd_source->func(fd_source->fd, mask, source->data); + return fd_source->func(source->fd, mask, source->data); } struct wl_event_source_interface fd_source_interface = { @@ -120,30 +119,10 @@ static struct wl_event_source * add_source(struct wl_event_loop *loop, struct wl_event_source *source, uint32_t mask, void *data) { - struct epoll_event ep; - - if (source->fd < 0) { - free(source); - return NULL; - } - source->loop = loop; source->data = data; wl_list_init(&source->link); - memset(&ep, 0, sizeof ep); - if (mask & WL_EVENT_READABLE) - ep.events |= EPOLLIN; - if (mask & WL_EVENT_WRITABLE) - ep.events |= EPOLLOUT; - ep.data.ptr = source; - - if (epoll_ctl(loop->epoll_fd, EPOLL_CTL_ADD, source->fd, &ep) < 0) { - close(source->fd); - free(source); - return NULL; - } - return source; } @@ -179,6 +158,9 @@ wl_event_loop_add_fd(struct wl_event_loo { struct wl_event_source_fd *source; + struct kevent events[2]; + unsigned int num_events = 0; + source = zalloc(sizeof *source); if (source == NULL) return NULL; @@ -187,8 +169,36 @@ wl_event_loop_add_fd(struct wl_event_loo 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: %s\n", + strerror(errno)); + free(source); + return NULL; + } - return add_source(loop, &source->base, mask, data); + 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 @@ -215,16 +225,22 @@ WL_EXPORT int wl_event_source_fd_update(struct wl_event_source *source, uint32_t mask) { struct wl_event_loop *loop = source->loop; - struct epoll_event ep; + 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++; + } - memset(&ep, 0, sizeof ep); - if (mask & WL_EVENT_READABLE) - ep.events |= EPOLLIN; - if (mask & WL_EVENT_WRITABLE) - ep.events |= EPOLLOUT; - ep.data.ptr = source; + if (mask & WL_EVENT_WRITABLE) { + EV_SET(&events[num_events], source->fd, EVFILT_WRITE, + EV_ADD | EV_ENABLE, 0, 0, source); + num_events++; + } - return epoll_ctl(loop->epoll_fd, EPOLL_CTL_MOD, source->fd, &ep); + return kevent(loop->event_fd, events, num_events, NULL, 0, NULL); } /** \cond INTERNAL */ @@ -239,7 +255,7 @@ struct wl_event_source_timer { static int noop_dispatch(struct wl_event_source *source, - struct epoll_event *ep) { + struct kevent *ep) { return 0; } @@ -257,25 +273,47 @@ time_lt(struct timespec ta, struct times } static int -set_timer(int timerfd, struct timespec deadline) { - struct itimerspec its; +set_timer(int timerfd, + struct timespec deadline, + struct wl_timer_heap *timers) +{ + struct kevent ev; + struct timespec now; + time_t diff_sec; + long diff_nsec; + long rel_deadline; /* msec */ + + if (clock_gettime(CLOCK_MONOTONIC, &now) == -1) + return -1; + + if (!time_lt(now, deadline)) + return -1; + + diff_sec = deadline.tv_sec - now.tv_sec; + diff_nsec = deadline.tv_nsec - now.tv_nsec; + if (diff_nsec < 0) { + diff_sec--; + diff_nsec += 1000000000L; + } - its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 0; - its.it_value = deadline; - return timerfd_settime(timerfd, TFD_TIMER_ABSTIME, &its, NULL); + rel_deadline = (long) ((diff_sec * 1000) + (diff_nsec / 1000000)); + if ((diff_nsec % 1000000) > 499999) + rel_deadline++; + + EV_SET(&ev, timerfd, EVFILT_TIMER, EV_ADD | EV_ENABLE | EV_ONESHOT, + 0, rel_deadline, timers); + + return kevent(timers->base.loop->event_fd, &ev, 1, NULL, 0, NULL); } static int -clear_timer(int timerfd) +clear_timer(int timerfd, struct wl_timer_heap *timers) { - struct itimerspec its; + struct kevent ev; - its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 0; - its.it_value.tv_sec = 0; - its.it_value.tv_nsec = 0; - return timerfd_settime(timerfd, 0, &its, NULL); + EV_SET(&ev, timerfd, EVFILT_TIMER, EV_ADD | EV_DISABLE, + 0, 0, timers); + return kevent(timers->base.loop->event_fd, &ev, 1, NULL, 0, NULL); } static void @@ -296,37 +334,43 @@ wl_timer_heap_init(struct wl_timer_heap static void wl_timer_heap_release(struct wl_timer_heap *timers) { - if (timers->base.fd != -1) { - close(timers->base.fd); - } free(timers->data); } +/* + * Timers are now kept in a binary heap. There is only one timer source + * which is used for all timer events. This routine ensures that the single + * kevent timer is created. + */ static int wl_timer_heap_ensure_timerfd(struct wl_timer_heap *timers) { - struct epoll_event ep; - int timer_fd; - - if (timers->base.fd != -1) - return 0; - - memset(&ep, 0, sizeof ep); - ep.events = EPOLLIN; - ep.data.ptr = timers; - - timer_fd = timerfd_create(CLOCK_MONOTONIC, - TFD_CLOEXEC | TFD_NONBLOCK); - if (timer_fd < 0) - return -1; - - if (epoll_ctl(timers->base.loop->epoll_fd, - EPOLL_CTL_ADD, timer_fd, &ep) < 0) { - close(timer_fd); + struct kevent ev; + /* + * Deprecated. + * We don't need a static counter any more, but keep it here for now. + * It must be => 0. + */ + static int timer_id = 1; + + /* + * We need to add timer filter already here. This avoids error messages + * when the timer filter is removed before ever updating it. + * Note the timer will not be enabled, this happens only in the update + * routine which arms/disarms the timer.) + */ + EV_SET(&ev, timer_id, + EVFILT_TIMER, EV_ADD | EV_DISABLE | EV_ONESHOT, 0, 0, timers); + if (kevent(timers->base.loop->event_fd, &ev, 1, NULL, 0, NULL) < 0) { + fprintf(stderr, "Could not add timer: %s\n", + strerror(errno)); return -1; } - timers->base.fd = timer_fd; + timers->base.fd = timer_id; + /* Deprecated, same as above. */ + timer_id++; + return 0; } @@ -484,7 +528,6 @@ wl_timer_heap_arm(struct wl_timer_heap * heap_sift_up(timers->data, source); } - static int wl_timer_heap_dispatch(struct wl_timer_heap *timers) { @@ -511,10 +554,10 @@ wl_timer_heap_dispatch(struct wl_timer_h list_tail->next_due = NULL; if (timers->active > 0) { - if (set_timer(timers->base.fd, timers->data[0]->deadline) < 0) + if (set_timer(timers->base.fd, timers->data[0]->deadline, timers) < 0) return -1; } else { - if (clear_timer(timers->base.fd) < 0) + if (clear_timer(timers->base.fd, timers) < 0) return -1; } @@ -531,7 +574,7 @@ wl_timer_heap_dispatch(struct wl_timer_h static int wl_event_source_timer_dispatch(struct wl_event_source *source, - struct epoll_event *ep) + struct kevent *ev) { struct wl_event_source_timer *timer; @@ -639,7 +682,7 @@ wl_event_source_timer_update(struct wl_e if (tsource->heap_idx == 0) { /* Only update the timerfd if the new deadline is * the earliest */ - if (set_timer(timers->base.fd, deadline) < 0) + if (set_timer(timers->base.fd, timers->data[0]->deadline, timers) < 0) return -1; } } else { @@ -650,7 +693,7 @@ wl_event_source_timer_update(struct wl_e if (timers->active == 0) { /* Only update the timerfd if this was the last * active timer */ - if (clear_timer(timers->base.fd) < 0) + if (clear_timer(timers->base.fd, timers) < 0) return -1; } } @@ -670,17 +713,11 @@ struct wl_event_source_signal { static int wl_event_source_signal_dispatch(struct wl_event_source *source, - struct epoll_event *ep) + struct kevent *ev) { - struct wl_event_source_signal *signal_source = - (struct wl_event_source_signal *) source; - struct signalfd_siginfo signal_info; - int len; - - len = read(source->fd, &signal_info, sizeof signal_info); - if (!(len == -1 && errno == EAGAIN) && len != sizeof signal_info) - /* Is there anything we can do here? Will this ever happen? */ - wl_log("signalfd read error: %s\n", strerror(errno)); + struct wl_event_source_signal *signal_source; + + signal_source = (struct wl_event_source_signal *) source; return signal_source->func(signal_source->signal_number, signal_source->base.data); @@ -717,6 +754,7 @@ wl_event_loop_add_signal(struct wl_event { struct wl_event_source_signal *source; sigset_t mask; + struct kevent ev; source = zalloc(sizeof *source); if (source == NULL) @@ -724,15 +762,26 @@ wl_event_loop_add_signal(struct wl_event source->base.interface = &signal_source_interface; source->signal_number = signal_number; + source->func = func; sigemptyset(&mask); sigaddset(&mask, signal_number); - source->base.fd = signalfd(-1, &mask, SFD_CLOEXEC | SFD_NONBLOCK); sigprocmask(SIG_BLOCK, &mask, NULL); - source->func = func; + 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 add_source(loop, &source->base, WL_EVENT_READABLE, data); + return &source->base; } /** \cond INTERNAL */ @@ -829,24 +878,100 @@ 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]; + } + + if ((_ret[0] < 0) && (_ret[1] < 0)) { + fprintf(stderr, + "Error removing fd = %i from kqueue: %s\n", + source->fd, strerror(saved_errno)); + } - /* We need to explicitly remove the fd, since closing the fd - * isn't enough in case we've dup'ed the fd. */ - if (source->fd >= 0) { - epoll_ctl(loop->epoll_fd, EPOLL_CTL_DEL, source->fd, NULL); close(source->fd); source->fd = -1; - } + } else if (source->interface == &timer_source_interface) { + + /* + * There is only timer event source with fd = 1 which is used + * for all timer events. Generally we do not need to remove + * the event source from kqueue. + */ + if (source->fd >= 0) { + 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; + + if (ret < 0) { + fprintf(stderr, + "Error removing timer = %i from kqueue: %s\n", + source->fd, strerror(saved_errno)); + } + } - if (source->interface == &timer_source_interface && - source->fd != TIMER_REMOVED) { - /* Disarm the timer (and the loop's timerfd, if necessary), - * before removing its space in the loop timer heap */ - wl_event_source_timer_update(source, 0); - wl_timer_heap_unreserve(&loop->timers); - /* Set the fd field to to indicate that the timer should NOT - * be dispatched in `wl_event_loop_dispatch` */ - source->fd = TIMER_REMOVED; + if (source->fd != TIMER_REMOVED) { + /* Disarm the timer (and the loop's timerfd, if necessary), + * before removing its space in the loop timer heap */ + wl_event_source_timer_update(source, 0); + wl_timer_heap_unreserve(&loop->timers); + /* Set the fd field to to indicate that the timer should NOT + * be dispatched in `wl_event_loop_dispatch` */ + source->fd = TIMER_REMOVED; + } + } 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; + + if (ret < 0) { + fprintf(stderr, + "Error removing signal = %i from kqueue: %s\n", + source->fd, strerror(saved_errno)); + } + source->fd = -1; } wl_list_remove(&source->link); @@ -889,8 +1014,8 @@ wl_event_loop_create(void) if (loop == NULL) return NULL; - loop->epoll_fd = wl_os_epoll_create_cloexec(); - if (loop->epoll_fd < 0) { + loop->event_fd = wl_os_kqueue_create_cloexec(); + if (loop->event_fd < 0) { free(loop); return NULL; } @@ -925,22 +1050,21 @@ wl_event_loop_destroy(struct wl_event_lo wl_event_loop_process_destroy_list(loop); wl_timer_heap_release(&loop->timers); - close(loop->epoll_fd); + close(loop->event_fd); free(loop); } static bool post_dispatch_check(struct wl_event_loop *loop) { - struct epoll_event ep; + struct kevent ev; struct wl_event_source *source, *next; bool needs_recheck = false; - ep.events = 0; wl_list_for_each_safe(source, next, &loop->check_list, link) { int dispatch_result; - dispatch_result = source->interface->dispatch(source, &ep); + dispatch_result = source->interface->dispatch(source, &ev); if (dispatch_result < 0) { wl_log("Source dispatch function returned negative value!\n"); wl_log("This would previously accidentally suppress a follow-up dispatch\n"); @@ -994,19 +1118,25 @@ wl_event_loop_dispatch_idle(struct wl_ev WL_EXPORT int wl_event_loop_dispatch(struct wl_event_loop *loop, int timeout) { - struct epoll_event ep[32]; + struct kevent ev[64]; struct wl_event_source *source; int i, count; + struct timespec timeout_spec; bool has_timers = false; wl_event_loop_dispatch_idle(loop); - count = epoll_wait(loop->epoll_fd, ep, ARRAY_LENGTH(ep), timeout); + /* timeout is provided in milliseconds */ + timeout_spec.tv_sec = (time_t) (timeout / 1000); + timeout_spec.tv_nsec = (long) (timeout % 1000) * 1000000L; + + 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 = ep[i].data.ptr; + source = ev[i].udata; if (source == &loop->timers.base) has_timers = true; } @@ -1022,9 +1152,10 @@ wl_event_loop_dispatch(struct wl_event_l } for (i = 0; i < count; i++) { - source = ep[i].data.ptr; - if (source->fd != -1) - source->interface->dispatch(source, &ep[i]); + source = ev[i].udata; + if (source->fd != -1) { + source->interface->dispatch(source, &ev[i]); + } } wl_event_loop_process_destroy_list(loop); @@ -1055,7 +1186,7 @@ wl_event_loop_dispatch(struct wl_event_l WL_EXPORT int wl_event_loop_get_fd(struct wl_event_loop *loop) { - return loop->epoll_fd; + return loop->event_fd; } /** Register a destroy listener for an event loop context [FILE:1426:dragonfly/patch-src_wayland-os.c] --- src/wayland-os.c.orig 2023-04-04 07:58:31 UTC +++ src/wayland-os.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #ifdef HAVE_SYS_UCRED_H @@ -69,17 +69,19 @@ wl_os_socket_cloexec(int domain, int typ { int fd; +#ifdef SOCK_CLOEXEC fd = socket(domain, type | SOCK_CLOEXEC, protocol); if (fd >= 0) return fd; if (errno != EINVAL) return -1; +#endif fd = socket(domain, type, protocol); return set_cloexec_or_close(fd); } -#if defined(__FreeBSD__) +#if defined(__FreeBSD__) || defined(__DragonFly__) int wl_os_socket_peercred(int sockfd, uid_t *uid, gid_t *gid, pid_t *pid) { @@ -87,7 +89,7 @@ wl_os_socket_peercred(int sockfd, uid_t struct xucred ucred; len = sizeof(ucred); - if (getsockopt(sockfd, SOL_LOCAL, LOCAL_PEERCRED, &ucred, &len) < 0 || + if (getsockopt(sockfd, 0, LOCAL_PEERCRED, &ucred, &len) < 0 || ucred.cr_version != XUCRED_VERSION) return -1; *uid = ucred.cr_uid; @@ -189,19 +191,11 @@ wl_os_recvmsg_cloexec(int sockfd, struct } int -wl_os_epoll_create_cloexec(void) +wl_os_kqueue_create_cloexec(void) { int fd; -#ifdef EPOLL_CLOEXEC - fd = epoll_create1(EPOLL_CLOEXEC); - if (fd >= 0) - return fd; - if (errno != EINVAL) - return -1; -#endif - - fd = epoll_create(1); + fd = kqueue(); return set_cloexec_or_close(fd); } [FILE:327:dragonfly/patch-src_wayland-os.h] --- src/wayland-os.h.orig 2023-04-04 07:58:31 UTC +++ src/wayland-os.h @@ -42,7 +42,7 @@ ssize_t wl_os_recvmsg_cloexec(int sockfd, struct msghdr *msg, int flags); int -wl_os_epoll_create_cloexec(void); +wl_os_kqueue_create_cloexec(void); int wl_os_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen); [FILE:758:dragonfly/patch-src_wayland-server.c] --- src/wayland-server.c.orig 2023-04-04 07:58:31 UTC +++ src/wayland-server.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include @@ -1117,10 +1116,6 @@ wl_display_create(void) return NULL; } - display->terminate_efd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); - if (display->terminate_efd < 0) - goto err_eventfd; - display->term_source = wl_event_loop_add_fd(display->loop, display->terminate_efd, WL_EVENT_READABLE, @@ -1151,10 +1146,6 @@ wl_display_create(void) err_term_source: close(display->terminate_efd); -err_eventfd: - wl_event_loop_destroy(display->loop); - free(display); - return NULL; } static void [FILE:989:dragonfly/patch-tests_os-wrappers-test.c] --- tests/os-wrappers-test.c.orig 2023-04-04 07:58:31 UTC +++ tests/os-wrappers-test.c @@ -39,7 +39,6 @@ #include #include #include -#include #include "wayland-private.h" #include "test-runner.h" @@ -152,15 +151,7 @@ recvmsg(int sockfd, struct msghdr *msg, __attribute__ ((visibility("default"))) int epoll_create1(int flags) { - wrapped_calls_epoll_create1++; - - if (fall_back) { - wrapped_calls_epoll_create1++; /* epoll_create() not wrapped */ - errno = EINVAL; - return -1; - } - - return real_epoll_create1(flags); + return 0; } static void @@ -375,6 +366,7 @@ TEST(os_wrappers_recvmsg_cloexec_fallbac do_os_wrappers_recvmsg_cloexec(1); } +#if !defined(__DragonFly__) static void do_os_wrappers_epoll_create_cloexec(int n) { @@ -406,5 +398,6 @@ TEST(os_wrappers_epoll_create_cloexec_fa init_fallbacks(1); do_os_wrappers_epoll_create_cloexec(2); } +#endif /* FIXME: add tests for wl_os_accept_cloexec() */ [FILE:2916:dragonfly/patch-tests_test-runner.c] --- tests/test-runner.c.orig 2023-04-04 07:58:31 UTC +++ tests/test-runner.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -42,7 +43,9 @@ #ifdef HAVE_SYS_PROCCTL_H #include #elif defined(HAVE_SYS_PRCTL_H) +#ifndef __DragonFly__ #include +#endif #ifndef PR_SET_PTRACER # define PR_SET_PTRACER 0x59616d61 #endif @@ -276,17 +279,22 @@ is_debugger_attached(void) close(pipefd[0]); if (buf == '-') _exit(1); +#ifndef __DragonFly__ if (ptrace(PTRACE_ATTACH, ppid, NULL, NULL) != 0) _exit(1); +#endif if (!waitpid(-1, NULL, 0)) _exit(1); +#ifndef __DragonFly__ ptrace(PTRACE_CONT, NULL, NULL); ptrace(PTRACE_DETACH, ppid, NULL, NULL); +#endif _exit(0); } else { close(pipefd[0]); /* Enable child to ptrace the parent process */ +#ifndef __DragonFly__ rc = prctl(PR_SET_PTRACER, pid); if (rc != 0 && errno != EINVAL) { /* An error prevents us from telling if a debugger is attached. @@ -300,6 +308,7 @@ is_debugger_attached(void) /* Signal to client that parent is ready by passing '+' */ write(pipefd[1], "+", 1); } +#endif close(pipefd[1]); waitpid(pid, &status, 0); @@ -315,18 +324,16 @@ int main(int argc, char *argv[]) const struct test *t; pid_t pid; int total, pass; +#ifdef __DragonFly__ + int status; +#else siginfo_t info; +#endif if (isatty(fileno(stderr))) is_atty = 1; - - if (is_debugger_attached()) { - fd_leak_check_enabled = 0; - timeouts_enabled = 0; - } else { - fd_leak_check_enabled = !getenv("WAYLAND_TEST_NO_LEAK_CHECK"); - timeouts_enabled = !getenv("WAYLAND_TEST_NO_TIMEOUTS"); - } + fd_leak_check_enabled = !getenv("WAYLAND_TEST_NO_LEAK_CHECK"); + timeouts_enabled = !getenv("WAYLAND_TEST_NO_TIMEOUTS"); if (argc == 2 && strcmp(argv[1], "--help") == 0) usage(argv[0], EXIT_SUCCESS); @@ -358,6 +365,12 @@ int main(int argc, char *argv[]) if (pid == 0) run_test(t); /* never returns */ +#ifdef __DragonFly__ + if (wait(&status)) { + fprintf(stderr, "waitid failed: %m\n"); + abort(); + } +#else if (waitid(P_PID, pid, &info, WEXITED)) { stderr_set_color(RED); fprintf(stderr, "waitid failed: %s\n", @@ -366,6 +379,21 @@ int main(int argc, char *argv[]) abort(); } +#endif + + fprintf(stderr, "test \"%s\":\t", t->name); +#ifdef __DragonFly__ + if (WIFEXITED(status)) { + fprintf(stderr, "exit status %d", WEXITSTATUS(status)); + if (WEXITSTATUS(status) == EXIT_SUCCESS) + success = 1; + break; + } else if (WIFSIGNALED(status) || WCOREDUMP(status)) { + fprintf(stderr, "signal %d", WTERMSIG(status)); + break; + } +#else + switch (info.si_code) { case CLD_EXITED: @@ -390,6 +418,7 @@ int main(int argc, char *argv[]) break; } +#endif if (success) { pass++;