| #include <pthread.h> |
| #include <sys/types.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
| #include <errno.h> |
| |
| #define handle_error_en(en, msg) \ |
| do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) |
| |
| static volatile int done = 0; |
| static volatile int cleanup_pop_arg = 0; |
| static volatile int cnt = 0; |
| |
| static void cleanup_handler(void *arg) |
| { |
| printf("Running Cleanup Handler\n"); |
| } |
| |
| static void *thread_start(void *arg) |
| { |
| time_t start, curr; |
| |
| printf("Pushing Cleanup Handler\n"); |
| pthread_cleanup_push(cleanup_handler, NULL); |
| while (!done) |
| cnt++; |
| printf("Popping Cleanup Handler: %d\n", cleanup_pop_arg); |
| pthread_cleanup_pop(cleanup_pop_arg); |
| return NULL; |
| } |
| |
| int main(int argc, char *argv[]) |
| { |
| pthread_t thr; |
| int s; |
| void *res; |
| |
| if (argc == 2) { |
| cleanup_pop_arg = atoi(argv[1]); |
| } else { |
| printf("You must supply either 0 or 1 as an argument to " |
| "run the pop handler or not.\n"); |
| exit(EXIT_FAILURE); |
| } |
| |
| /* Start a new thread. */ |
| s = pthread_create(&thr, NULL, thread_start, NULL); |
| if (s != 0) |
| handle_error_en(s, "pthread_create"); |
| |
| /* Allow new thread to run a while, then signal done. */ |
| uthread_sleep(2); |
| done = 1; |
| |
| s = pthread_join(thr, &res); |
| if (s != 0) |
| handle_error_en(s, "pthread_join"); |
| |
| printf("Thread terminated normally; cnt = %d\n", cnt); |
| exit(EXIT_SUCCESS); |
| } |