summaryrefslogtreecommitdiff
path: root/src/test/test-process-util.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-02-08 18:01:26 +0100
committerLennart Poettering <lennart@poettering.net>2023-02-17 14:27:58 +0100
commit6aa90884a093040ddb2dd656c1bf93892420c804 (patch)
tree78f8bf36e87f23b12b3cedf8a0af874abd3374b6 /src/test/test-process-util.c
parentceecf3d45d00a176dbdbeaec8e3179b635da6f1a (diff)
downloadsystemd-6aa90884a093040ddb2dd656c1bf93892420c804.tar.gz
process-util: add helper get_process_threads()
Let's add a proper helper for querying the number of threads in a process.
Diffstat (limited to 'src/test/test-process-util.c')
-rw-r--r--src/test/test-process-util.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c
index 1864f8a750..9c24ca8204 100644
--- a/src/test/test-process-util.c
+++ b/src/test/test-process-util.c
@@ -2,6 +2,7 @@
#include <fcntl.h>
#include <linux/oom.h>
+#include <pthread.h>
#include <sys/mount.h>
#include <sys/personality.h>
#include <sys/prctl.h>
@@ -793,6 +794,59 @@ TEST(set_oom_score_adjust) {
assert_se(b == a);
}
+static void* dummy_thread(void *p) {
+ int fd = PTR_TO_FD(p);
+ char x;
+
+ /* let main thread know we are ready */
+ assert_se(write(fd, &(const char) { 'x' }, 1) == 1);
+
+ /* wait for the main thread to tell us to shut down */
+ assert_se(read(fd, &x, 1) == 1);
+ return NULL;
+}
+
+TEST(get_process_threads) {
+ int r;
+
+ /* Run this test in a child, so that we can guarantee there's exactly one thread around in the child */
+ r = safe_fork("(nthreads)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_REOPEN_LOG|FORK_WAIT|FORK_LOG, NULL);
+ assert_se(r >= 0);
+
+ if (r == 0) {
+ _cleanup_close_pair_ int pfd[2] = PIPE_EBADF, ppfd[2] = PIPE_EBADF;
+ pthread_t t, tt;
+ char x;
+
+ assert_se(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, pfd) >= 0);
+ assert_se(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, ppfd) >= 0);
+
+ assert_se(get_process_threads(0) == 1);
+ assert_se(pthread_create(&t, NULL, &dummy_thread, FD_TO_PTR(pfd[0])) == 0);
+ assert_se(read(pfd[1], &x, 1) == 1);
+ assert_se(get_process_threads(0) == 2);
+ assert_se(pthread_create(&tt, NULL, &dummy_thread, FD_TO_PTR(ppfd[0])) == 0);
+ assert_se(read(ppfd[1], &x, 1) == 1);
+ assert_se(get_process_threads(0) == 3);
+
+ assert_se(write(pfd[1], &(const char) { 'x' }, 1) == 1);
+ assert_se(pthread_join(t, NULL) == 0);
+
+ /* the value reported via /proc/ is decreased asynchronously, and there appears to be no nice
+ * way to sync on it. Hence we do the weak >= 2 check, even though == 2 is what we'd actually
+ * like to check here */
+ assert_se(get_process_threads(0) >= 2);
+
+ assert_se(write(ppfd[1], &(const char) { 'x' }, 1) == 1);
+ assert_se(pthread_join(tt, NULL) == 0);
+
+ /* similar here */
+ assert_se(get_process_threads(0) >= 1);
+
+ _exit(EXIT_SUCCESS);
+ }
+}
+
static int intro(void) {
log_show_color(true);
return EXIT_SUCCESS;