Skip to content

Commit

Permalink
Merge pull request #2524 from babsingh/signal_register_changes
Browse files Browse the repository at this point in the history
Extend OMR Signal API [Part 2]
  • Loading branch information
charliegracie authored May 14, 2018
2 parents ba2a966 + 75f00a1 commit 53cb267
Show file tree
Hide file tree
Showing 10 changed files with 224 additions and 64 deletions.
2 changes: 1 addition & 1 deletion fvtest/porttest/omrsignalTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1100,7 +1100,7 @@ TEST(PortSigTest, sig_test_async_unix_handler)
OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());
const char *testName = "omrsig_test_async_unix_handler";
AsyncHandlerInfo handlerInfo;
uint32_t setAsyncRC;
int32_t setAsyncRC;
unsigned int index;
omrthread_monitor_t asyncMonitor;
intptr_t monitorRC;
Expand Down
5 changes: 4 additions & 1 deletion include_core/omrport.h
Original file line number Diff line number Diff line change
Expand Up @@ -1382,13 +1382,15 @@ typedef struct OMRPortLibrary {
/** see @ref omrsignal.c::omrsig_can_protect "omrsig_can_protect"*/
int32_t (*sig_can_protect)(struct OMRPortLibrary *portLibrary, uint32_t flags) ;
/** see @ref omrsignal.c::omrsig_set_async_signal_handler "omrsig_set_async_signal_handler"*/
uint32_t (*sig_set_async_signal_handler)(struct OMRPortLibrary *portLibrary, omrsig_handler_fn handler, void *handler_arg, uint32_t flags) ;
int32_t (*sig_set_async_signal_handler)(struct OMRPortLibrary *portLibrary, omrsig_handler_fn handler, void *handler_arg, uint32_t flags) ;
/** see @ref omrsignal.c::omrsig_set_single_async_signal_handler "omrsig_set_single_async_signal_handler"*/
int32_t (*sig_set_single_async_signal_handler)(struct OMRPortLibrary *portLibrary, omrsig_handler_fn handler, void *handler_arg, uint32_t portlibSignalFlag, void **oldOSHandler) ;
/** see @ref omrsignal.c::omrsig_map_os_signal_to_portlib_signal "omrsig_map_os_signal_to_portlib_signal"*/
uint32_t (*sig_map_os_signal_to_portlib_signal)(struct OMRPortLibrary *portLibrary, uint32_t osSignalValue) ;
/** see @ref omrsignal.c::omrsig_map_portlib_signal_to_os_signal "omrsig_map_portlib_signal_to_os_signal"*/
int32_t (*sig_map_portlib_signal_to_os_signal)(struct OMRPortLibrary *portLibrary, uint32_t portlibSignalFlag) ;
/** see @ref omrsignal.c::omrsig_register_os_handler "omrsig_register_os_handler"*/
int32_t (*sig_register_os_handler)(struct OMRPortLibrary *portLibrary, uint32_t portlibSignalFlag, void *newOSHandler, void **oldOSHandler) ;
/** see @ref omrsignal.c::omrsig_info "omrsig_info"*/
uint32_t (*sig_info)(struct OMRPortLibrary *portLibrary, void *info, uint32_t category, int32_t index, const char **name, void **value) ;
/** see @ref omrsignal.c::omrsig_info_count "omrsig_info_count"*/
Expand Down Expand Up @@ -1890,6 +1892,7 @@ extern J9_CFUNC int32_t omrport_getVersion(struct OMRPortLibrary *portLibrary);
#define omrsig_set_single_async_signal_handler(param1,param2,param3,param4) privateOmrPortLibrary->sig_set_single_async_signal_handler(privateOmrPortLibrary, (param1), (param2), (param3), (param4))
#define omrsig_map_os_signal_to_portlib_signal(param1) privateOmrPortLibrary->sig_map_os_signal_to_portlib_signal(privateOmrPortLibrary, (param1))
#define omrsig_map_portlib_signal_to_os_signal(param1) privateOmrPortLibrary->sig_map_portlib_signal_to_os_signal(privateOmrPortLibrary, (param1))
#define omrsig_register_os_handler(param1,param2,param3) privateOmrPortLibrary->sig_register_os_handler(privateOmrPortLibrary, (param1), (param2), (param3))
#define omrsig_info(param1,param2,param3,param4,param5) privateOmrPortLibrary->sig_info(privateOmrPortLibrary, (param1), (param2), (param3), (param4), (param5))
#define omrsig_info_count(param1,param2) privateOmrPortLibrary->sig_info_count(privateOmrPortLibrary, (param1), (param2))
#define omrsig_set_options(param1) privateOmrPortLibrary->sig_set_options(privateOmrPortLibrary, (param1))
Expand Down
1 change: 1 addition & 0 deletions port/common/omrport.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ static OMRPortLibrary MasterPortLibraryTable = {
omrsig_set_single_async_signal_handler, /* sig_set_single_async_signal_handler */
omrsig_map_os_signal_to_portlib_signal, /* sig_map_os_signal_to_portlib_signal */
omrsig_map_portlib_signal_to_os_signal, /* sig_map_portlib_signal_to_os_signal */
omrsig_register_os_handler, /* sig_register_os_handler */
omrsig_info, /* sig_info */
omrsig_info_count, /* sig_info_count */
omrsig_set_options, /* sig_set_options */
Expand Down
6 changes: 5 additions & 1 deletion port/common/omrport.tdf
Original file line number Diff line number Diff line change
Expand Up @@ -1064,4 +1064,8 @@ TraceEvent=Trc_PRT_signal_omrsig_set_single_async_signal_handler_user_handler_ad
TraceEvent=Trc_PRT_signal_omrsig_set_single_async_signal_handler_user_handler_added_2 Group=signal Overhead=1 Level=1 NoEnv Template="omrsig_set_single_async_signal_handler: user handler added_2, handler=%p, handler_arg=%p, portlibSignalFlag=0x%X"
TraceExit=Trc_PRT_signal_omrsig_set_single_async_signal_handler_exiting Group=signal Overhead=1 Level=1 NoEnv Template="omrsig_set_single_async_signal_handler: Exiting, rc=%d, handler=%p, handler_arg=%p, portlibSignalFlag=0x%X, oldOSHandler=%p"

TraceException=Trc_PRT_signal_mapOSSignalToPortLib_ERROR_unknown_signal Group=signal Overhead=1 Level=1 NoEnv Template="omrsignal: ERROR unknown OS signal=0x%X"
TraceException=Trc_PRT_signal_mapOSSignalToPortLib_ERROR_unknown_signal Group=signal Overhead=1 Level=1 NoEnv Template="omrsignal: ERROR unknown OS signal=0x%X"

TraceEntry=Trc_PRT_signal_omrsig_register_os_handler_entered Group=signal Overhead=1 Level=1 NoEnv Template="omrsig_register_os_handler: Entered, portLibrarySignalFlag=0x%X, newOSHandler=%p"
TraceExit=Trc_PRT_signal_omrsig_register_os_handler_exiting Group=signal Overhead=1 Level=1 NoEnv Template="omrsig_register_os_handler: Exiting, rc=%d, portLibrarySignalFlag=0x%X, newOSHandler=%p, oldOSHandler=%p"
TraceException=Trc_PRT_signal_omrsig_register_os_handler_invalid_portlibSignalFlag Group=signal Overhead=1 Level=1 NoEnv Template="omrsig_register_os_handler: ERROR, portlibSignalFlag=0x%X is either zero or has multiple signal bits set."
70 changes: 61 additions & 9 deletions port/common/omrsignal.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,25 +163,28 @@ omrsig_protect(struct OMRPortLibrary *portLibrary, omrsig_protected_fn fn, void
* @note A handler should not do anything to cause the reporting thread to terminate (e.g. call omrthread_exit()) as that may prevent
* future signals from being reported.
*
* @return 0 on success
* @return 0 on success or non-zero on failure
*/
uint32_t
int32_t
omrsig_set_async_signal_handler(struct OMRPortLibrary *portLibrary, omrsig_handler_fn handler, void *handler_arg, uint32_t flags)
{
return 1;
return OMRPORT_SIG_ERROR;
}


/*
/**
* @brief Similar to omrsig_set_async_signal_handler. Refer to omrsig_set_async_signal_handler's description above.
* A new element is added to the asyncHandlerList for omrsig_handler_fn, and masterASynchSignalHandler is registered
* with the OS for the signal corresponding to the specified portlibSignalFlag. masterASynchSignalHandler invokes
* asyncHandlerList elements when a relevant signal is raised. If portlibSignalFlag is 0, then the asyncHandlerList
* entry corresponding to omrsig_handler_fn is removed, and related resources are freed. portlibSignalFlag can only
* have one signal flag set; otherwise, OMRPORT_SIG_ERROR is returned. One omrsig_handler_fn handler is registered
* with a signal at any time instead of multiple handlers. When associating a new omrsig_handler_fn with a signal,
* prior omrsig_handler_fn(s) are dissociated from the signal. The address of the old signal handler function is
* stored in oldOSHandler. This function supports all signals listed in OMRPORT_SIG_FLAG_SIGALLASYNC.
* prior omrsig_handler_fn(s) are dissociated from the signal. This function supports all signals listed in
* OMRPORT_SIG_FLAG_SIGALLASYNC.
*
* The address of the old signal handler function is stored in *oldOSHandler. In case of error or if NULL is provided
* for oldOSHandler, then *oldOSHandler is not updated to reflect the old signal handler function.
*
* @param[in] portLibrary The port library
* @param[in] handler the function to call if an asynchronous signal arrives
Expand All @@ -197,21 +200,21 @@ omrsig_set_single_async_signal_handler(struct OMRPortLibrary *portLibrary, omrsi
return OMRPORT_SIG_ERROR;
}

/*
/**
* @brief Given an OS signal value, return the corresponding port library signal flag.
*
* @param[in] portLibrary The port library
* @param[in] osSignalValue OS signal value
*
* @return port library signal flag on success and 0 on failure
*/
*/
uint32_t
omrsig_map_os_signal_to_portlib_signal(struct OMRPortLibrary *portLibrary, uint32_t osSignalValue)
{
return 0;
}

/*
/**
* @brief Given a port library signal flag, return the corresponding OS signal value.
*
* @param[in] portLibrary The port library
Expand All @@ -225,6 +228,55 @@ omrsig_map_portlib_signal_to_os_signal(struct OMRPortLibrary *portLibrary, uint3
return OMRPORT_SIG_ERROR;
}

/**
* @brief Register a handler with the OS. For an invalid portlibSignalFlag, an error is returned.
* portlibSignalFlag is invalid: if it is zero or if multiple signal bits are specified or if the
* specified flag is not supported. If OS fails to register newOSHandler for the specified signal,
* then an error is returned.
*
* The address of the old signal handler function is stored in *oldOSHandler. In case of error or
* if NULL is provided for oldOSHandler, then *oldOSHandler is not updated to reflect the old
* signal handler function.
*
* This function may override a master handler which was previously set by omrsig_protect or
* omrsig_set_*_async_signal_handler variant. The records associated with the master handler
* for the portlibSignalFlag signal are left unchanged when this function overrides the master
* handler. When the master handler is re-registered with the portlibSignalFlag signal, then
* the records associated with master handler don't need to be restored. An example of records
* is J9*AsyncHandlerRecord(s) in asyncHandlerList.
*
* Each platform variant of omrsignal.c should have a signalMap. signalMap should have a list of
* signals, which are supported on a platform. This function supports all signals listed in
* omrsignal.c::signalMap.
*
* On Unix variants, sigaction is used to register the handler. SA_SIGINFO flag is set.
* So, the signature of the signal handling function should be void (*)(int, siginfo_t *, void *).
* On zLinux, the signature changes to void (*)(int, siginfo_t *, void *, uintptr_t).
*
* sigaction isn't available on Windows. On Windows, signal is used to register the handler.
* The signature of the signal handling function should be void (*)(int).
*
* On Unix variants, original OS handler is cached in oldActions while registering the first handler
* with the OS. The original OS handler is restored during shutdown. If OMRSIG_SIGACTION is called outside
* OMR, then the original OS handler can get overwritten without being cached in oldActions. Subsequently,
* the oldActions can cache a user handler instead of the original OS handler. During shutdown, the
* original OS handler can be restored incorrectly. omrsig_register_os_handler lets a user register a
* handler with the OS while properly caching the original OS handler. The original OS handler is properly
* restored during shutdown.
*
* @param[in] portLibrary The port library
* @param[in] portlibSignalFlag a single port library signal flag
* @param[in] newOSHandler the new signal handler function to register
* @param[out] oldOSHandler points to the old signal handler function
*
* @return 0 on success or non-zero on failure
*/
int32_t
omrsig_register_os_handler(struct OMRPortLibrary *portLibrary, uint32_t portlibSignalFlag, void *newOSHandler, void **oldOSHandler)
{
return OMRPORT_SIG_ERROR;
}

/**
* Determine if the port library is capable of protecting a function from the indicated signals in the indicated way.
*
Expand Down
4 changes: 3 additions & 1 deletion port/omrportpriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -547,14 +547,16 @@ extern J9_CFUNC int32_t
omrsig_set_options(struct OMRPortLibrary *portLibrary, uint32_t options);
extern J9_CFUNC int32_t
omrsig_protect(struct OMRPortLibrary *portLibrary, omrsig_protected_fn fn, void *fn_arg, omrsig_handler_fn handler, void *handler_arg, uint32_t flags, uintptr_t *result);
extern J9_CFUNC uint32_t
extern J9_CFUNC int32_t
omrsig_set_async_signal_handler(struct OMRPortLibrary *portLibrary, omrsig_handler_fn handler, void *handler_arg, uint32_t flags);
extern J9_CFUNC int32_t
omrsig_set_single_async_signal_handler(struct OMRPortLibrary *portLibrary, omrsig_handler_fn handler, void *handler_arg, uint32_t portlibSignalFlag, void **oldOSHandler);
extern J9_CFUNC uint32_t
omrsig_map_os_signal_to_portlib_signal(struct OMRPortLibrary *portLibrary, uint32_t osSignalValue);
extern J9_CFUNC int32_t
omrsig_map_portlib_signal_to_os_signal(struct OMRPortLibrary *portLibrary, uint32_t portlibSignalFlag);
extern J9_CFUNC int32_t
omrsig_register_os_handler(struct OMRPortLibrary *portLibrary, uint32_t portlibSignalFlag, void *newOSHandler, void **oldOSHandler);
extern J9_CFUNC uint32_t
omrsig_info(struct OMRPortLibrary *portLibrary, void *info, uint32_t category, int32_t index, const char **name, void **value);
extern J9_CFUNC int32_t
Expand Down
Loading

0 comments on commit 53cb267

Please sign in to comment.