Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
fix Issue 13416 - dead-lock in FreeBSD suspend handler
Browse files Browse the repository at this point in the history
- use pthread internal THR_IN_CRITICAL to retry suspend
  • Loading branch information
MartinNowak committed Dec 7, 2014
1 parent 72e07b0 commit ad8662d
Showing 1 changed file with 42 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/core/thread.d
Expand Up @@ -418,6 +418,7 @@ else version( Posix )
status = sigdelset( &sigres, resumeSignalNumber );
assert( status == 0 );

version (FreeBSD) Thread.sm_suspendagain = false;
status = sem_post( &suspendCount );
assert( status == 0 );

Expand All @@ -429,6 +430,17 @@ else version( Posix )
}
}

// avoid deadlocks on FreeBSD, see Issue 13416
version (FreeBSD)
{
if (THR_IN_CRITICAL(pthread_self()))
{
Thread.sm_suspendagain = true;
if (sem_post(&suspendCount)) assert(0);
return;
}
}

callWithStackShell(&op);
}

Expand All @@ -442,6 +454,24 @@ else version( Posix )
{

}

// HACK to avoid deadlocks on FreeBSD, see Issue 13416
version (FreeBSD) bool THR_IN_CRITICAL(pthread_t p) nothrow @nogc
{
import core.sys.posix.sys.types : c_long, lwpid_t;
static struct pthread
{
c_long tid;
static struct umutex { lwpid_t owner; uint flags; uint[2] ceilings; uint[4] spare; }
umutex lock;
uint cycle;
int locklevel;
int critical_count;
// ...
}
auto priv = cast(pthread*)p;
return priv.locklevel > 0 || priv.critical_count > 0;
}
}
}
else
Expand Down Expand Up @@ -1350,6 +1380,12 @@ private:
//
__gshared Thread sm_main;

version (FreeBSD)
{
// set when suspend failed and should be retried, see Issue 13416
static shared bool sm_suspendagain;
}


//
// Standard thread data
Expand Down Expand Up @@ -2466,6 +2502,7 @@ private void suspend( Thread t ) nothrow
{
if( t.m_addr != pthread_self() )
{
Lagain:
if( pthread_kill( t.m_addr, suspendSignalNumber ) != 0 )
{
if( !t.isRunning )
Expand All @@ -2481,6 +2518,11 @@ private void suspend( Thread t ) nothrow
onThreadError( "Unable to wait for semaphore" );
errno = 0;
}
version (FreeBSD)
{
// avoid deadlocks, see Issue 13416
if (Thread.sm_suspendagain) goto Lagain;
}
}
else if( !t.m_lock )
{
Expand Down

0 comments on commit ad8662d

Please sign in to comment.