Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Use synchmanager worker thread to handle process termination requests.
Browse files Browse the repository at this point in the history
  • Loading branch information
adityamandaleeka committed Apr 26, 2016
1 parent 5aa1bfe commit 975a4f9
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 245 deletions.
3 changes: 1 addition & 2 deletions src/pal/inc/pal.h
Original file line number Diff line number Diff line change
Expand Up @@ -480,10 +480,9 @@ typedef long time_t;
#define PAL_INITIALIZE_SYNC_THREAD 0x01
#define PAL_INITIALIZE_EXEC_ALLOCATOR 0x02
#define PAL_INITIALIZE_STD_HANDLES 0x04
#define PAL_INITIALIZE_SIGNAL_THREAD 0x08

// PAL_Initialize() flags
#define PAL_INITIALIZE (PAL_INITIALIZE_SYNC_THREAD | PAL_INITIALIZE_STD_HANDLES | PAL_INITIALIZE_SIGNAL_THREAD)
#define PAL_INITIALIZE (PAL_INITIALIZE_SYNC_THREAD | PAL_INITIALIZE_STD_HANDLES)

// PAL_InitializeDLL() flags - don't start any of the helper threads
#define PAL_INITIALIZE_DLL PAL_INITIALIZE_NONE
Expand Down
50 changes: 0 additions & 50 deletions src/pal/src/exception/seh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,6 @@ PHARDWARE_EXCEPTION_SAFETY_CHECK_FUNCTION g_safeExceptionCheckFunction = NULL;

PGET_GCMARKER_EXCEPTION_CODE g_getGcMarkerExceptionCode = NULL;

PTERMINATION_REQUEST_HANDLER g_terminationRequestHandler = nullptr;

/* Internal function declarations *********************************************/

#if !HAVE_MACH_EXCEPTIONS
PAL_ERROR
StartExternalSignalHandlerThread(
CPalThread *pthr);
#endif // !HAVE_MACH_EXCEPTIONS

/* Internal function definitions **********************************************/

/*++
Expand All @@ -93,17 +83,6 @@ SEHInitialize (CPalThread *pthrCurrent, DWORD flags)
SEHCleanup();
return FALSE;
}

if (flags & PAL_INITIALIZE_SIGNAL_THREAD)
{
PAL_ERROR palError = StartExternalSignalHandlerThread(pthrCurrent);
if (palError != NO_ERROR)
{
ERROR("StartExternalSignalHandlerThread returned %d\n", palError);
SEHCleanup();
return FALSE;
}
}
#endif

return TRUE;
Expand Down Expand Up @@ -155,26 +134,6 @@ PAL_SetHardwareExceptionHandler(
g_safeExceptionCheckFunction = exceptionCheckFunction;
}

/*++
Function:
PAL_SetTerminationRequestHandler
Register a termination request handler.
Parameters:
terminationHandler - handler for termination request
Return value:
None
--*/
VOID
PALAPI
PAL_SetTerminationRequestHandler(
IN PTERMINATION_REQUEST_HANDLER terminationHandler)
{
g_terminationRequestHandler = terminationHandler;
}

/*++
Function:
PAL_SetGetGcMarkerExceptionCode
Expand Down Expand Up @@ -294,15 +253,6 @@ SEHProcessException(PEXCEPTION_POINTERS pointers)
// Unhandled hardware exception pointers->ExceptionRecord->ExceptionCode at pointers->ExceptionRecord->ExceptionAddress
}

VOID
SEHHandleTerminationRequest()
{
if (g_terminationRequestHandler != NULL)
{
g_terminationRequestHandler();
}
}

/*++
Function :
SEHEnable
Expand Down
154 changes: 6 additions & 148 deletions src/pal/src/exception/signal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,6 @@ struct sigaction g_previous_sigint;
struct sigaction g_previous_sigquit;
struct sigaction g_previous_sigterm;

// Pipe used for sending signal notifications to a helper thread
int g_signalPipe[2] = { 0, 0 };

DWORD g_dwExternalSignalHandlerThreadId = 0;

/* public function definitions ************************************************/

/*++
Expand Down Expand Up @@ -137,6 +132,7 @@ BOOL SEHInitializeSignals()
handle_signal(SIGSEGV, sigsegv_handler, &g_previous_sigsegv);
handle_signal(SIGINT, sigint_handler, &g_previous_sigint);
handle_signal(SIGQUIT, sigquit_handler, &g_previous_sigquit);
handle_signal(SIGTERM, sigterm_handler, &g_previous_sigterm);

#ifdef INJECT_ACTIVATION_SIGNAL
handle_signal(INJECT_ACTIVATION_SIGNAL, inject_activation_handler, NULL);
Expand Down Expand Up @@ -184,13 +180,7 @@ void SEHCleanupSignals()
restore_signal(SIGSEGV, &g_previous_sigsegv);
restore_signal(SIGINT, &g_previous_sigint);
restore_signal(SIGQUIT, &g_previous_sigquit);

// Only restore if the signal handler thread was started and
// the previous handler was saved.
if (g_dwExternalSignalHandlerThreadId != 0)
{
restore_signal(SIGTERM, &g_previous_sigterm);
}
restore_signal(SIGTERM, &g_previous_sigterm);
}

/* internal function definitions **********************************************/
Expand Down Expand Up @@ -397,34 +387,6 @@ static void sigquit_handler(int code, siginfo_t *siginfo, void *context)
kill(gPID, code);
}

