A NOTE has been added to this issue. 
====================================================================== 
https://austingroupbugs.net/view.php?id=1731 
====================================================================== 
Reported By:                geoffclare
Assigned To:                
====================================================================== 
Project:                    1003.1(2016/18)/Issue7+TC2
Issue ID:                   1731
Category:                   System Interfaces
Type:                       Clarification Requested
Severity:                   Objection
Priority:                   normal
Status:                     New
Name:                       Geoff Clare 
Organization:               The Open Group 
User Reference:              
Section:                    pthread_sigmask() 
Page Number:                1734 
Line Number:                56243 
Interp Status:              --- 
Final Accepted Text:         
====================================================================== 
Date Submitted:             2023-05-23 09:43 UTC
Last Modified:              2023-06-06 19:24 UTC
====================================================================== 
Summary:                    pthread_sigmask() pending signal requirement time
paradox
====================================================================== 

---------------------------------------------------------------------- 
 (0006313) kre (reporter) - 2023-06-06 19:24
 https://austingroupbugs.net/view.php?id=1731#c6313 
---------------------------------------------------------------------- 
Re https://austingroupbugs.net/view.php?id=1731#c6312

First, I am not proposing any requirement, just to leave the requirement
in this function the same as it has always been, your change was to add
a new requirement (that the signal delivered be one that was just
unblocked,
rather than simply any pending deliverable signal).   If my wording seemed
to be adding something new, then use some other wording which does not.
I certainly did not intend to alter anything, except to avoid the
before/after
issue.


I see nothing in the description of the Illuminos code that you included
(I am one of those "some people" though I have no idea what kind of
licence
Illuminos has on its code) which is different in any material way from the
BSD code fragments I posted (BSD code these days is licensed mostly with a
"don't sue anyone" type licence, if it matters to anyone).  This doesn't
mean
there isn't one - just that your note did not mention it.

The t_sig_check field looks like a different (and perhaps better)
optimisation
than what the CURSIG() macro in BSD provides; as you describe it, it
merely
encompasses the idea that there cannot be a signal pending unless someone
has
delivered one (or unblocked one) - and hence it is pointless to test
whether
one might now be pending (whereas the BSD code tests every time, but tries
to
make that test as cheap as possible).   [ While it seems "obvious" it is
a better way, it isn't necessarily - setting the field needs to be
protected
by a lock to guard against it simultaneously being cleared - that might be
more costly than is warranted - or might be zero if the relevant code is
already running holding a suitable lock for the purpose.   And that is an
extra field which makes the structure bigger, which also has costs - on
fork,
there is more to copy, for example, and more memory is consumed.  So, this
way might be improvement, or might not be, much benchmarking would be
required
for a definitive answer - and that might vary from system to system. ]

t_sig_check doesn't need to be set in the SIG_BLOCK case, as that cannot
be
allowing any signals that were pending to be delivered, and it is not
sending
a signal of its own.   I would assume that all code which sends a signal,
in addition to that code which unblocks pending signals, sets t_sig_check.
Check their code for the kill() system call and verify that also sets that
field (on the process/thread being sent the signal of course, not the one
sending it, unless they are the same), and if you feel inclined, the code
that sends SIGCHLD when a child exits, which should do the same (if the
signal is actually sent. or SIGALRM if a timer expires).

Traps which send signals should do the same - though one of those should
not
normally happen to a process running inside a system call.

