1 /* Creates several daemon threads and non-daemon threads.
2    Tests that the process can exit even if the daemon threads are still running,
3    as per thr_create(3C). */
4 
5 #include <pthread.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <thread.h>
10 #include <unistd.h>
11 
12 #define DAEMON_THREADS 5
13 #define NON_DAEMON_THREADS 6
14 #define SLEEP_100_MS usleep(100 * 1000)
15 
16 static pthread_barrier_t barrier;
17 
18 void *daemon_thread_func(void *arg) {
19    size_t index = (size_t) arg;
20    printf("DAEMON thread #%zu running\n", index); fflush(stdout);
21    pthread_barrier_wait(&barrier);
22 
23    /* Give the non-daemon threads enough time to exit. */
24    sleep(10);
25    printf("DAEMON thread #%zu still running?!\n", index); fflush(stdout);
26    return NULL;
27 }
28 
29 void *normal_thread_func(void *arg) {
30    size_t index = (size_t) arg;
31    printf("non-daemon thread #%zu running\n", index); fflush(stdout);
32    pthread_barrier_wait(&barrier);
33 
34    sleep(2);
35    return NULL;
36 }
37 
38 int main(void) {
39    size_t i;
40    int ret = pthread_barrier_init(&barrier, NULL,
41                                   DAEMON_THREADS + NON_DAEMON_THREADS + 1);
42    if (ret != 0) {
43       fprintf(stderr, "pthread_barrier_init failed: %s\n", strerror(ret));
44       return 1;
45    }
46 
47    for (i = 0; i < DAEMON_THREADS; i++) {
48       ret = thr_create(NULL, 0, daemon_thread_func, (void *) i,
49                        THR_DAEMON, NULL);
50       if (ret != 0) {
51          fprintf(stderr, "thr_create failed: %s\n", strerror(ret));
52          return 1;
53       }
54       SLEEP_100_MS;
55    }
56 
57    for (i = 0; i < NON_DAEMON_THREADS; i++) {
58       ret = thr_create(NULL, 0, normal_thread_func, (void *) i, 0, NULL);
59       if (ret != 0) {
60          fprintf(stderr, "thr_create failed: %s\n", strerror(ret));
61          return 1;
62       }
63       SLEEP_100_MS;
64    }
65 
66    pthread_barrier_wait(&barrier);
67 
68    printf("MAIN thread exiting\n");
69    /* Exit only the main thread, not whole process.
70       That is, do not exit(0) or return(0). */
71    thr_exit(NULL);
72 }
73