Skip to content

Commit

Permalink
Added signal handlers so owned semaphores are signaled after a crash.
Browse files Browse the repository at this point in the history
  • Loading branch information
macmade committed Mar 22, 2017
1 parent 4a20e90 commit 707aebc
Show file tree
Hide file tree
Showing 2 changed files with 204 additions and 2 deletions.
80 changes: 80 additions & 0 deletions CPPAtomic.xcodeproj/xcshareddata/xcschemes/CPPAtomic.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0820"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "05EC8A461E81E854007233F2"
BuildableName = "libCPPAtomic.a"
BlueprintName = "CPPAtomic"
ReferencedContainer = "container:CPPAtomic.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "05EC8A461E81E854007233F2"
BuildableName = "libCPPAtomic.a"
BlueprintName = "CPPAtomic"
ReferencedContainer = "container:CPPAtomic.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "05EC8A461E81E854007233F2"
BuildableName = "libCPPAtomic.a"
BlueprintName = "CPPAtomic"
ReferencedContainer = "container:CPPAtomic.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
126 changes: 124 additions & 2 deletions CPPAtomic/source/IPC/Semaphore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,26 @@
#include <mach/mach_init.h>
#include <mach/task.h>
#include <mach/semaphore.h>
#include <signal.h>
#else
#include <Windows.h>
#include <locale>
#include <codecvt>
#endif

#include <mutex>
#include <vector>

#ifndef SEM_NAME_MAX
#define SEM_NAME_MAX 32
#endif

static void init( void );
static void cleanup( void );

static std::recursive_mutex * rmtx = nullptr;
static std::vector< XS::IPC::Semaphore * > * semaphores = nullptr;

namespace XS
{
template<>
Expand Down Expand Up @@ -131,9 +141,11 @@ namespace XS

bool Semaphore::TryWait( void )
{
bool ret;

if( this->IsNamed() )
{
return ( sem_trywait( this->impl->_semp ) == 0 ) ? true : false;
ret = ( sem_trywait( this->impl->_semp ) == 0 ) ? true : false;
}
else
{
Expand All @@ -143,9 +155,18 @@ namespace XS
ts.tv_sec = 0;
ts.tv_nsec = 0;

return ( semaphore_timedwait( this->impl->_semaphore, ts ) == KERN_SUCCESS ) ? true : false;
ret = ( semaphore_timedwait( this->impl->_semaphore, ts ) == KERN_SUCCESS ) ? true : false;
}
}

if( ret )
{
rmtx->lock();
semaphores->push_back( this );
rmtx->unlock();
}

return ret;
}

void Semaphore::Wait( void )
Expand All @@ -158,6 +179,10 @@ namespace XS
{
semaphore_wait( this->impl->_semaphore );
}

rmtx->lock();
semaphores->push_back( this );
rmtx->unlock();
}

void Semaphore::Signal( void )
Expand All @@ -170,6 +195,10 @@ namespace XS
{
semaphore_signal( this->impl->_semaphore );
}

rmtx->lock();
semaphores->erase( std::find( semaphores->begin(), semaphores->end(), this ) );
rmtx->unlock();
}

#endif
Expand All @@ -183,6 +212,10 @@ namespace XS
_count( count ),
_name( name )
{
std::once_flag once;

std::call_once( once, init );

this->CreateSemaphore();
}

Expand Down Expand Up @@ -289,3 +322,92 @@ namespace XS

#endif
}

#ifdef _WIN32

static void init( void )
{
rmtx = new std::recursive_mutex();
semaphores = new std::vector< XS::IPC::Semaphore * >();
}

#elif defined( __APPLE__ )

#include <iostream>

static void sig( int signo );

static struct sigaction sigaction_sigabrt = {};
static struct sigaction sigaction_sigsegv = {};
static struct sigaction sigaction_sigbus = {};
static struct sigaction sigaction_sigill = {};
static struct sigaction sigaction_sigfpe = {};
static struct sigaction sigaction_sigpipe = {};
static struct sigaction sigaction_prev_sigabrt = {};
static struct sigaction sigaction_prev_sigsegv = {};
static struct sigaction sigaction_prev_sigbus = {};
static struct sigaction sigaction_prev_sigill = {};
static struct sigaction sigaction_prev_sigfpe = {};
static struct sigaction sigaction_prev_sigpipe = {};

static void init( void )
{
rmtx = new std::recursive_mutex();
semaphores = new std::vector< XS::IPC::Semaphore * >();

memset( &sigaction_sigabrt, 0, sizeof( struct sigaction ) );
memset( &sigaction_sigsegv, 0, sizeof( struct sigaction ) );
memset( &sigaction_sigbus, 0, sizeof( struct sigaction ) );
memset( &sigaction_sigill, 0, sizeof( struct sigaction ) );
memset( &sigaction_sigfpe, 0, sizeof( struct sigaction ) );
memset( &sigaction_sigpipe, 0, sizeof( struct sigaction ) );

memset( &sigaction_prev_sigabrt, 0, sizeof( struct sigaction ) );
memset( &sigaction_prev_sigsegv, 0, sizeof( struct sigaction ) );
memset( &sigaction_prev_sigbus, 0, sizeof( struct sigaction ) );
memset( &sigaction_prev_sigill, 0, sizeof( struct sigaction ) );
memset( &sigaction_prev_sigfpe, 0, sizeof( struct sigaction ) );
memset( &sigaction_prev_sigpipe, 0, sizeof( struct sigaction ) );

sigaction_sigabrt.sa_handler = sig;
sigaction_sigsegv.sa_handler = sig;
sigaction_sigbus.sa_handler = sig;
sigaction_sigill.sa_handler = sig;
sigaction_sigfpe.sa_handler = sig;
sigaction_sigpipe.sa_handler = sig;

sigaction( SIGABRT, &sigaction_sigabrt, &sigaction_prev_sigabrt );
sigaction( SIGSEGV, &sigaction_sigsegv, &sigaction_prev_sigsegv );
sigaction( SIGBUS, &sigaction_sigbus, &sigaction_prev_sigbus );
sigaction( SIGILL, &sigaction_sigill, &sigaction_prev_sigill );
sigaction( SIGFPE, &sigaction_sigfpe, &sigaction_prev_sigfpe );
sigaction( SIGPIPE, &sigaction_sigpipe, &sigaction_prev_sigpipe );
}

static void sig( int signo )
{
cleanup();

switch( signo )
{
case SIGABRT: sigaction( SIGABRT, &sigaction_prev_sigabrt, nullptr ); break;
case SIGSEGV: sigaction( SIGSEGV, &sigaction_prev_sigsegv, nullptr ); break;
case SIGBUS: sigaction( SIGBUS, &sigaction_prev_sigbus, nullptr ); break;
case SIGILL: sigaction( SIGILL, &sigaction_prev_sigill, nullptr ); break;
case SIGFPE: sigaction( SIGFPE, &sigaction_prev_sigfpe, nullptr ); break;
case SIGPIPE: sigaction( SIGPIPE, &sigaction_prev_sigpipe, nullptr ); break;
default: break;
}
}

#endif

static void cleanup( void )
{
for( auto s: *( semaphores ) )
{
s->Signal();
}

semaphores->clear();
}

0 comments on commit 707aebc

Please sign in to comment.