/*++
Function :
HandleExternalSignal
Write to a pipe to kick off handling of the signal.
Parameters :
signalCode - code of the external signal
(no return value)
--*/
static void HandleExternalSignal(int signalCode)
{
BYTE signalCodeByte = (BYTE)signalCode;
ssize_t writtenBytes;
do
{
writtenBytes = write(g_signalPipe[1], &signalCodeByte, 1);
}
while ((writtenBytes == -1) && (errno == EINTR));

if (writtenBytes == -1)
{
// Fatal error
abort();
}
}

/*++
Function :
sigterm_handler
Expand All @@ -440,7 +402,10 @@ static void sigterm_handler(int code, siginfo_t *siginfo, void *context)
{
if (PALIsInitialized())
{
HandleExternalSignal(code);
// g_pSynchronizationManager shouldn't be null if PAL is initialized.
_ASSERTE(g_pSynchronizationManager != nullptr);

g_pSynchronizationManager->SendTerminationRequestToWorkerThread();
}
else
{
Expand Down Expand Up @@ -693,111 +658,4 @@ void restore_signal(int signal_id, struct sigaction *previousAction)
}
}

static
DWORD
PALAPI
ExternalSignalHandlerThreadRoutine(
PVOID
);

PAL_ERROR
StartExternalSignalHandlerThread(
CPalThread *pthr)
{
PAL_ERROR palError = NO_ERROR;

#ifndef DO_NOT_USE_SIGNAL_HANDLING_THREAD
HANDLE hThread;

if (pipe(g_signalPipe) != 0)
{
palError = ERROR_CANNOT_MAKE;
goto done;
}

palError = InternalCreateThread(
pthr,
NULL,
0,
ExternalSignalHandlerThreadRoutine,
NULL,
0,
SignalHandlerThread, // Want no_suspend variant
&g_dwExternalSignalHandlerThreadId,
&hThread
);

if (palError != NO_ERROR)
{
ERROR("Failure creating external signal handler thread (%d)\n", palError);
goto done;
}

InternalCloseHandle(pthr, hThread);

handle_signal(SIGTERM, sigterm_handler, &g_previous_sigterm);
#endif // DO_NOT_USE_SIGNAL_HANDLING_THREAD

done:

return palError;
}

static
DWORD
PALAPI
ExternalSignalHandlerThreadRoutine(
PVOID
)
{
DWORD dwThreadId;
bool fContinue = TRUE;
HANDLE hThread;
PAL_ERROR palError = NO_ERROR;
CPalThread *pthr = InternalGetCurrentThread();

//
// Wait for a signal to occur
//

while (fContinue)
{
BYTE signalCode;
ssize_t bytesRead;

do
{
bytesRead = read(g_signalPipe[0], &signalCode, 1);
}
while ((bytesRead == -1) && (errno == EINTR));

if (bytesRead == -1)
{
// Fatal error
abort();
}

switch (signalCode)
{
case SIGTERM:
{
SEHHandleTerminationRequest();
}

default:
ASSERT("Unexpected signal %d in signal thread\n", signalCode);
abort();
break;
}
}

//
// Perform an immediate (non-graceful) shutdown
//

_exit(EXIT_FAILURE);

return 0;
}

#endif // !HAVE_MACH_EXCEPTIONS
4 changes: 4 additions & 0 deletions src/pal/src/include/pal/corunix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,10 @@ namespace CorUnix
CPalThread *pThread
) = 0;

virtual
PAL_ERROR
SendTerminationRequestToWorkerThread() = 0;

//
// This routine is primarily meant for use by WaitForMultipleObjects[Ex].
// The caller must individually release each of the returned controller
Expand Down
12 changes: 0 additions & 12 deletions src/pal/src/include/pal/seh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,6 @@ Return value:
VOID
SEHProcessException(PEXCEPTION_POINTERS pointers);

/*++
Function:
SEHHandleTerminationRequest
Send a process termination request to a registered handler.
Parameters:
None
--*/
VOID
SEHHandleTerminationRequest();

#if !HAVE_MACH_EXCEPTIONS
// TODO: Implement for Mach exceptions. Not in CoreCLR surface area.
/*++
Expand Down
Loading

0 comments on commit 975a4f9

Please sign in to comment.