Skip to content

Commit

Permalink
Merge pull request #4554 from babsingh/unblock_signals_update
Browse files Browse the repository at this point in the history
Only unblock an asynchronous signal if it is used
  • Loading branch information
youngar authored Nov 22, 2019
2 parents dcfdf60 + 717082e commit f0489cc
Showing 1 changed file with 24 additions and 28 deletions.
52 changes: 24 additions & 28 deletions port/unix/omrsignal.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ static void masterSynchSignalHandler(int signal, siginfo_t *sigInfo, void *conte
static void masterASynchSignalHandler(int signal, siginfo_t *sigInfo, void *contextInfo);
#endif /* defined(S390) && defined(LINUX) */

static int32_t unblockSignals(void);
static int32_t unblockSignal(int signal);

static void setBitMaskSignalsWithHandlers(uint32_t flags);
static void unsetBitMaskSignalsWithHandlers(uint32_t flags);
Expand Down Expand Up @@ -1269,6 +1269,18 @@ registerSignalHandlerWithOS(OMRPortLibrary *portLibrary, uint32_t portLibrarySig
return OMRPORT_SIG_ERROR;
}

/* If a process has blocked an asynchronous signal, then the signal stays
* blocked in the sub-processes across fork(s) and exec(s). A blocked
* signal prevents its OS signal handler to be invoked. A signal is
* unblocked as an OS signal handler is installed for it in case a
* parent process has blocked it.
*/
if (OMR_ARE_ALL_BITS_SET(OMRPORT_SIG_FLAG_SIGALLASYNC, portLibrarySignalNo)) {
if (0 != unblockSignal(unixSignalNo)) {
return OMRPORT_SIG_ERROR;
}
}

memset(&newAction, 0, sizeof(struct sigaction));

/* Do not block any signals. */
Expand Down Expand Up @@ -1606,16 +1618,6 @@ initializeSignalTools(OMRPortLibrary *portLibrary)
}
#endif /* !defined(J9ZOS390) */

/* If a process has blocked signals, then the signals stay blocked in the
* sub-processes across fork(s) and exec(s). Blocked signals prevent signal
* handlers to be invoked. Signals listed in signalMap should be unblocked
* during initialization in case a parent process has blocked any of those
* signals.
*/
if (0 != unblockSignals()) {
return -1;
}

#if defined(OMR_PORT_ASYNC_HANDLER)
if (J9THREAD_SUCCESS != createThreadWithCategory(
&asynchSignalReporterThread,
Expand Down Expand Up @@ -1870,19 +1872,18 @@ omrsig_chain_at_shutdown_and_exit(struct OMRPortLibrary *portLibrary)
#endif /* defined(OMRPORT_OMRSIG_SUPPORT) */

/**
* This function will unblock signals listed in signalMap by changing the
* signal mask of the calling thread. This function should only be called
* during initialization from the main thread and before creation of other
* threads.
* This function will unblock a signal by changing the signal mask of the
* calling thread. This function is only invoked while registering a signal
* handler with the OS (registerSignalHandlerWithOS), which is protected by
* registerHandlerMonitor for synchronization.
*
* @param[in] void
* @param[in] signal the signal to be unblocked
*
* @return 0 on success and non-zero on failure
*/
static int32_t
unblockSignals(void) {
unblockSignal(int signal) {
int32_t rc = 0;
int i = 0;
sigset_t signalSet;

rc = sigemptyset(&signalSet);
Expand All @@ -1891,18 +1892,13 @@ unblockSignals(void) {
goto exit;
}

/* Iterate through all signals listed in signalMap. */
for (i = 0; i < sizeof(signalMap) / sizeof(signalMap[0]); i++) {
/* Add the current signal to the signal set. */
int currentSignal = signalMap[i].unixSignalNo;
rc = sigaddset(&signalSet, currentSignal);
if (0 != rc) {
Trc_PRT_signal_unblockSignals_sigaddset_failed(currentSignal, rc, errno);
goto exit;
}
rc = sigaddset(&signalSet, signal);
if (0 != rc) {
Trc_PRT_signal_unblockSignals_sigaddset_failed(signal, rc, errno);
goto exit;
}

/* Unblock the signals listed in signalMap. */
/* Unblock the signal. */
rc = pthread_sigmask(SIG_UNBLOCK, &signalSet, NULL);
if (0 != rc) {
Trc_PRT_signal_unblockSignals_pthread_sigmask_failed(rc, errno);
Expand Down

0 comments on commit f0489cc

Please sign in to comment.