Skip to content

Commit

Permalink
Fix issue with re-registering master handlers
Browse files Browse the repository at this point in the history
OMRSIG_SIGACTION can be called outside of omrsignal.c functions. A
call to OMRSIG_SIGACTION will override the master handlers set by either
omrsig_protect or omrsig_set_async_signal_handler. Setting a master
handler once sets a bit in signalsWithMasterHandlers. If the master
handler is overridden by an external call to OMRSIG_SIGACTION, then the
bit in signalsWithMasterHandlers will not be un-set. Since the bit in
signalsWithMasterHandlers isn't un-set once the master handler has been
overridden, then subsequent calls to omrsig_protect and
omrsig_set_async_signal_handler will not re-register the master handler.
In subsequent calls, it will look as if the master handler is already
registered.

We mustn't rely on signalsWithMasterHandlers to re-register master
handlers. It doesn't cause any harm to register master handlers every
time a call is made to either omrsig_protect or
omrsig_set_async_signal_handler.

Signed-off-by: Babneet Singh <sbabneet@ca.ibm.com>
  • Loading branch information
babsingh committed Apr 9, 2018
1 parent 12d6fd9 commit ed5a742
Showing 1 changed file with 4 additions and 15 deletions.
19 changes: 4 additions & 15 deletions port/unix/omrsignal.c
Expand Up @@ -322,7 +322,6 @@ omrsig_protect(struct OMRPortLibrary *portLibrary, omrsig_protected_fn fn, void
omrthread_t thisThread = NULL;
uint32_t rc = 0;
uint32_t flagsSignalsOnly = 0;
uint32_t flagsWithoutMasterHandlers = 0;

Trc_PRT_signal_omrsig_protect_entered(fn, fn_arg, handler, handler_arg, flags);

Expand All @@ -334,15 +333,9 @@ omrsig_protect(struct OMRPortLibrary *portLibrary, omrsig_protected_fn fn, void
return 0;
}

/* Check to see if we have already installed a masterHandler for these signal(s).
* We will need to aquire the masterHandlerMonitor if flagsWithoutMasterHandlers is not 0 in order to install the handlers (and to check if another thread had "just" taken care of it).
* If we do have masterHandlers installed already then OMRPORT_SIG_OPTIONS_REDUCED_SIGNALS_SYNCHRONOUS has not been set.
*/
flagsSignalsOnly = flags & OMRPORT_SIG_FLAG_SIGALLSYNC;
flagsWithoutMasterHandlers = flagsSignalsOnly & (~signalsWithMasterHandlers);

if (0 != flagsWithoutMasterHandlers) {

if (0 != flagsSignalsOnly) {
/* we have not installed handlers for all the signals, aquire the masterHandlerMonitor, check again and install handlers as required all done in registerMasterHandlers */
omrthread_monitor_enter(masterHandlerMonitor);
rc = registerMasterHandlers(portLibrary, flags, OMRPORT_SIG_FLAG_SIGALLSYNC);
Expand Down Expand Up @@ -1256,7 +1249,6 @@ static int32_t
registerMasterHandlers(OMRPortLibrary *portLibrary, uint32_t flags, uint32_t allowedSubsetOfFlags)
{
uint32_t flagsSignalsOnly = 0;
uint32_t flagsWithoutHandlers = 0;
unix_sigaction handler = NULL;

if (OMRPORT_SIG_FLAG_SIGALLSYNC == allowedSubsetOfFlags) {
Expand All @@ -1268,24 +1260,21 @@ registerMasterHandlers(OMRPortLibrary *portLibrary, uint32_t flags, uint32_t all
}

flagsSignalsOnly = flags & allowedSubsetOfFlags;
flagsWithoutHandlers = flagsSignalsOnly & (~signalsWithMasterHandlers);

if (0 != flagsWithoutHandlers) {
if (0 != flagsSignalsOnly) {
/* registering some handlers */
uint32_t portSignalType = 0;

/* portSignalType starts off at 4 as it is the smallest synch
* signal. In the case that we are registering an asynch
* signal, flagsWithoutHandlers already has masked off the
* signal, flagsSignalsOnly already has masked off the
* synchronous signals (eg. "4") so we are not at risk of registering a handler
* for an incorrect signal
*/
for (portSignalType = 4; portSignalType < allowedSubsetOfFlags; portSignalType = portSignalType << 1) {
/* iterate through all the signals and register the master handler for those that don't have one yet */

if (OMR_ARE_ANY_BITS_SET(flagsWithoutHandlers, portSignalType)) {
if (OMR_ARE_ANY_BITS_SET(flagsSignalsOnly, portSignalType)) {
/* we need a master handler for this (portSignalType's) signal */

if (0 != registerSignalHandlerWithOS(portLibrary, portSignalType, handler)) {
return OMRPORT_SIG_ERROR;
}
Expand Down

0 comments on commit ed5a742

Please sign in to comment.