From 233e3ccb96525e7a6af31a60b891badd8d73c5a4 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Mon, 31 Aug 2026 23:45:35 +0000 Subject: Prepare for 2.15.2.0 Add pthread_create_flat, waitpid_nohang, waitpids_nohang --- src/include/skalibs/djbunix.h | 5 +++- src/include/skalibs/functypes.h | 3 ++ src/libplaynice/pthread_create_flat.c | 56 +++++++++++++++++++++++++++++++++++ src/libstddjb/wait_pid_nohang.c | 5 ++++ src/libstddjb/wait_pids_nohang.c | 4 +++ src/libstddjb/waitpids_nohang.c | 19 ++++++++++++ 6 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 src/libplaynice/pthread_create_flat.c create mode 100644 src/libstddjb/waitpids_nohang.c (limited to 'src') diff --git a/src/include/skalibs/djbunix.h b/src/include/skalibs/djbunix.h index a2a0d42..d6efa09 100644 --- a/src/include/skalibs/djbunix.h +++ b/src/include/skalibs/djbunix.h @@ -62,9 +62,12 @@ extern size_t path_canonicalize (char *, char const *, int) ; extern pid_t wait_nointr (int *) ; extern pid_t waitpid_nointr (pid_t, int *, int) ; #define wait_pid(pid, wstat) waitpid_nointr(pid, (wstat), 0) -#define wait_nohang(wstat) waitpid_nointr(-1, (wstat), WNOHANG) +#define waitpid_nohang(pid, wstat) waitpid_nointr(pid, (wstat), WNOHANG) +#define wait_nohang(wstat) waitpid_nohang(-1, (wstat)) extern pid_t wait_pid_nohang (pid_t, int *) ; extern int wait_pids_nohang (pid_t const *, unsigned int, int *) ; +extern int waitpids_nohang (pid_t const *, unsigned int, int *) ; + #define wait_status(w) (WIFSIGNALED(w) ? 256 + WTERMSIG(w) : WEXITSTATUS(w)) #define wait_estatus(w) (WIFSIGNALED(w) ? 128 + WTERMSIG(w) : WEXITSTATUS(w) >= 128 ? 128 : WEXITSTATUS(w)) diff --git a/src/include/skalibs/functypes.h b/src/include/skalibs/functypes.h index d1a7c4c..8d21b45 100644 --- a/src/include/skalibs/functypes.h +++ b/src/include/skalibs/functypes.h @@ -67,4 +67,7 @@ typedef randomgen_func *randomgen_func_ref ; typedef int main_func (char const *const *) ; typedef main_func *main_func_ref ; +typedef void *generic_func (void *) ; +typedef generic_func *generic_func_ref ; + #endif diff --git a/src/libplaynice/pthread_create_flat.c b/src/libplaynice/pthread_create_flat.c new file mode 100644 index 0000000..5c8e466 --- /dev/null +++ b/src/libplaynice/pthread_create_flat.c @@ -0,0 +1,56 @@ +/* ISC license. */ + +#include + +#ifdef SKALIBS_HASPTHREAD + +#include +#include + +#include + +struct spawndata_s +{ + pthread_cond_t cond ; + pthread_mutex_t mutex ; + generic_func_ref start ; + void *arg ; + size_t argsize ; +} ; + +static void *bootstrap (void *arg) +{ + struct spawndata_s *data = arg ; + char newarg[data->argsize ? data->argsize : 1] ; + memcpy(newarg, data->arg, data->argsize) ; + int e = pthread_mutex_lock(&data->mutex) ; + if (e) return 0 ; + pthread_cond_signal(&data->cond) ; + pthread_mutex_unlock(&data->mutex) ; + return (*data->start)(newarg) ; +} + +int pthread_create_flat (pthread_t *restrict th, pthread_attr_t const *restrict attr, generic_func_ref start, void *restrict arg, size_t argsize) +{ + struct spawndata_s data = + { + .cond = PTHREAD_COND_INITIALIZER, + .mutex = PTHREAD_MUTEX_INITIALIZER, + .start = start, + .arg = arg, + .argsize = argsize + } ; + pthread_t tth ; + int e = pthread_mutex_lock(&data.mutex) ; + if (e) return e ; + e = pthread_create(&tth, attr, &bootstrap, &data) ; + if (e) return e ; + e = pthread_cond_wait(&data.cond, &data.mutex) ; + if (e) pthread_cancel(tth) ; else *th = tth ; + pthread_mutex_unlock(&data.mutex) ; + pthread_cond_destroy(&data.cond) ; + pthread_mutex_destroy(&data.mutex) ; + return e ; +} + +#endif diff --git a/src/libstddjb/wait_pid_nohang.c b/src/libstddjb/wait_pid_nohang.c index 7b27bbe..f22a222 100644 --- a/src/libstddjb/wait_pid_nohang.c +++ b/src/libstddjb/wait_pid_nohang.c @@ -3,6 +3,11 @@ #include #include + /* + wait_pid_nohang (defined here): reaps everything until it gets pid + waitpid_nohang (macro): only tries to reap pid, doesn't touch others + */ + pid_t wait_pid_nohang (pid_t pid, int *wstat) { int w = 0 ; diff --git a/src/libstddjb/wait_pids_nohang.c b/src/libstddjb/wait_pids_nohang.c index c13ddec..f56c065 100644 --- a/src/libstddjb/wait_pids_nohang.c +++ b/src/libstddjb/wait_pids_nohang.c @@ -3,6 +3,10 @@ #include #include + /* + wait_pids_nohang (with the underscore): reap everything, report if in pids + */ + int wait_pids_nohang (pid_t const *pids, unsigned int len, int *wstat) { for (;;) diff --git a/src/libstddjb/waitpids_nohang.c b/src/libstddjb/waitpids_nohang.c new file mode 100644 index 0000000..23f03de --- /dev/null +++ b/src/libstddjb/waitpids_nohang.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include +#include + + /* + waitpids_nohang (defined here): only reap pids, don't touch the rest + */ + +int waitpids_nohang (pid_t const *pids, unsigned int len, int *wstat) +{ + for (unsigned int i = 0 ; i < len ; i++) + { + pid_t r = waitpid_nohang(pids[i], wstat) ; + if (r == -1) return -1-i ; + else if (r == pids[i]) return 1+i ; + } + return 0 ; +} -- cgit v1.3.1