aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
parentb41f7406424e0b3f2d069e2c9c9f3e925c42c67e (diff)
downloadskalibs-0ee1464bd20df97b45e20d7da031a206853dabaf.tar.gz
Add libplaynice with keventbridge.h
Diffstat (limited to 'src')
-rw-r--r--src/include/skalibs/keventbridge.h30
-rw-r--r--src/include/skalibs/playnice.h8
-rw-r--r--src/include/skalibs/skalibs.h1
-rw-r--r--src/include/skalibs/stddjb.h4
-rw-r--r--src/libplaynice/keventbridge_end.c21
-rw-r--r--src/libplaynice/keventbridge_read.c16
-rw-r--r--src/libplaynice/keventbridge_start.c75
-rw-r--r--src/sysdeps/trykqueue1.c15
8 files changed, 168 insertions, 2 deletions
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 <skalibs/sysdeps.h>
+
+#ifdef SKALIBS_HASKEVENT
+
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#include <pthread.h>
+
+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 <skalibs/keventbridge.h>
+
+#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 <skalibs/random.h>
#include <skalibs/datastruct.h>
#include <skalibs/unixonacid.h>
+#include <skalibs/playnice.h>
#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 <skalibs/uint16.h>
#include <skalibs/uint32.h>
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
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 <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#include <fcntl.h>
+
+int main (void)
+{
+ int q = kqueue1(O_CLOEXEC) ;
+ return 0 ;
+}