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 16static pthread_barrier_t barrier; 17 18void *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 29void *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 38int 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