From 0ee1464bd20df97b45e20d7da031a206853dabaf Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Wed, 22 Oct 2025 18:48:33 +0000 Subject: Add libplaynice with keventbridge.h --- src/include/skalibs/keventbridge.h | 30 +++++++++++++++ src/include/skalibs/playnice.h | 8 ++++ src/include/skalibs/skalibs.h | 1 + src/include/skalibs/stddjb.h | 4 +- src/libplaynice/keventbridge_end.c | 21 ++++++++++ src/libplaynice/keventbridge_read.c | 16 ++++++++ src/libplaynice/keventbridge_start.c | 75 ++++++++++++++++++++++++++++++++++++ src/sysdeps/trykqueue1.c | 15 ++++++++ 8 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 src/include/skalibs/keventbridge.h create mode 100644 src/include/skalibs/playnice.h create mode 100644 src/libplaynice/keventbridge_end.c create mode 100644 src/libplaynice/keventbridge_read.c create mode 100644 src/libplaynice/keventbridge_start.c create mode 100644 src/sysdeps/trykqueue1.c (limited to 'src') diff --git a/src/include/skalibs/keventbridge.h b/src/include/skalibs/keventbridge.h new file mode 100644 index 0000000..8389db0 --- /dev/null +++ b/src/include/skalibs/keventbridge.h @@ -0,0 +1,30 @@ +/* ISC license. */ + +#ifndef SKALIBS_KEVENTBRIDGE_H +#define SKALIBS_KEVENTBRIDGE_H + +#include + +#ifdef SKALIBS_HASKEVENT + +#include +#include +#include +#include + +typedef struct keventbridge_s keventbridge, *keventbridge_ref ; +struct keventbridge_s +{ + pthread_t th ; + int kq ; + int p[2] ; +} ; +#define KEVENTBRIDGE_ZERO { .th = PTHREAD_NULL, .kq = -1, .p = { -1, -1 } } + +extern int keventbridge_start (keventbridge *) ; +#define keventbridge_write (kb, ke, n) kevent((kb)->kq, ke, (n), 0, 0, 0) +extern int keventbridge_read (keventbridge const *, struct kevent *) ; +extern void keventbridge_end (keventbridge *) ; + +#endif +#endif diff --git a/src/include/skalibs/playnice.h b/src/include/skalibs/playnice.h new file mode 100644 index 0000000..e820d65 --- /dev/null +++ b/src/include/skalibs/playnice.h @@ -0,0 +1,8 @@ +/* ISC license. */ + +#ifndef SKALIBS_PLAYNICE_H +#define SKALIBS_PLAYNICE_H + +#include + +#endif diff --git a/src/include/skalibs/skalibs.h b/src/include/skalibs/skalibs.h index 2c55ef2..71ce9a2 100644 --- a/src/include/skalibs/skalibs.h +++ b/src/include/skalibs/skalibs.h @@ -21,5 +21,6 @@ #include #include #include +#include #endif diff --git a/src/include/skalibs/stddjb.h b/src/include/skalibs/stddjb.h index d57a3df..edb5d58 100644 --- a/src/include/skalibs/stddjb.h +++ b/src/include/skalibs/stddjb.h @@ -1,7 +1,7 @@ /* ISC license. */ -#ifndef STDDJB_H -#define STDDJB_H +#ifndef SKALIBS_STDDJB_H +#define SKALIBS_STDDJB_H #include #include diff --git a/src/libplaynice/keventbridge_end.c b/src/libplaynice/keventbridge_end.c new file mode 100644 index 0000000..57aef56 --- /dev/null +++ b/src/libplaynice/keventbridge_end.c @@ -0,0 +1,21 @@ +/* ISC license. */ + +#include + +#ifdef SKALIBS_HASKEVENT + +#include + +#include +#include + +void keventbridge_end (keventbridge *kbp) +{ + pthread_cancel(kbp->th) ; + pthread_join(kbp->th, 0) ; + fd_close(kbp->kq) ; + if (kbp->p[1] >= 0) fd_close(kbp->p[1]) ; + fd_close(kbp->p[0]) ; +} + +#endif diff --git a/src/libplaynice/keventbridge_read.c b/src/libplaynice/keventbridge_read.c new file mode 100644 index 0000000..e5a5eac --- /dev/null +++ b/src/libplaynice/keventbridge_read.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include + +#ifdef SKALIBS_HASKEVENT + +#include +#include + +int keventbridge_read (keventbridge *kbp, struct kevent *ke) +{ + ssize_t r = sanitize_read(allread(kbp->p[0], (char *)ke, sizeof(struct kevent))) ; + return r <= 0 ? r : 1 ; +} + +#endif diff --git a/src/libplaynice/keventbridge_start.c b/src/libplaynice/keventbridge_start.c new file mode 100644 index 0000000..21ead0e --- /dev/null +++ b/src/libplaynice/keventbridge_start.c @@ -0,0 +1,75 @@ +/* ISC license. */ + +#include + +#ifdef SKALIBS_HASKEVENT + +#include +#include + +#include +#include +#include + +#ifdef SKALIBS_HASKQUEUE1 + +# define kqueuec() kqueue1(O_CLOEXEC) + +#else + +static int kqueuec (void) +{ + int kq = kqueue() ; + if (kq == -1) return -1 ; + if (coe(kq) == -1) + { + fd_close(kq) ; + return -1 ; + } + return kq ; +} + +#endif + +static void *keventbridge_reader (void *arg) +{ + keventbridge *kbp = arg ; + struct kevent ke ; + for (;;) + { + int r = kevent(kbp->kq, 0, 0, &ke, 1, 0) ; + if (r == -1 && errno != EINTR) break ; + if (r && allwrite(kbp->p[1], (char *)&ke, sizeof(ke)) < sizeof(ke)) break ; + } + fd_close(kbp->p[1]) ; + kbp->p[1] = -1 ; + return 0 ; +} + +int keventbridge_start (keventbridge *kbp) +{ + pthread_attr_t attr ; + int e ; + + kbp->kq = kqueuec() ; + if (pipecoe(kbp->p) == -1) goto errkq ; + if (ndelay_on(kbp->p[0]) == -1) goto errp ; + e = pthread_attr_init(&attr) ; + if (e) { errno = e ; goto errp ; } + pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN) ; + e = pthread_create(&kbp->th, &attr, &keventbridge_reader, kbp) ; + if (e) { errno = e ; goto errattr ; } + pthread_attr_destroy(&attr) ; + return 1 ; + + errattr: + pthread_attr_destroy(&attr) ; + errp: + fd_close(kbp->p[1]) ; + fd_close(kbp->p[0]) ; + errkq: + fd_close(kbp->kq) ; + return 0 ; +} + +#endif diff --git a/src/sysdeps/trykqueue1.c b/src/sysdeps/trykqueue1.c new file mode 100644 index 0000000..95f1d29 --- /dev/null +++ b/src/sysdeps/trykqueue1.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#include +#include +#include +#include + +int main (void) +{ + int q = kqueue1(O_CLOEXEC) ; + return 0 ; +} -- cgit v1.3.1