The problem is to transfer interruption signal to the thread performing I/O multiplexing, for instance, waiting for new data during select(2) call. Default signal handler will force select(..) to return, but as far as we want to have a custom one, we need to abort select(..) manually.
The tricky solution is to set up an non-blocking pipe and add its read end to select(2)'s readfds array. Hence select(..) will return immediately when any data will be written to the pipe's write end. Therefore, write(selfpipe_write_fd, "", 1); must be called in signal handler after the termination_signal_received is set to true.
The same effect can be achieved with signalfd(2). Unfortunately, this syscall is linux-specific.
Here is a draft of the proposed aspect:
class selfpipe : noncopyable { protected: void setup() { pipe(fd_); fcntl(fd_[READ_FD], F_SETFL, fcntl(fd_[READ_FD], F_GETFL) | O_NONBLOCK); fcntl(fd_[WRITE_FD], F_SETFL, fcntl(fd_[WRITE_FD], F_GETFL) | O_NONBLOCK); } void teardown() { close(fd_[READ_FD]; close(fd_[WRITE_FD]; } public: int readfd() const { return fd_[READ_FD]; } void poke() { write(fd_[WRITE_FD], "", 1); } private: enum { READ_FD = 0, WRITE_FD = 1 }; int fd_[2]; }; Thanks a lot for the code, I want to implement it on lib. Some questions: The user need use 'select' to use this aspect? How user will use it? (on final application code) I can't figure it! I tell this because, One question that comes to mind! We have something like that in Windows side? I must/want provide an 'aspect' with same functionality or interface on both sides! I need tie all internally on lib, and provide a normalized interface, but signals are completely different on windows (windows don't have signal) and posix. Any idea ? Thanks a lot.