Revert "Rewrite the entire internal signal handling/wakeup."
[cubemap] / thread.cpp
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <signal.h>
6 #include <errno.h>
7
8 #include "log.h"
9 #include "thread.h"
10         
11 Thread::~Thread() {}
12
13 void Thread::run()
14 {
15         should_stop = false;
16         int pipefd[2];
17         if (pipe2(pipefd, O_CLOEXEC) == -1) {
18                 log_perror("pipe");
19                 exit(1);
20         }
21         stop_fd_read = pipefd[0];
22         stop_fd_write = pipefd[1];
23         pthread_create(&worker_thread, NULL, &Thread::do_work_thunk, this);
24 }
25
26 void Thread::stop()
27 {
28         should_stop = true;
29         char ch = 0;
30         int err;
31         do {
32                 err = write(stop_fd_write, &ch, 1);
33         } while (err == -1 && errno == EINTR);
34
35         if (err == -1) {
36                 log_perror("write");
37                 exit(1);
38         }
39
40         do {
41                 err = close(stop_fd_write);
42         } while (err == -1 && errno == EINTR);
43
44         if (err == -1) {
45                 log_perror("close");
46                 // Can continue (we have close-on-exec).
47         }
48
49         pthread_kill(worker_thread, SIGHUP);
50         if (pthread_join(worker_thread, NULL) == -1) {
51                 log_perror("pthread_join");
52                 exit(1);
53         }
54         
55         do {
56                 err = close(stop_fd_read);
57         } while (err == -1 && errno == EINTR);
58
59         if (err == -1) {
60                 log_perror("close");
61                 // Can continue (we have close-on-exec).
62         }
63 }
64
65 void *Thread::do_work_thunk(void *arg)
66 {
67         Thread *thread = reinterpret_cast<Thread *>(arg);
68         thread->do_work();
69         return NULL;
70 }
71