I'm doing some event handling with C++ and pthreads. I have a main thread that reads from event queue I defined, and a worker thread that fills the event queue. The queue is of course thread safe.
The worker thread have a list of file descriptors and create an epoll system call to get events on those file descriptors. It uses epoll_wait to wait for events on the fd's.
Now the problem. Assuming I want to terminate my application cleanly, how can I cancel the worker thread properly? epoll_wait
is not one of the cancellation points of pthread(7) so it cannot react properly on pthread_cancel
.
The worker thread main() looks like this
while(m_WorkerRunning) {
epoll_wait(m_EpollDescriptor, events, MAXEVENTS, -1);
//handle events and insert to queue
}
The m_WorkerRunning
is set to true
when the thread starts and it looks like I can interrupt the thread by settings m_WorkerRunning
to false from the main thread. The problem is that epoll_wait
theoretically can wait forever.
Other solution I though about is: instead of waiting forever (-1) I can wait for example X time slots, then handle properly no-events case and if m_WorkerRunning == false
then exit the loop and terminate the worker thread cleanly. The main thread then sets m_WorkerRunning
to false, and sleeps X. However I'm not sure about the performance of such epoll_wait and also not sure what would be the correct X? 500ms? 1s? 10s?
I'd like to hear some experienced advises!
More relevant information: the fd's I'm waiting events on, are devices in /dev/input
so technically I'm doing some sort of input subsystem. The targeted OS is Linux (latest kernel) on ARM architecture.
Thanks!
You could send the thread a signal which would interupt the blocking call to
epoll_wait()
. If doing so modify your code like this:A way to add a signal handler:
To set this handler for the signal
SIGUSR1
do:To send a signal
SIGUSR1
from another process:To have a process send a signal to itself: