aboutsummaryrefslogtreecommitdiffstats
path: root/src/libplaynice
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2025-10-22 18:48:33 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2025-10-22 18:48:33 +0000
commit0ee1464bd20df97b45e20d7da031a206853dabaf (patch)
tree3f988ba598a70e450c3a3215b0c6de336b4ea5c7 /src/libplaynice
parentb41f7406424e0b3f2d069e2c9c9f3e925c42c67e (diff)
downloadskalibs-0ee1464bd20df97b45e20d7da031a206853dabaf.tar.gz
Add libplaynice with keventbridge.h
Diffstat (limited to 'src/libplaynice')
-rw-r--r--src/libplaynice/keventbridge_end.c21
-rw-r--r--src/libplaynice/keventbridge_read.c16
-rw-r--r--src/libplaynice/keventbridge_start.c75
3 files changed, 112 insertions, 0 deletions
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 <skalibs/sysdeps.h>
+
+#ifdef SKALIBS_HASKEVENT
+
+#include <pthread.h>
+
+#include <skalibs/djbunix.h>
+#include <skalibs/keventbridge.h>
+
+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 <skalibs/sysdeps.h>
+
+#ifdef SKALIBS_HASKEVENT
+
+#include <skalibs/allreadwrite.h>
+#include <skalibs/keventbridge.h>
+
+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 <skalibs/sysdeps.h>
+
+#ifdef SKALIBS_HASKEVENT
+
+#include <errno.h>
+#include <pthread.h>
+
+#include <skalibs/fcntl.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/keventbridge.h>
+
+#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