1 #ifndef DASYNQ_INTERRUPT_H_INCLUDED
2 #define DASYNQ_INTERRUPT_H_INCLUDED
7 #include "dasynq-config.h"
8 #include "dasynq-mutex.h"
11 * Mechanism for interrupting an event loop wait.
16 template <typename Base, typename Mutex = typename Base::mutex_t> class interrupt_channel;
18 // In the non-multi-thread case, this doesn't need to be supported:
19 template <typename Base> class interrupt_channel<Base, null_mutex> : public Base
28 template <typename Base, typename Mutex> class interrupt_channel : public Base
31 int create_pipe(int filedes[2])
33 return pipe2(filedes, O_CLOEXEC | O_NONBLOCK);
36 int create_pipe(int filedes[2])
38 int r = pipe(filedes);
40 fcntl(filedes[0], F_SETFD, O_CLOEXEC);
41 fcntl(filedes[1], F_SETFD, O_CLOEXEC);
42 fcntl(filedes[0], F_SETFL, O_NONBLOCK);
43 fcntl(filedes[1], F_SETFL, O_NONBLOCK);
54 template <typename T> void init(T *loop_mech)
57 if (create_pipe(pipedes) == -1) {
58 throw std::system_error(errno, std::system_category());
61 pipe_r_fd = pipedes[0];
62 pipe_w_fd = pipedes[1];
65 loop_mech->addFdWatch(pipe_r_fd, &pipe_r_fd, IN_EVENTS);
73 Base::init(loop_mech);
77 void receiveFdEvent(T &loop_mech, typename Base::FD_r fd_r, void * userdata, int flags)
79 if (userdata == &pipe_r_fd) {
80 // try to clear the pipe
82 read(pipe_r_fd, buf, 64);
85 Base::receiveFdEvent(loop_mech, fd_r, userdata, flags);
92 write(pipe_w_fd, buf, 1);
98 #endif /* DASYNQ_INTERRUPT_H_INCLUDED */