Giter Club home page Giter Club logo

epoll-shim's People

Contributors

alyssais avatar arichardson avatar grembo avatar jbeich avatar jiixyj avatar sghctoma avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

epoll-shim's Issues

FreeBSD build - linker error

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.

Refactor "fd to context object" mapping for faster lookup

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:

  • storing some bits of state inside a kqueue object
  • the poll fd hack (there is a static struct pollfd for fds which cannot be registered with a kqueue instance)

Firefox wants to pass eventfds, but kqueues are not passable

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

timerfd_gettime is not defined

pipewire master branch started using timerfd_gettime function, which is #if 0ed 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.

epoll-shim.pc isn't compiled or builded

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?

gmake: *** No rule to make target 'install'. Stop.

[ 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) 

timerfd_create fails with CLOCK_BOOTTIME

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

Fails to build on FreeBSD 11.*

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.

Missing include for sigset_t on FreeBSD

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() {}

Add support for FreeBSD's POLLRDHUP

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.

libwayland crashes since epoll-shim v0.0.20220607

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

Ignore EVFILT_WRITE deregistration ENOENT errors

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.

All timerfd-root-test failed on macOS

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).

pkg-config file wrong include dir

I guess @CMAKE_INSTALL_INCLUDEDIR@ already includes /libepoll-shim because the result is

[…]
includedir=${prefix}/include/libepoll-shim
[…]
Cflags: -I${includedir}/libepoll-shim

cmake failure

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.

Only 32 timerfds are possible in the current implementation

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?

Calling timerfd_create "cancels out" signal blocks

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

-Weverything is not recognized by gcc

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'

Why return EPOLLHUP on not yet connected stream sockets?

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.

epoll-test.epoll__invalid_op2 failed and epoll-test.epoll__epollhup_on_fresh_socket, epoll-test.epoll__epollpri tests where skipped

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 sec

The 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 8

Stop.

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

timerfd.h only includes a forward declaration of struct itimerspec

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.

Fails to build on FreeBSD < 12

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 */
        ^

Install pkg-config file

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}

kqueue1 implementation here and FreeBSD's diverge

https://lists.freebsd.org/archives/freebsd-current/2023-March/003391.html

From: Ed Maste [email protected]
Date: Fri, 31 Mar 2023 17:27:54 UTC

On 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 +0000

 Add 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)?

sizeof(event) not always equal to 12

By definition of epoll_event,

struct epoll_event {
uint32_t events;
epoll_data_t data;
}
#ifdef __x86_64__
__attribute__((__packed__))
#endif

the following test might fail on non-x86_64 platforms:

struct epoll_event event;
// this check works on 32bit _and_ 64bit, since
// sizeof(epoll_event) == sizeof(uint32_t) + sizeof(uint64_t)
ATF_REQUIRE(sizeof(event) == 12);

For example, on Linux / macOS on M1 (aarch64), the size should be 16.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.