Skip to content

waitForTermination is unreliable on Linux. #2978

@IneptProgrammer

Description

@IneptProgrammer

ServerApplication::waitForTerminationRequest() creates a signal mask blocking SIGINT, SIGTERM, and SIGQUIT . Pthreads inherit the signal mask of the creating thread. A Poco Server Application's main method is supposed to call waitForTerminationRequest() at the end. So all the threads that get created before this point don't inherit the mask blocking these signals. This basically means all of the threads created by the application, besides the main thread, do not inherit this signal mask and do not block these signals.

From signal(7):

A process-directed signal may be delivered to any one of the threads that does not currently have the signal blocked. If more than one of the threads has the signal unblocked, then the kernel chooses an arbitrary thread to which to deliver the signal.

ServerApplication::terminate() uses a process directed signal to break out of waitForTerminationRequest(). This signal may get delivered to any thread. If it is not delivered to the main thread it causes the process to terminate immediately with a SIGINT exit code.

The application I work in is heavily threaded (hundreds of threads), but I only see this behavior on occasion when calling terminate. (It seems like it should happen most of the time terminate gets called). I took a look at the Linux source code and it looks like if multiple threads, including the main thread, can receive a signal the kernel tries to prioritize the main thread. However, it is not guaranteed to choose the main thread (for instance if the main thread already has Pending signals it will choose another thread).

The signals waited for in waitForTerminationRequest need to be blocked before other threads are created. It looks like there is code to do something similar for SIGPIPE in Thread_POSIX.cpp.

This is related to to issue: SIGTERM is not always handled properly in ServerApplication

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions