Revert "Rewrite the entire internal signal handling/wakeup."
[cubemap] / thread.cpp
index bd4cfd1..f719eac 100644 (file)
@@ -1,97 +1,71 @@
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <errno.h>
 
 #include "log.h"
-#include "mutexlock.h"
 #include "thread.h"
-
+       
 Thread::~Thread() {}
 
 void Thread::run()
 {
-       pthread_mutex_init(&should_stop_mutex, NULL);
-       should_stop_status = false;
+       should_stop = false;
+       int pipefd[2];
+       if (pipe2(pipefd, O_CLOEXEC) == -1) {
+               log_perror("pipe");
+               exit(1);
+       }
+       stop_fd_read = pipefd[0];
+       stop_fd_write = pipefd[1];
        pthread_create(&worker_thread, NULL, &Thread::do_work_thunk, this);
 }
 
 void Thread::stop()
 {
-       {
-               MutexLock lock(&should_stop_mutex);
-               should_stop_status = true;
-       }
-       wakeup();
-       if (pthread_join(worker_thread, NULL) == -1) {
-               log_perror("pthread_join");
+       should_stop = true;
+       char ch = 0;
+       int err;
+       do {
+               err = write(stop_fd_write, &ch, 1);
+       } while (err == -1 && errno == EINTR);
+
+       if (err == -1) {
+               log_perror("write");
                exit(1);
        }
-}
 
-void *Thread::do_work_thunk(void *arg)
-{
-       Thread *thread = reinterpret_cast<Thread *>(arg);
+       do {
+               err = close(stop_fd_write);
+       } while (err == -1 && errno == EINTR);
 
-       // Block SIGHUP; only the main thread should see that.
-       // (This isn't strictly required, but it makes it easier to debug that indeed
-       // SIGUSR1 was what woke us up.)
-       sigset_t set;
-       sigaddset(&set, SIGHUP);
-       int err = pthread_sigmask(SIG_BLOCK, &set, NULL);
-       if (err != 0) {
-               errno = err;
-               log_perror("pthread_sigmask");
-               exit(1);
+       if (err == -1) {
+               log_perror("close");
+               // Can continue (we have close-on-exec).
        }
 
-       // Block SIGUSR1, and store the old signal mask.
-       sigemptyset(&set);
-       sigaddset(&set, SIGUSR1);
-       err = pthread_sigmask(SIG_BLOCK, &set, &thread->sigset_without_usr1_block);
-       if (err != 0) {
-               errno = err;
-               log_perror("pthread_sigmask");
+       pthread_kill(worker_thread, SIGHUP);
+       if (pthread_join(worker_thread, NULL) == -1) {
+               log_perror("pthread_join");
                exit(1);
        }
+       
+       do {
+               err = close(stop_fd_read);
+       } while (err == -1 && errno == EINTR);
 
-       // Call the right thunk.
-       thread->do_work();
-       return NULL;
-}
-
-bool Thread::wait_for_activity(int fd, short events, const struct timespec *timeout_ts)
-{
-       pollfd pfd;
-       pfd.fd = fd;
-       pfd.events = events;
-
-       for ( ;; ) {
-               int nfds = ppoll(&pfd, (fd == -1) ? 0 : 1, timeout_ts, &sigset_without_usr1_block);
-               if (nfds == -1 && errno == EINTR) {
-                       return false;
-               }
-               if (nfds == -1) {
-                       log_perror("poll");
-                       usleep(100000);
-                       continue;
-               }
-               assert(nfds <= 1);
-               return (nfds == 1);
+       if (err == -1) {
+               log_perror("close");
+               // Can continue (we have close-on-exec).
        }
 }
 
-void Thread::wakeup()
+void *Thread::do_work_thunk(void *arg)
 {
-       pthread_kill(worker_thread, SIGUSR1);
+       Thread *thread = reinterpret_cast<Thread *>(arg);
+       thread->do_work();
+       return NULL;
 }
 
-bool Thread::should_stop()
-{
-       MutexLock lock(&should_stop_mutex);
-       return should_stop_status;
-}