Nothing you described has any bearing upon what signal gets delivered to
the
process when the sigprocmask() system all is done - whether it is one that
was just unblocked, or another that happened to arrive while that system
call
was running.   You would need to look deeper into what the post_syscall()
function you mention does in that case that t_sig_check is set, to
discover
if it somehow makes a distinction between a signal that has been pending,
and
is now unblocked, and one which was never blocked, but just arrived while
the
system call was running (a child exiting that was running on a different
CPU
would, I suspect, be the most likely way that might happen - but since
this is a very fast system call (only likely to block if it needs to wait
on
some internal data structure lock, or if is pre-empted) the chances of
that
happening are very small.

Since you (seem to) want to change the requirement from what it has been,
I'd expect it is incumbent upon you to show that at least most systems
behave
the way that you believe they should behave.   I actually doubt that there
are any - but that's just based upon the way the code was developed, and
intuition, not investigation.

The requirement that if a pending signal was unblocked, that it be
delivered
before the system call returns (which in reality means before any other
application code runs after the system call returns - though it will be
before the library function that made the system call returns) doesn't
really need to be there at all - if there is a pending signal when any
system call completes, that signal (or one of them if there is more than
one)
is taken before the application runs any more code (for all system calls).
I suspect that the requirement is there just to make it clear that
unblocking
a pending signal is equivalent to sending that signal, and implementations
aren't permitted to only deliver signals if the system call being run
actually generated one, which is probably reasonable (someone implementing
an OS from the standard, without any experience, could make that mistake).

I'd suggest simply fixing the time paradox, and avoid attempting to "fix"
the wording otherwise than that, as what is there now, is almost certainly
exactly what it should say (things occurring after things they precede
excepted, of course).   Alternatively, we could just leave the time
paradox
there as a "quaint oddity" as it doesn't really affect anything (but no, I
am not suggesting doing that, just that that would be better than the
proposed change).

While (re-)considering the change you are proposing, consider this case.

Let's assume that SIGINT SIGQUIT and SIGTSTP are blocked, and there is
a pending SIGINT waiting to be delivered, but neither of the others.

The application calls pthread_sigmask() to unblock those 3 signals.  In
the normal course of events, the SIGINT would be delivered to the
application
as soon as it starts to run again - before the pthread_sigmask() call
returns,
and that is what you are trying to say is required.   But let's assume
that
before the application gets put back on a CPU to run (perhaps its priority
has degraded, and higher priority processes are now running on all CPUs
that
are available) the user types the terminal's stop character (usually ^Z)
which the terminal driver turns into a progress group SIGTSTP to the
process
group of the terminal - one member of which, we will assume, is our
application.

Are you contending that the system may not deliver that SIGTSTP (instead
of
the SIGINT) if it so desires?   Because that is what the wording you
proposed
would suggest.   The SIGTSTP signal was not a pending signal which became
unblocked by the pthread_sigmask() call, it had not occurred yet when the
unblocking happened, hence it is not the case that "the change made to the
currently blocked set of signals causes any pending signals to become
unblocked," for that signal, but it was for SIGINT, so according to your
wording, only the SIGINT can be delivered, and not the SIGTSTP.

The previous (current) wording simply says that if there are any unblocked
signals when the call returns (which there are now, 2 of them, SIGINT and
SIGTSTP) then one of them must be delivered immediately - it does not say
which, and nor should it. 

Issue History 
Date Modified    Username       Field                    Change               
====================================================================== 
2023-05-23 09:43 geoffclare     New Issue                                    
2023-05-23 09:43 geoffclare     Name                      => Geoff Clare     
2023-05-23 09:43 geoffclare     Organization              => The Open Group  
2023-05-23 09:43 geoffclare     Section                   => pthread_sigmask()
2023-05-23 09:43 geoffclare     Page Number               => 1734            
2023-05-23 09:43 geoffclare     Line Number               => 56243           
2023-05-23 09:43 geoffclare     Interp Status             => ---             
2023-05-23 21:08 kre            Note Added: 0006287                          
2023-05-25 08:40 geoffclare     Note Added: 0006288                          
2023-05-25 18:26 kre            Note Added: 0006292                          
2023-05-25 18:32 kre            Note Edited: 0006292                         
2023-05-25 18:44 kre            Note Added: 0006293                          
2023-05-30 11:14 geoffclare     Note Added: 0006294                          
2023-05-31 19:50 kre            Note Added: 0006296                          
2023-06-06 15:50 geoffclare     Note Added: 0006312                          
2023-06-06 19:24 kre            Note Added: 0006313                          
======================================================================


  • [1003.1(2016... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
      • Re:... Geoff Clare via austin-group-l at The Open Group
      • Re:... Robert Elz via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • Re: [10... Robert Elz via austin-group-l at The Open Group

Reply via email to