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

Commit

Permalink
fix Issue 8960 - Unable to set thread priority
Browse files Browse the repository at this point in the history
- Ignore error when get-/setting the priority of a terminated thread.
  • Loading branch information
MartinNowak committed Sep 21, 2014
1 parent 05c9db3 commit 62696b4
Showing 1 changed file with 51 additions and 20 deletions.
71 changes: 51 additions & 20 deletions src/core/thread.d
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ else version( Posix )
obj.m_main.tstack = obj.m_main.bstack;
obj.m_tlsgcdata = rt_tlsgc_init();

obj.m_isRunning = true;
atomicStore!(MemoryOrder.raw)(obj.m_isRunning, true);
Thread.setThis( obj );
//Thread.add( obj );
scope( exit )
Expand All @@ -301,7 +301,7 @@ else version( Posix )
// removed or a double-removal could occur between this
// function and thread_suspendAll.
Thread.remove( obj );
obj.m_isRunning = false;
atomicStore!(MemoryOrder.raw)(obj.m_isRunning,false);
}
Thread.add( &obj.m_main );

Expand All @@ -314,7 +314,7 @@ else version( Posix )
// not running and let thread_suspendAll remove it from
// the thread list. This is safer and is consistent
// with the Windows thread code.
obj.m_isRunning = false;
atomicStore!(MemoryOrder.raw)(obj.m_isRunning,false);
}

// NOTE: Using void to skip the initialization here relies on
Expand Down Expand Up @@ -684,8 +684,8 @@ class Thread
// NOTE: This is also set to true by thread_entryPoint, but set it
// here as well so the calling thread will see the isRunning
// state immediately.
m_isRunning = true;
scope( failure ) m_isRunning = false;
atomicStore!(MemoryOrder.raw)(m_isRunning, true);
scope( failure ) atomicStore!(MemoryOrder.raw)(m_isRunning, false);

version (Shared)
{
Expand Down Expand Up @@ -873,10 +873,7 @@ class Thread
}
else version( Posix )
{
// NOTE: It should be safe to access this value without
// memory barriers because word-tearing and such
// really isn't an issue for boolean values.
return m_isRunning;
return atomicLoad(m_isRunning);
}
}

Expand Down Expand Up @@ -916,6 +913,9 @@ class Thread
/**
* Gets the scheduling priority for the associated thread.
*
* Note: Getting the priority of a thread that already terminated
* might return the default priority.
*
* Returns:
* The scheduling priority of this thread.
*/
Expand All @@ -930,8 +930,12 @@ class Thread
int policy;
sched_param param;

if( pthread_getschedparam( m_addr, &policy, &param ) )
throw new ThreadException( "Unable to get thread priority" );
if (auto err = pthread_getschedparam(m_addr, &policy, &param))
{
// ignore error if thread is not running => Bugzilla 8960
if (!atomicLoad(m_isRunning)) return PRIORITY_DEFAULT;
throw new ThreadException("Unable to get thread priority");
}
return param.sched_priority;
}
}
Expand All @@ -940,6 +944,9 @@ class Thread
/**
* Sets the scheduling priority for the associated thread.
*
* Note: Setting the priority of a thread that already terminated
* might have no effect.
*
* Params:
* val = The new scheduling priority of this thread.
*/
Expand Down Expand Up @@ -984,10 +991,14 @@ class Thread
}
else version( Posix )
{
static if( __traits( compiles, pthread_setschedprio ) )
static if(__traits(compiles, pthread_setschedprio))
{
if( pthread_setschedprio( m_addr, val ) )
throw new ThreadException( "Unable to set thread priority" );
if (auto err = pthread_setschedprio(m_addr, val))
{
// ignore error if thread is not running => Bugzilla 8960
if (!atomicLoad(m_isRunning)) return;
throw new ThreadException("Unable to set thread priority");
}
}
else
{
Expand All @@ -996,11 +1007,19 @@ class Thread
int policy;
sched_param param;

if( pthread_getschedparam( m_addr, &policy, &param ) )
throw new ThreadException( "Unable to set thread priority" );
if (auto err = pthread_getschedparam(m_addr, &policy, &param))
{
// ignore error if thread is not running => Bugzilla 8960
if (!atomicLoad(m_isRunning)) return;
throw new ThreadException("Unable to set thread priority");
}
param.sched_priority = val;
if( pthread_setschedparam( m_addr, policy, &param ) )
throw new ThreadException( "Unable to set thread priority" );
if (auto err = pthread_setschedparam(m_addr, policy, &param))
{
// ignore error if thread is not running => Bugzilla 8960
if (!atomicLoad(m_isRunning)) return;
throw new ThreadException("Unable to set thread priority");
}
}
}
}
Expand All @@ -1020,6 +1039,18 @@ class Thread
assert(thr.priority == PRIORITY_MAX);
}

unittest // Bugzilla 8960
{
import core.sync.semaphore;

auto thr = new Thread({});
thr.start();
Thread.sleep(1.msecs); // wait a little so the thread likely has finished
thr.priority = PRIORITY_MAX; // setting priority doesn't cause error
auto prio = thr.priority; // getting priority doesn't cause error
assert(prio >= PRIORITY_MIN && prio <= PRIORITY_MAX);
}

///////////////////////////////////////////////////////////////////////////
// Actions on Calling Thread
///////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1392,7 +1423,7 @@ private:
size_t m_sz;
version( Posix )
{
bool m_isRunning;
shared bool m_isRunning;
}
bool m_isDaemon;
bool m_isInCriticalRegion;
Expand Down Expand Up @@ -1989,7 +2020,7 @@ extern (C) Thread thread_attachThis()
thisContext.bstack = getStackBottom();
thisContext.tstack = thisContext.bstack;

thisThread.m_isRunning = true;
atomicStore!(MemoryOrder.raw)(thisThread.m_isRunning, true);
}
thisThread.m_isDaemon = true;
thisThread.m_tlsgcdata = rt_tlsgc_init();
Expand Down

0 comments on commit 62696b4

Please sign in to comment.