From e87b9678a2498d226fa2a8faff35868fae5765bc Mon Sep 17 00:00:00 2001 From: Babneet Singh Date: Thu, 30 Aug 2018 10:12:07 -0400 Subject: [PATCH] Enable signal chaining and use omrsig in omrsignal.c [win32/win64amd] 1) Calls to signal are replaced with OMRSIG_SIGNAL. OMRSIG_SIGNAL deals with caching application signal handler while registering another OS signal handler. 2) omrsig_handler is called from runHandlers to invoke the application signal handler after J9Win*AsyncHandlerRecord->handler is invoked. Signed-off-by: Babneet Singh --- port/win32/omrsignal.c | 25 ++++++++++++++++++------- port/win64amd/omrsignal.c | 25 ++++++++++++++++++------- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/port/win32/omrsignal.c b/port/win32/omrsignal.c index 0eb8e97cc07..befe49289cd 100644 --- a/port/win32/omrsignal.c +++ b/port/win32/omrsignal.c @@ -22,7 +22,6 @@ #include #include -#include #include "omrport.h" #include "omrthread.h" @@ -31,6 +30,10 @@ #include "omrutilbase.h" #include "ut_omrport.h" +#if defined(OMRPORT_OMRSIG_SUPPORT) +#include "omrsig.h" +#endif /* defined(OMRPORT_OMRSIG_SUPPORT) */ + typedef struct J9Win32AsyncHandlerRecord { OMRPortLibrary *portLib; omrsig_handler_fn handler; @@ -118,7 +121,7 @@ static void masterASynchSignalHandler(int osSignalNo); #if defined(OMR_PORT_ASYNC_HANDLER) static int J9THREAD_PROC asynchSignalReporter(void *userData); -static void runHandlers(uint32_t asyncSignalFlag); +static void runHandlers(uint32_t asyncSignalFlag, int osSignal); #endif /* defined(OMR_PORT_ASYNC_HANDLER) */ static int32_t registerMasterHandlers(OMRPortLibrary *portLibrary, uint32_t flags, uint32_t allowedSubsetOfFlags, void **oldOSHandler); @@ -440,7 +443,7 @@ omrsig_shutdown(struct OMRPortLibrary *portLibrary) /* Register the original signal handlers, which were overwritten. */ for (index = 1; index < ARRAY_SIZE_SIGNALS; index++) { if (0 != handlerInfo[index].restore) { - signal(index, handlerInfo[index].originalHandler); + OMRSIG_SIGNAL(index, handlerInfo[index].originalHandler); /* record that we no longer have a handler installed with the OS for this signal */ Trc_PRT_signal_sig_full_shutdown_deregistered_handler_with_OS(portLibrary, index); handlerInfo[index].restore = 0; @@ -1008,7 +1011,7 @@ registerSignalHandlerWithOS(OMRPortLibrary *portLibrary, uint32_t portLibrarySig return OMRPORT_SIG_ERROR; } - localOldOSHandler = signal(osSignalNo, handler); + localOldOSHandler = OMRSIG_SIGNAL(osSignalNo, handler); if (SIG_ERR == localOldOSHandler) { Trc_PRT_signal_registerSignalHandlerWithOS_failed_to_registerHandler(portLibrarySignalNo, osSignalNo, handler); return OMRPORT_SIG_ERROR; @@ -1137,7 +1140,7 @@ masterASynchSignalHandler(int osSignalNo) /* Signal handler is reset after invocation. So, the signal handler needs to * be registered again after it is invoked. */ - signal(osSignalNo, masterASynchSignalHandler); + OMRSIG_SIGNAL(osSignalNo, masterASynchSignalHandler); } #if defined(OMR_PORT_ASYNC_HANDLER) @@ -1150,7 +1153,7 @@ masterASynchSignalHandler(int osSignalNo) * @return void */ static void -runHandlers(uint32_t asyncSignalFlag) +runHandlers(uint32_t asyncSignalFlag, int osSignal) { J9Win32AsyncHandlerRecord *cursor = NULL; @@ -1173,6 +1176,14 @@ runHandlers(uint32_t asyncSignalFlag) omrthread_monitor_notify_all(asyncMonitor); } omrthread_monitor_exit(asyncMonitor); + +#if defined(OMRPORT_OMRSIG_SUPPORT) + if (OMR_ARE_NO_BITS_SET(signalOptions, OMRPORT_SIG_OPTIONS_OMRSIG_NO_CHAIN)) { + if (OMRPORT_SIG_ERROR != osSignal) { + omrsig_handler(osSignal, NULL, NULL); + } + } +#endif /* defined(OMRPORT_OMRSIG_SUPPORT) */ } /** @@ -1200,7 +1211,7 @@ asynchSignalReporter(void *userData) if (signalCount > 0) { asyncSignalFlag = mapOSSignalToPortLib(osSignal); - runHandlers(asyncSignalFlag); + runHandlers(asyncSignalFlag, osSignal); subtractAtomic(&signalCounts[osSignal], 1); /* j9sem_wait will fall-through for each j9sem_post. We can handle * one signal at a time. Ultimately, all signals will be handled diff --git a/port/win64amd/omrsignal.c b/port/win64amd/omrsignal.c index 06ab2fc9034..9692fd7f48f 100644 --- a/port/win64amd/omrsignal.c +++ b/port/win64amd/omrsignal.c @@ -22,7 +22,6 @@ #include #include -#include #include "omrsignal.h" #include "omrport.h" @@ -31,6 +30,10 @@ #include "omrthread.h" #include "ut_omrport.h" +#if defined(OMRPORT_OMRSIG_SUPPORT) +#include "omrsig.h" +#endif /* defined(OMRPORT_OMRSIG_SUPPORT) */ + /* UNWIND_CODE and UNWIND_INFO are not in the Windows SDK headers, but they are documented on MSDN */ typedef union UNWIND_CODE { struct { @@ -171,7 +174,7 @@ static void removeAsyncHandlers(OMRPortLibrary *portLibrary); #if defined(OMR_PORT_ASYNC_HANDLER) static int J9THREAD_PROC asynchSignalReporter(void *userData); -static void runHandlers(uint32_t asyncSignalFlag); +static void runHandlers(uint32_t asyncSignalFlag, int osSignal); #endif /* defined(OMR_PORT_ASYNC_HANDLER) */ static int32_t registerMasterHandlers(OMRPortLibrary *portLibrary, uint32_t flags, uint32_t allowedSubsetOfFlags, void **oldOSHandler); @@ -1443,7 +1446,7 @@ sig_full_shutdown(struct OMRPortLibrary *portLibrary) /* Register the original signal handlers, which were overwritten. */ for (index = 1; index < ARRAY_SIZE_SIGNALS; index++) { if (handlerInfo[index].restore) { - signal(index, handlerInfo[index].originalHandler); + OMRSIG_SIGNAL(index, handlerInfo[index].originalHandler); /* record that we no longer have a handler installed with the OS for this signal */ Trc_PRT_signal_sig_full_shutdown_deregistered_handler_with_OS(portLibrary, index); handlerInfo[index].restore = 0; @@ -1594,7 +1597,7 @@ registerSignalHandlerWithOS(OMRPortLibrary *portLibrary, uint32_t portLibrarySig return OMRPORT_SIG_ERROR; } - localOldOSHandler = signal(osSignalNo, handler); + localOldOSHandler = OMRSIG_SIGNAL(osSignalNo, handler); if (SIG_ERR == localOldOSHandler) { Trc_PRT_signal_registerSignalHandlerWithOS_failed_to_registerHandler(portLibrarySignalNo, osSignalNo, handler); return OMRPORT_SIG_ERROR; @@ -1644,7 +1647,7 @@ masterASynchSignalHandler(int osSignalNo) /* Signal handler is reset after invocation. So, the signal handler needs to * be registered again after it is invoked. */ - signal(osSignalNo, masterASynchSignalHandler); + OMRSIG_SIGNAL(osSignalNo, masterASynchSignalHandler); } /** @@ -1698,7 +1701,7 @@ removeAsyncHandlers(OMRPortLibrary *portLibrary) * @return void */ static void -runHandlers(uint32_t asyncSignalFlag) +runHandlers(uint32_t asyncSignalFlag, int osSignal) { J9WinAMD64AsyncHandlerRecord *cursor = NULL; @@ -1721,6 +1724,14 @@ runHandlers(uint32_t asyncSignalFlag) omrthread_monitor_notify_all(asyncMonitor); } omrthread_monitor_exit(asyncMonitor); + +#if defined(OMRPORT_OMRSIG_SUPPORT) + if (OMR_ARE_NO_BITS_SET(signalOptions, OMRPORT_SIG_OPTIONS_OMRSIG_NO_CHAIN)) { + if (OMRPORT_SIG_ERROR != osSignal) { + omrsig_handler(osSignal, NULL, NULL); + } + } +#endif /* defined(OMRPORT_OMRSIG_SUPPORT) */ } /** @@ -1748,7 +1759,7 @@ asynchSignalReporter(void *userData) if (signalCount > 0) { asyncSignalFlag = mapOSSignalToPortLib(osSignal); - runHandlers(asyncSignalFlag); + runHandlers(asyncSignalFlag, osSignal); subtractAtomic(&signalCounts[osSignal], 1); /* j9sem_wait will fall-through for each j9sem_post. We can handle * one signal at a time. Ultimately, all signals will be handled