jiixyj / epoll-shim Goto Github PK
View Code? Open in Web Editor NEWsmall epoll implementation using kqueue; includes all features needed for libinput/libevdev
License: MIT License
small epoll implementation using kqueue; includes all features needed for libinput/libevdev
License: MIT License
Hi!
I'm not sure that this is the right place to ask for help, so please let me know if I need to ask somewhere else.
I'm using Poudriere to build my ports automatically. I'm using the latest head of 12.01 port tree. The devel/libepoll-shim port build fails with linker error.
First these 2 warnings:
[12/44] /usr/local/libexec/ccache/cc -Depoll_shim_EXPORTS -Isrc -I/wrkdirs/usr/ports/devel/libepoll-shim/work/epoll-shim-c8491d3/include -I/wrkdirs/usr/ports/devel/libepoll-shim/work/epoll-shim-c8491d3/include/eventfd -I/wrkdirs/usr/ports/devel/libepoll-shim/work/epoll-shim-c8491d3/external/queue-macros/include -I/wrkdirs/usr/ports/devel/libepoll-shim/work/epoll-shim-c8491d3/external/tree-macros/include -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fPIC -fvisibility=hidden -pthread -std=gnu11 -MD -MT src/CMakeFiles/epoll-shim.dir/signalfd_ctx.c.o -MF src/CMakeFiles/epoll-shim.dir/signalfd_ctx.c.o.d -o src/CMakeFiles/epoll-shim.dir/signalfd_ctx.c.o -c /wrkdirs/usr/ports/devel/libepoll-shim/work/epoll-shim-c8491d3/src/signalfd_ctx.c
/wrkdirs/usr/ports/devel/libepoll-shim/work/epoll-shim-c8491d3/src/signalfd_ctx.c:60:6: warning: implicit declaration of function 'sigandset' is invalid in C99 [-Wimplicit-function-declaration]
sigandset(&pending_sigs, &pending_sigs, &signalfd->sigs) < 0) {
^
/wrkdirs/usr/ports/devel/libepoll-shim/work/epoll-shim-c8491d3/src/signalfd_ctx.c:64:18: warning: implicit declaration of function 'sigisemptyset' is invalid in C99 [-Wimplicit-function-declaration]
*has_pending = !sigisemptyset(&pending_sigs);
^
2 warnings generated.
then:
[21/44] : && /usr/local/libexec/ccache/cc -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fstack-protector-strong test/CMakeFiles/tst-timerfd.dir/tst-timerfd.c.o -o test/tst-timerfd -Wl,-rpath,/wrkdirs/usr/ports/devel/libepoll-shim/work/.build/src:/wrkdirs/usr/ports/devel/libepoll-shim/work/.build/external/microatf/src src/libepoll-shim.so.0 external/microatf/src/libmicroatf-c.so -pthread && cd /wrkdirs/usr/ports/devel/libepoll-shim/work/.build/test && /usr/local/bin/cmake -D TEST_TARGET=tst-timerfd -D TEST_EXECUTABLE=/wrkdirs/usr/ports/devel/libepoll-shim/work/.build/test/tst-timerfd -D TEST_EXECUTOR= -D TEST_PROPERTIES= -D TEST_CONFIG_VARIABLES= -D TRANSLATE_SIGNAL=/wrkdirs/usr/ports/devel/libepoll-shim/work/.build/external/microatf/src/microatf-translate-signal -D CTEST_FILE=/wrkdirs/usr/ports/devel/libepoll-shim/work/.build/test/tst-timerfd_tests.cmake -D BINARY_DIR=/wrkdirs/usr/ports/devel/libepoll-shim/work/.build/test -D TEST_RUN_SCRIPT=/wrkdirs/usr/ports/devel/libepoll-shim/work/epoll-shim-c8491d3/external/microatf/cmake/ATFRunTest.cmake -P /wrkdirs/usr/ports/devel/libepoll-shim/work/epoll-shim-c8491d3/external/microatf/cmake/ATFTestAddTests.cmake
FAILED: test/tst-timerfd test/tst-timerfd_tests.cmake
: && /usr/local/libexec/ccache/cc -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fstack-protector-strong test/CMakeFiles/tst-timerfd.dir/tst-timerfd.c.o -o test/tst-timerfd -Wl,-rpath,/wrkdirs/usr/ports/devel/libepoll-shim/work/.build/src:/wrkdirs/usr/ports/devel/libepoll-shim/work/.build/external/microatf/src src/libepoll-shim.so.0 external/microatf/src/libmicroatf-c.so -pthread && cd /wrkdirs/usr/ports/devel/libepoll-shim/work/.build/test && /usr/local/bin/cmake -D TEST_TARGET=tst-timerfd -D TEST_EXECUTABLE=/wrkdirs/usr/ports/devel/libepoll-shim/work/.build/test/tst-timerfd -D TEST_EXECUTOR= -D TEST_PROPERTIES= -D TEST_CONFIG_VARIABLES= -D TRANSLATE_SIGNAL=/wrkdirs/usr/ports/devel/libepoll-shim/work/.build/external/microatf/src/microatf-translate-signal -D CTEST_FILE=/wrkdirs/usr/ports/devel/libepoll-shim/work/.build/test/tst-timerfd_tests.cmake -D BINARY_DIR=/wrkdirs/usr/ports/devel/libepoll-shim/work/.build/test -D TEST_RUN_SCRIPT=/wrkdirs/usr/ports/devel/libepoll-shim/work/epoll-shim-c8491d3/external/microatf/cmake/ATFRunTest.cmake -P /wrkdirs/usr/ports/devel/libepoll-shim/work/epoll-shim-c8491d3/external/microatf/cmake/ATFTestAddTests.cmake
ld: error: src/libepoll-shim.so.0: undefined reference to sigandset
ld: error: src/libepoll-shim.so.0: undefined reference to sigisemptyset
cc: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
*** Error code 1
Environment details:
=>> Building devel/libepoll-shim
build started at Tue Mar 9 22:32:03 CET 2021
port directory: /usr/ports/devel/libepoll-shim
package name: libepoll-shim-0.0.20210213
building for: FreeBSD 1201amd64-head-job-01 12.1-RELEASE-p10 FreeBSD 12.1-RELEASE-p10 amd64
maintained by: [email protected]
Makefile ident: $FreeBSD: head/devel/libepoll-shim/Makefile 566000 2021-02-18 22:06:57Z jbeich $
Poudriere version: 3.3.6
Host OSVERSION: 1202000
Jail OSVERSION: 1201000
Job Id: 01
---Begin Environment---
SHELL=/bin/csh
OSVERSION=1201000
UNAME_v=FreeBSD 12.1-RELEASE-p10
UNAME_r=12.1-RELEASE-p10
BLOCKSIZE=K
MAIL=/var/mail/root
STATUS=1
HOME=/root
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin
LOCALBASE=/usr/local
USER=root
LIBEXECPREFIX=/usr/local/libexec/poudriere
POUDRIERE_VERSION=3.3.6
MASTERMNT=/usr/local/poudriere/data/.m/1201amd64-head/ref
POUDRIERE_BUILD_TYPE=bulk
PACKAGE_BUILDING=yes
SAVED_TERM=unknown
PWD=/usr/local/poudriere/data/.m/1201amd64-head/ref/.p/pool
P_PORTS_FEATURES=FLAVORS SELECTED_OPTIONS
MASTERNAME=1201amd64-head
SCRIPTPREFIX=/usr/local/share/poudriere
OLDPWD=/usr/local/poudriere/data/.m/1201amd64-head/ref/.p
SCRIPTPATH=/usr/local/share/poudriere/bulk.sh
POUDRIEREPATH=/usr/local/bin/poudriere
---End Environment---
Any advise what can be wrong?
Thanks.
I'd like to create a map from fd to the context objects for faster lookup. Currently, the context objects are stored in linked lists with a worst case lookup of O(n).
I also like to have some persistent state for epoll instances in the context object. This can be used to replace two ugly hacks:
Since this landed in Firefox, it started using an eventfd
for a shared reference count thing, and it's trying to pass it over a socket every time there's a video frame decoded by hardware (vaapi).. and it fails because our eventfds fail the (fp->f_ops->fo_flags & DFLAG_PASSABLE)
check in kern/uipc_usrreq.c
and the sendmsg
fails with EOPNOTSUPP
. :(
[Child 24571, Chrome_ChildThread] WARNING: pipe error: Operation not supported: file /home/greg/src/hg.mozilla.org/mozilla-unified/ipc/chromium/src/chrome/common/ipc_channel_posix.cc, line 696
I do have an easy workaround for Firefox (just ifdef'ing out refCountFDs.AppendElement(ipc::FileDescriptor(mGlobalRefCountFd))
) but this is quite a surprising problem in general / in theory!
/cc @jbeich
pipewire master branch started using timerfd_gettime
function, which is #if 0
ed for some reason. If it is hard to implement, can we at least provide a stub for it?
While there, timerfd.h
is also not defining TFD_TIMER_CANCEL_ON_SET
, which is used in timerfd_settime
call.
I'd like to port this library over to NetBSD.
Compiling fuzzel brought me here to satisfy one of its dependency (epoll-shim / epoll-shim.pc) , then I compiled epoll-shim and succesfully compiled but I can't find "epoll-shim.pc" though I know there is a "epollshim.pc.cmakein" . Any advice?
[ 62%] Linking C executable pipe-test
[ 62%] Built target pipe-test
[ 65%] Building C object test/CMakeFiles/socketpair-test.dir/socketpair-test.c.o
[ 67%] Linking C executable socketpair-test
[ 67%] Built target socketpair-test
[ 69%] Building C object test/CMakeFiles/tst-epoll.dir/tst-epoll.c.o
[ 72%] Linking C executable tst-epoll
[ 72%] Built target tst-epoll
[ 74%] Building C object test/CMakeFiles/tst-timerfd.dir/tst-timerfd.c.o
[ 76%] Linking C executable tst-timerfd
[ 76%] Built target tst-timerfd
[ 79%] Building C object test/CMakeFiles/rwlock-test.dir/rwlock-test.c.o
[ 81%] Linking C executable rwlock-test
[ 81%] Built target rwlock-test
[ 83%] Building C object test/CMakeFiles/epoll-include-test.dir/epoll-include-test.c.o
[ 86%] Linking C executable epoll-include-test
[ 86%] Built target epoll-include-test
[ 88%] Building C object test/CMakeFiles/epoll-include-c89-test.dir/epoll-include-c89-test.c.o
[ 90%] Linking C executable epoll-include-c89-test
[ 90%] Built target epoll-include-c89-test
[ 93%] Building C object test/CMakeFiles/fcntl-warning.dir/fcntl-warning.c.o
[ 95%] Linking C executable fcntl-warning
[ 95%] Built target fcntl-warning
[ 97%] Building C object test/CMakeFiles/dlsym-fail.dir/epoll-include-test.c.o
[100%] Linking C executable dlsym-fail
[100%] Built target dlsym-fail
➜ build git:(master) git pull
Already up to date.
➜ build git:(master) cmake --build . --target install
gmake: *** No rule to make target 'install'. Stop.
➜ build git:(master)
infact there's no install:
properties Makefile
have
➜ build git:(master) make install
make: *** No rule to make target 'install'. Stop.
➜ build git:(master)
FreeBSD >= 13.1 added CLOCK_BOOTTIME
but it appears to work differently from what consumers expect.
$ pkg install git meson pkgconf libepoll-shim json-glib
$ git clone https://gitlab.gnome.org/guidog/gmobile.git
$ git -C gmobile fetch origin merge-requests/11/head
$ git -C gmobile merge FETCH_HEAD
$ meson setup gmobile_build gmobile
$ meson compile -C gmobile_build
$ meson test -C gmobile_build timeout
[...]
1/1 timeout TIMEOUT 30.02s killed by signal 15 SIGTERM
$ gmobile_build/examples/gm-timeout -s 1
** Message: 19:01:38.768: Arming timer with 1 seconds
** Message: 19:01:38.769: Now 19:01:38
^T
load: 0.08 cmd: gm-timeout 9389 [select] 40.63r 0.00u 0.00s 0% 6152k
Defining close
and friends without arguments has border cases with include order.
Maybe it has a sense to change the definitions from #define close epoll_shim_close
to #define close(fd) epoll_shim_close(fd)
? But this change breaks function pointer assignments. What do you think? I can create pull request this change has sense for you.
Please see for details https://codeberg.org/dnkl/foot/issues/500#issuecomment-197764
Regressed by 7fff1fc. -Wimplicit-function-declaration
regressed by db0f2de + b3be554.
$ cc --version
FreeBSD clang version 8.0.0 (tags/RELEASE_800/final 356365) (based on LLVM 8.0.0)
Target: x86_64-unknown-freebsd11.3
Thread model: posix
InstalledDir: /usr/bin
$ pkg install cmake ninja
$ cmake -GNinja .
$ ninja
[5/14] Building C object test/CMakeFiles/kqueue-state.dir/kqueue-state.c.o
FAILED: test/CMakeFiles/kqueue-state.dir/kqueue-state.c.o
/usr/bin/cc -Itest/../include -std=gnu99 -MD -MT test/CMakeFiles/kqueue-state.dir/kqueue-state.c.o -MF test/CMakeFiles/kqueue-state.dir/kqueue-state.c.o.d -o test/CMakeFiles/kqueue-state.dir/kqueue-state.c.o -c test/kqueue-state.c
In file included from test/kqueue-state.c:1:
/usr/include/sys/event.h:75:2: error: unknown type name 'uintptr_t'
uintptr_t ident; /* identifier for this event */
^
/usr/include/sys/event.h:77:2: error: unknown type name 'u_short'; did you mean 'short'?
u_short flags; /* action flags for kqueue */
^
/usr/include/sys/event.h:78:2: error: unknown type name 'u_int'
u_int fflags; /* filter flag value */
^
/usr/include/sys/event.h:79:2: error: unknown type name 'intptr_t'
intptr_t data; /* filter data value */
^
4 errors generated.
[6/14] Building C object test/CMakeFiles/many-timers.dir/many-timers.c.o
FAILED: test/CMakeFiles/many-timers.dir/many-timers.c.o
/usr/bin/cc -Iinclude -std=gnu99 -MD -MT test/CMakeFiles/many-timers.dir/many-timers.c.o -MF test/CMakeFiles/many-timers.dir/many-timers.c.o.d -o test/CMakeFiles/many-timers.dir/many-timers.c.o -c test/many-timers.c
In file included from test/many-timers.c:1:
/usr/include/sys/event.h:75:2: error: unknown type name 'uintptr_t'
uintptr_t ident; /* identifier for this event */
^
/usr/include/sys/event.h:77:2: error: unknown type name 'u_short'; did you mean 'short'?
u_short flags; /* action flags for kqueue */
^
/usr/include/sys/event.h:78:2: error: unknown type name 'u_int'
u_int fflags; /* filter flag value */
^
/usr/include/sys/event.h:79:2: error: unknown type name 'intptr_t'
intptr_t data; /* filter data value */
^
test/many-timers.c:65:3: warning: implicit declaration of function 'timespecsub' is invalid in C99 [-Wimplicit-function-declaration]
timespecsub(&e, &b, &e);
^
test/many-timers.c:88:3: warning: implicit declaration of function 'timespecsub' is invalid in C99 [-Wimplicit-function-declaration]
timespecsub(&e, &b, &e);
^
test/many-timers.c:123:3: warning: implicit declaration of function 'timespecsub' is invalid in C99 [-Wimplicit-function-declaration]
timespecsub(&e, &b, &e);
^
test/many-timers.c:175:3: warning: implicit declaration of function 'timespecsub' is invalid in C99 [-Wimplicit-function-declaration]
timespecsub(&e, &b, &e);
^
test/many-timers.c:215:3: warning: implicit declaration of function 'timespecsub' is invalid in C99 [-Wimplicit-function-declaration]
timespecsub(&e, &b, &e);
^
5 warnings and 4 errors generated.
[8/14] Building C object test/CMakeFiles/epoll-test.dir/epoll-test.c.o
ninja: build stopped: subcommand failed.
Regressed by 3cf8deb. wlroots examples fail to build due to incomplete includes:
FAILED: examples/c590b3c@@input-method@exe/input-method.c.o
cc -Iexamples/c590b3c@@input-method@exe -Iexamples -I../examples -Iprotocol -I/usr/local/include -I/usr/local/include/libepoll-shim -I/usr/local/lib/libffi-3.2.1/include -Xclang -fcolor-diagnostics -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Werror -std=c11 -g -DWLR_USE_UNSTABLE -Wundef -Wmissing-include-dirs -Wold-style-definition -Wpointer-arith -Winit-self -Wstrict-prototypes -Wendif-labels -Wstrict-aliasing=2 -Woverflow -Wmissing-prototypes -Wno-missing-braces -Wno-missing-field-initializers -Wno-unused-parameter '-DWLR_REL_SRC_DIR="../"' -Wno-missing-field-initializers -Wno-missing-braces -DLIBINPUT_MAJOR=1 -DLIBINPUT_MINOR=15 -DLIBINPUT_PATCH=5 '-DICONDIR="/usr/local/share/icons"' -MD -MQ 'examples/c590b3c@@input-method@exe/input-method.c.o' -MF 'examples/c590b3c@@input-method@exe/input-method.c.o.d' -o 'examples/c590b3c@@input-method@exe/input-method.c.o' -c ../examples/input-method.c
In file included from ../examples/input-method.c:8:
/usr/local/include/libepoll-shim/sys/epoll.h:70:60: error: unknown type name 'sigset_t'
int epoll_pwait(int, struct epoll_event *, int, int, const sigset_t *);
^
1 error generated.
Test case:
$ cc a.c $(pkg-config --cflags --libs epoll-shim)
In file included from a.c:2:
/usr/local/include/libepoll-shim/sys/epoll.h:70:60: error: unknown type name 'sigset_t'
int epoll_pwait(int, struct epoll_event *, int, int, const sigset_t *);
^
1 error generated.
$ cat a.c
#define _POSIX_C_SOURCE 200809L
#include <sys/epoll.h>
int main() {}
FreeBSD added support for POLLRDHUP
recently in freebsd/freebsd-src@3aaaa2e.
Figure out what's needed in epoll-shim to support this, make sure the tests still work, etc. One difference that springs to mind is that the value of POLLRDHUP
is 0x4000
while the musl header defines EPOLLRDHUP
to be 0x2000
. So the epoll__poll_flags
test will fail for sure.
Regressed by 973b85c
$ pkg install sway
$ WLR_BACKENDS=headless WLR_RENDERER=pixman sway -dc /dev/null
00:00:00.000 [sway/main.c:343] Sway version 1.7
00:00:00.000 [sway/main.c:344] wlroots version 0.15.1-g29938b74251e
00:00:00.001 [sway/main.c:120] FreeBSD 130amd64-default ...
00:00:00.001 [sway/main.c:108] LD_LIBRARY_PATH=
00:00:00.001 [sway/main.c:108] LD_PRELOAD=
00:00:00.001 [sway/main.c:108] PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
00:00:00.001 [sway/main.c:108] SWAYSOCK=
00:00:00.001 [sway/server.c:50] Preparing Wayland server initialization
Segmentation fault
(lldb) bt
* thread #1, name = 'sway', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)
* frame #0: 0x0000000000000000
frame #1: 0x0000000833b3fbe1 libepoll-shim.so.0`real_fcntl(fd=3, cmd=1) at wrap.c:108:11
frame #2: 0x0000000833b352cd libepoll-shim.so.0`compat_kqueue1_impl(fd_out=0x000000082126ecc4, flags=1048576) at compat_kqueue1.c:35:13
frame #3: 0x0000000833b351ef libepoll-shim.so.0`compat_kqueue1(flags=1048576) at compat_kqueue1.c:71:7
frame #4: 0x0000000833b35c58 libepoll-shim.so.0`epoll_shim_ctx_create_desc(epoll_shim_ctx=0x0000000833b44f98, flags=1048576, fd=0x000000082126ed6c, desc=0x000000082126ed60) at epoll_shim_ctx.c:245:11
frame #5: 0x0000000833b38268 libepoll-shim.so.0`epoll_create_impl(fd_out=0x000000082126edb4, flags=1048576) at epoll.c:73:7
frame #6: 0x0000000833b37a0f libepoll-shim.so.0`epoll_create_common(flags=1048576) at epoll.c:103:7
frame #7: 0x0000000833b37abb libepoll-shim.so.0`epoll_create1(flags=1048576) at epoll.c:131:9
frame #8: 0x000000082977dc02 libwayland-server.so.0`wl_os_epoll_create_cloexec at wayland-os.c:197:7
frame #9: 0x0000000829779213 libwayland-server.so.0`wl_event_loop_create at event-loop.c:892:19
frame #10: 0x00000008297747bc libwayland-server.so.0`wl_display_create at wayland-server.c:1072:18
frame #11: 0x000000000023dde6 sway`server_privileged_prepare(server=0x00000000002a5c40) at server.c:51:23
frame #12: 0x000000000023d454 sway`main(argc=3, argv=0x000000082126ef70) at main.c:376:7
frame #13: 0x000000000022c540 sway`_start(ap=<unavailable>, cleanup=<unavailable>) at crt1_c.c:75:7
(lldb) f 8
frame #8: 0x000000082977dc02 libwayland-server.so.0`wl_os_epoll_create_cloexec at wayland-os.c:197:7
194 int fd;
195
196 #ifdef EPOLL_CLOEXEC
-> 197 fd = epoll_create1(EPOLL_CLOEXEC);
198 if (fd >= 0)
199 return fd;
200 if (errno != EINVAL)
# When "sway" was already started before epoll-shim upgrade
$ pkg install wayland-utils
$ wayland-info
Segmentation fault
(lldb) bt
* thread #1, name = 'wayland-info', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)
* frame #0: 0x0000000000000000
frame #1: 0x000000082422cbe1 libepoll-shim.so.0`real_fcntl(fd=4, cmd=1) at wrap.c:108:11
frame #2: 0x0000000824223e5a libepoll-shim.so.0`epoll_shim_fcntl(fd=4, cmd=1) at epoll_shim_ctx.c:809:3
frame #3: 0x0000000822e4a400 libwayland-client.so.0`set_cloexec_or_close(fd=4) at wayland-os.c:53:10
frame #4: 0x0000000822e4a707 libwayland-client.so.0`recvmsg_cloexec_fallback(sockfd=3, msg=0x000000082119da60, flags=128) at wayland-os.c:162:10
frame #5: 0x0000000822e4a5e1 libwayland-client.so.0`wl_os_recvmsg_cloexec(sockfd=3, msg=0x000000082119da60, flags=128) at wayland-os.c:188:9
frame #6: 0x0000000822e470cc libwayland-client.so.0`wl_connection_read(connection=0x0000000825f2efc0) at connection.c:360:9
frame #7: 0x0000000822e44f2d libwayland-client.so.0`read_events(display=0x0000000825f2b000) at wayland-client.c:1612:11
frame #8: 0x0000000822e44e83 libwayland-client.so.0`wl_display_read_events(display=0x0000000825f2b000) at wayland-client.c:1717:8
frame #9: 0x0000000822e44d8c libwayland-client.so.0`wl_display_dispatch_queue(display=0x0000000825f2b000, queue=0x0000000825f2b0d0) at wayland-client.c:1956:6
frame #10: 0x0000000822e44980 libwayland-client.so.0`wl_display_roundtrip_queue(display=0x0000000825f2b000, queue=0x0000000825f2b0d0) at wayland-client.c:1370:9
frame #11: 0x0000000822e44e02 libwayland-client.so.0`wl_display_roundtrip(display=0x0000000825f2b000) at wayland-client.c:1399:9
frame #12: 0x0000000000205565 wayland-info`main(argc=1, argv=0x000000082119dd50) at wayland-info.c:1921:3
frame #13: 0x0000000000205280 wayland-info`_start(ap=<unavailable>, cleanup=<unavailable>) at crt1_c.c:75:7
(lldb) f 3
frame #3: 0x0000000822e4a400 libwayland-client.so.0`set_cloexec_or_close(fd=4) at wayland-os.c:53:10
50 if (fd == -1)
51 return -1;
52
-> 53 flags = fcntl(fd, F_GETFD);
54 if (flags == -1)
55 goto err;
56
In src/epoll.c at line 293, EVFILT_WRITE
registration EINVAL
errors are ignored. If you register an fd, and this happens, you won't be able to deregister it, because trying to remove the nonexistent EVFILT_WRITE
filter will result in error ENOENT
, and epoll_ctl
will return -1 at line 299.
I have replaced line 293 with the following:
if (i == 1 && (kev[i].data == EINVAL || kev[i].data == ENOENT)) {
The reason I opened an issue, and not sent a pull request is that I'm not 100% sure if this is the correct thing to do, but it seems to work with sway now.
On macos branch
The following tests FAILED:
123 - timerfd-root-test.timerfd_root__zero_read_on_abs_realtime (Failed)
124 - timerfd-root-test.timerfd_root__read_on_abs_realtime_no_interval (Failed)
125 - timerfd-root-test.timerfd_root__cancel_on_set (Failed)
126 - timerfd-root-test.timerfd_root__cancel_on_set_init (Failed)
127 - timerfd-root-test.timerfd_root__clock_change_notification (Failed)
128 - timerfd-root-test.timerfd_root__advance_time_no_cancel (Failed)
129 - timerfd-root-test-interpose.timerfd_root__zero_read_on_abs_realtime (Failed)
130 - timerfd-root-test-interpose.timerfd_root__read_on_abs_realtime_no_interval (Failed)
131 - timerfd-root-test-interpose.timerfd_root__cancel_on_set (Failed)
132 - timerfd-root-test-interpose.timerfd_root__cancel_on_set_init (Failed)
133 - timerfd-root-test-interpose.timerfd_root__clock_change_notification (Failed)
134 - timerfd-root-test-interpose.timerfd_root__advance_time_no_cancel (Failed)
Errors while running CTest
They actually passed the tests, marked as failed because file descriptors leaks (or they haven't been closed after tests).
I guess @CMAKE_INSTALL_INCLUDEDIR@
already includes /libepoll-shim
because the result is
[…]
includedir=${prefix}/include/libepoll-shim
[…]
Cflags: -I${includedir}/libepoll-shim
Hi,
following the installation instructions from README.md results in:
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo
CMake Error at test/CMakeLists.txt:20 (add_library):
add_library cannot create target "epoll-shim" because another target with
the same name already exists. The existing target is a shared library
created in source directory "/home/da/src/epoll-shim/src". See
documentation for policy CMP0002 for more details.
I was wondering why I couldn't launch new Wayland clients (the compositor would return the "no memory" error) when working very actively on stuff.. and DTrace led me to timerfd
creation failing.
Looks like this timerfd
implementation creates one POSIX timer and one thread per timer (btw, threads should be named, I just realized where all the threads in my compositor came from.. also looks like one thread should be enough, signal info includes a unique ID per timer).
And.. turns out you can only create TIMER_MAX
timers, which is defined as 32 in sys/timers.h
:D
I'm not sure what's the right solution. Looks like timer limit should be increased in the kernel since the POSIX timer limit on Linux is relatively huge. I just created FreeBSD bug 238675 for this.
But maybe there should be a fallback to userspace thread based timing?
With wayland 1.18 there's a new event loop update that would've fixed the same issue as #8 :D but now there's 100% CPU consumption in wlroots based compositors at least. Here's a dtrace flamegraph, lots of time spent in poll
, kevent
and ktimer_settime
…
This would be required for pipewire
Currently, timerfd_gettime
is only a stub.
Hello,
I was trying out Wayland on HardenedBSD 12.0-CURRENT the other day, and stumbled upon an error that chase me down the rabbit hole quite a bit: both Weston and rootston (from wlroots) was terminated by SIGUSR1
when I tried to use Xwayland.
I started debugging it using rootston, and observed the following: SIGUSR1
signals are blocked, and a custom signal handler is installed, so receiving a SIGUSR1
should not terminate the application. Eventually it turned out that the timerfd_create
function called from wl_event_loop_add_timer
somehow cancels out the signal block. By "cancels out" I mean that SIGUSR1
is still on the sigprocmask, but the program lets the signal through anyways, and the custom handler is never called. To simplify the debugging process, I wrote this PoC:
#include <signal.h>
#include <sys/timerfd.h>
int main(int argc, char** argv)
{
timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
sigset_t _sigset;
sigemptyset(&_sigset);
sigaddset(&_sigset, SIGUSR1);
sigprocmask(SIG_BLOCK, &_sigset, NULL);
kill(getpid(), SIGUSR1);
while (1) sleep(1);
return 0;
}
This program should run indefinitely, but terminates instantly:
[0x00 wayland-sandbox]$ cc -I/usr/local/include -I/usr/local/include/libepoll-shim -L/usr/local/lib test.c -o test -lepoll-shim -lpthread -lrt
[0x00 wayland-sandbox]$ ./test
zsh: user-defined signal 1 ./test
[0x00 wayland-sandbox]$
I have tried to extract the minimum code from timerfd_create
that still triggers this behaviour, and came up with this:
#include <signal.h>
#include <stdio.h>
#include <sys/timerfd.h>
#include <sys/event.h>
#include <pthread.h>
#include <pthread_np.h>
static void *
worker_function(void *arg)
{
struct kevent kev;
EV_SET(&kev, 0, EVFILT_USER, 0, NOTE_TRIGGER, 0,
(void *)(intptr_t)pthread_getthreadid_np());
(void)kevent((int)arg, &kev, 1, NULL, 0, NULL);
return NULL;
}
int main(int argc, char** argv)
{
pthread_t worker;
int fd = kqueue();
struct kevent kev;
EV_SET(&kev, 0, EVFILT_USER, EV_ADD | EV_CLEAR, 0, 0, 0);
kevent(fd, &kev, 1, NULL, 0, NULL);
pthread_create(&worker, NULL, worker_function, (void*)(intptr_t)fd);
//kevent(fd, NULL, 0, &kev, 1, NULL); /* SIGUSR1 block working */
sigset_t _sigset;
sigemptyset(&_sigset);
sigaddset(&_sigset, SIGUSR1);
sigprocmask(SIG_BLOCK, &_sigset, NULL);
kill(getpid(), SIGUSR1);
kevent(fd, NULL, 0, &kev, 1, NULL); /* SIGUSR1 block not working */
while (1) sleep(1);
return 0;
}
This terminates the same way the previous one, but if I put the kevent
call right after pthread_create
, it works as expected. I have tried some other modifications (e.g. not using threads), but results were not conclusive to me, and I think I have reached a point where some help is needed.
All in all, the culprit seems to be timerfd_create
, but I am not really sure if this is a bug in epoll-shim, Wayland, kqueue, something else, or is it just me missing something, but I decided to post it here before trying to dig any deeper - maybe the problem is obvious to you.
One more thing: I have tried the above code pieces on a fresh 11.1-RELEASE too, so this behaviour is not caused by either Hardened, or -CURRENT. I have also tried the first one on Linux (Kali Linux with 4.12 kernel), and it works as expected (does not terminate).
Cheers,
sghctoma
On Makefile,
CFLAGS+= -I${.CURDIR}/include -Weverything -Wno-missing-prototypes -Wno-padded -Wno-missing-variable-declarations -Wno-thread-safety-analysis
building with GCC:
--- src/epoll.o ---
cc -pipe -O2 -fno-strict-aliasing -I/construction/devel/libepoll-shim/epoll-shim-c04b26b/include -Weverything -Wno-missing-prototypes -Wno-padded -Wno-missing-variable-declarations -Wno-thread-safety-analysis -std=gnu99 -c src/epoll.c -o src/epoll.o
cc: error: unrecognized command line option '-Weverything'
Hello,
Commit 7a36cd3 introduced a change to return EPOLLHUP
on not yet connected stream sockets. Is it really the desirable behaviour? As per the Linux man page, epoll
should share the same semantics as poll
when used in the default level-triggered mode, and poll
does not do this. The Linux version of epoll
does not do it either. Consider the following program:
#include <stdio.h>
#include <stdlib.h>
#ifdef __FreeBSD__
#include <malloc_np.h>
#endif
#include <unistd.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
int main(int argc, char** argv)
{
struct sockaddr_un *sockaddr = malloc(sizeof(struct sockaddr_un));
sockaddr->sun_family = AF_UNIX;
int path_size = sizeof(sockaddr->sun_path);
snprintf(sockaddr->sun_path, path_size, "/tmp/epoll-test.sock");
unlink(sockaddr->sun_path);
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
bind(sock, (struct sockaddr *)sockaddr, sizeof(*sockaddr));
listen(sock, 3);
int epoll_fd = epoll_create1(EPOLL_CLOEXEC);
struct epoll_event ep;
memset(&ep, 0, sizeof ep);
ep.events = EPOLLIN;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sock, &ep);
struct epoll_event events[1] = {0};
epoll_wait(epoll_fd, events, 1, -1);
printf("ep[0].events=%d\n", events[0].events);
}
This will block until an incoming connection (EPOLLIN
event) on Linux, but return immediately on FreeBSD, becauase an EPOLLHUP
was received. The equivalent program that uses poll
blocks on both Linux and FreeBSD:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <poll.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
int main(int argc, char** argv)
{
struct sockaddr_un *sockaddr = malloc(sizeof(struct sockaddr_un));
sockaddr->sun_family = AF_UNIX;
int path_size = sizeof(sockaddr->sun_path);
snprintf(sockaddr->sun_path, path_size, "/tmp/epoll-test.sock");
unlink(sockaddr->sun_path);
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
bind(sock, (struct sockaddr *)sockaddr, sizeof(*sockaddr));
listen(sock, 3);
struct pollfd fds[1];
fds[0].fd = sock;
fds[0].events = POLLIN;
int p = poll(fds, 1, -1);
printf("fds[0].revents=%d\n", fds[0].revents);
}
This behaviour causes trouble with sway, because it waits for a WL_EVENT_READABLE
Wayland event to detect incoming connections on a socket (it is fired when an EPOLLIN
event happens on the socket), and gets EPOLLHUP
immediately instead.
Hello.
Here is my situation:
make test
===> Testing for libepoll-shim-0.0.20200602
Test project /usr/ports/devel/libepoll-shim/work/.build
Total Test time (real) = 196.91 secThe following tests did not run:
23 - epoll-test.epoll__epollhup_on_fresh_socket (Skipped)
25 - epoll-test.epoll__epollpri (Skipped)The following tests FAILED:
6 - epoll-test.epoll__invalid_op2 (Failed)
Errors while running CTest
*** Error code 8Stop.
I am on
#uname -a
FreeBSD gollvm.build.server 13.0-CURRENT FreeBSD 13.0-CURRENT #0 b9403d7aae8-c254071(main): Thu Oct 29 08:06:03 UTC 2020 [email protected]:/usr/obj/usr/src/amd64.amd64/sys/GENERIC amd64
Please define the struct in the header. Failure to do so results in build failures in clients such as Wayland:
../src/event-loop.c:261:20: error: variable has incomplete type 'struct itimerspec'
struct itimerspec its;
^
/opt/X11/include/libepoll-shim/sys/timerfd.h:17:8: note: forward declaration of 'struct itimerspec'
struct itimerspec;
^
../src/event-loop.c:272:20: error: variable has incomplete type 'struct itimerspec'
struct itimerspec its;
^
/opt/X11/include/libepoll-shim/sys/timerfd.h:17:8: note: forward declaration of 'struct itimerspec'
struct itimerspec;
^
2 errors generated.
Regressed by ac44fb4 due to missing freebsd/freebsd-src@92bb8c6. From error log:
In file included from src/compat_kqueue1.c:3:
/usr/include/sys/event.h:75:2: error: unknown type name 'uintptr_t'
uintptr_t ident; /* identifier for this event */
^
/usr/include/sys/event.h:77:2: error: unknown type name 'u_short'; did you mean 'short'?
u_short flags; /* action flags for kqueue */
^
/usr/include/sys/event.h:78:2: error: unknown type name 'u_int'
u_int fflags; /* filter flag value */
^
/usr/include/sys/event.h:79:2: error: unknown type name 'intptr_t'
intptr_t data; /* filter data value */
^
Something like
prefix=/usr/local
exec_prefix=\$\{\$prefix\}
libdir=${prefix}/lib
sharedlibdir=${prefix}/lib
includedir=${prefix}/include/libepoll-shim
Name: epoll-shim
Description: epoll shim implemented using kevent
Version: 0
Requires:
Libs: -L${libdir} -L${sharedlibdir} -lepoll-shim -lthr
Cflags: -I${includedir}
https://lists.freebsd.org/archives/freebsd-current/2023-March/003391.html
From: Ed Maste [email protected]
Date: Fri, 31 Mar 2023 17:27:54 UTCOn Fri, 31 Mar 2023 at 12:38, Charlie Li [email protected] wrote:
Konstantin Belousov wrote:
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=61194e9852e641d1533cd04a5679d6042ff975d3
commit 61194e9852e641d1533cd04a5679d6042ff975d3
Author: Konstantin Belousov [email protected]
AuthorDate: 2023-03-25 23:39:02 +0000
Commit: Konstantin Belousov [email protected]
CommitDate: 2023-03-27 23:39:26 +0000Add kqueue1() syscall It takes the flags argument. Immediate use is to provide the KQUEUE_CLOEXEC flag for kqueue(2).
This commit series causes x11/libinput to hit an assert (which also
silently crashes X on launch):Assertion failed: (libinput->refcount > 0), function libinput_unref, file ../src/libinput.c, line 1957.
devel/libepoll-shim, x11/libinput's prime dependency, has its own
kqueue1() implementation, which is used when the system does not already
have one. Reverting this series and rebuilding devel/libepoll-shim to
use its included implementation allows x11/libinput to work again.Ah, NetBSD added kqueue1 some time ago, and it uses the already
existing flags (O_CLOEXEC etc.)
If it's easy to test, can you try changing libepoll-shim to call
kqueue1(KQUEUE_CLOEXEC)?
According to https://marc.info/?l=openbsd-ports&m=161435671507618.
By definition of epoll_event,
epoll-shim/include/sys/epoll.h
Lines 46 to 52 in 605be8c
the following test might fail on non-x86_64 platforms:
Lines 343 to 346 in 605be8c
For example, on Linux / macOS on M1 (aarch64), the size should be 16.
The tests of the internal EventFDCtx
machinery can be ported to the eventfd
interface to make them run on Linux, too.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.