|Anonymous | Login||2023-12-07 16:31 UTC|
|Main | My View | View Issues | Change Log | Docs|
|Viewing Issue Simple Details|
|ID||Category||Severity||Type||Date Submitted||Last Update|
|0000633||[1003.1(2008)/Issue 7] System Interfaces||Editorial||Enhancement Request||2012-11-16 04:22||2022-09-27 15:25|
|Priority||normal||Resolution||Accepted As Marked|
|Final Accepted Text||Note: 0005937|
|Summary||0000633: SIGEV_THREAD delivery renders many signal interfaces unsafe|
Regarding SIGEV_THREAD signal delivery (for timers, etc.), XSH 2.4.2 reads:
"Multi-threaded programs can use an alternate event notification mechanism. When a notification is processed, and the sigev_notify member of the sigevent structure has the value SIGEV_THREAD, the function sigev_notify_function is called with parameter sigev_value.
The function shall be executed in an environment as if it were the start_routine for a newly created thread with thread attributes specified by sigev_notify_attributes. If sigev_notify_attributes is NULL, the behavior shall be as if the thread were created with the detachstate attribute set to PTHREAD_CREATE_DETACHED. Supplying an attributes structure with a detachstate attribute of PTHREAD_CREATE_JOINABLE results in undefined behavior. The signal mask of this thread is implementation-defined."
The final sentence renders any use of sigwait, sigwaitinfo, sigtimedwait, pselect, and possibly other interfaces unsafe/unreliable whenever SIGEV_THREAD delivery is in use. This is because the thread handling the event may have the signals to be waited for unmasked when the start function is invoked; even if the application attempts to block them, there is a race window during which this new thread may "steal" the signal.
The currently-allowed behavior violates the principle that functions manipulating the signal-mask in a thread-safe manner should never explicitly unblock signals, only block them or restore a previously-saved signal mask.
To my knowledge, this issue was first raised on the glibc bug tracker as issue #10815.
Replace the sentence:
"The signal mask of this thread is implementation-defined."
with something to the effect of:
"The signal mask of this thread in an implementation-defined set containing at least all signals which were masked at the time of the call which installed the sigevent notification handler in the thread from which the call was made."
Or, if a more blunt solution is acceptable, replace the entire paragraph with:
"The function shall be executed in an environment as if it were the start_routine for a newly created thread with thread attributes specified by sigev_notify_attributes and with all signals initially masked. If sigev_notify_attributes is NULL, the behavior shall be as if the thread were created with the detachstate attribute set to PTHREAD_CREATE_DETACHED. Supplying an attributes structure with a detachstate attribute of PTHREAD_CREATE_JOINABLE results in undefined behavior."
Input from AIX:
The notification thread runs with all signals blocked (except KILL and STOP which can never be blocked). There is only one notification thread so if an event is posted while it's running, it will see that one posted event when it tries to wait, but multiple pending events are neither queued nor handled concurrently.
Input from Solaris:
1. What is the signal mask in the thread that is created to handle
the notification? (Is it just inherited from the calling thread?)
It is inherited.
2. When an event notification is triggered and a previous handler is
still executing, do they execute a new instance of the same handler
concurrently, or suppress the new notification (or something else)?
Something else. The request is handled by a thread which adds the request to a work queue; if the maximum number of worker threads for the specific type of SIGEV_THREAD notification has not been reached, then a new worker thread is spawned to handle the request. Otherwise, the request is added to a work queue for the next idle worker thread to process.
On 2018 edition page 490 line 16984 section 2.4.2, change:
The signal mask of this thread is implementation-defined.to:
It is implementation-defined whether the signal mask of this thread has all signals except SIGKILL and SIGSTOP blocked, or is the same as the mask that was in effect for the thread which installed the sigevent notification handler at the time of the call that installed the handler.
|2012-11-16 04:22||dalias||New Issue|
|2012-11-16 04:22||dalias||Status||New => Under Review|
|2012-11-16 04:22||dalias||Assigned To||=> ajosey|
|2012-11-16 04:22||dalias||Name||=> Rich Felker|
|2012-11-16 04:22||dalias||Organization||=> musl libc|
|2012-11-16 04:22||dalias||Section||=> XSH 2.4.2|
|2012-11-16 04:22||dalias||Page Number||=> unknown|
|2012-11-16 04:22||dalias||Line Number||=> unknown|
|2013-01-17 16:19||ajosey||Note Added: 0001445|
|2022-08-22 15:07||geoffclare||Note Added: 0005937|
|2022-08-22 15:08||geoffclare||Interp Status||=> ---|
|2022-08-22 15:08||geoffclare||Final Accepted Text||=> Note: 0005937|
|2022-08-22 15:08||geoffclare||Status||Under Review => Resolved|
|2022-08-22 15:08||geoffclare||Resolution||Open => Accepted As Marked|
|2022-08-22 15:08||geoffclare||Tag Attached: tc3-2008|
|2022-09-27 15:25||geoffclare||Status||Resolved => Applied|
|Mantis 1.1.6[^] Copyright © 2000 - 2008 Mantis Group|