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

Commit

Permalink
Merge pull request #1021 from MartinNowak/fiberNothrow
Browse files Browse the repository at this point in the history
nothrow for Fiber
  • Loading branch information
dnadlinger committed Nov 21, 2014
2 parents b143378 + 9b91cb5 commit 0088d0b
Showing 1 changed file with 75 additions and 64 deletions.
139 changes: 75 additions & 64 deletions src/core/thread.d
Original file line number Diff line number Diff line change
Expand Up @@ -98,24 +98,6 @@ class ThreadError : Error
}
}


/**
* Base class for fiber exceptions.
*/
class FiberException : Exception
{
@safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)
{
super(msg, file, line, next);
}

@safe pure nothrow this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__)
{
super(msg, file, line, next);
}
}


private
{
import core.sync.mutex;
Expand Down Expand Up @@ -1096,7 +1078,7 @@ class Thread
/**
* Forces a context switch to occur away from the calling thread.
*/
static void yield()
static void yield() nothrow
{
version( Windows )
SwitchToThread();
Expand Down Expand Up @@ -1605,7 +1587,7 @@ private:
//
// Add a context to the global context list.
//
static void add( Context* c )
static void add( Context* c ) nothrow
in
{
assert( c );
Expand Down Expand Up @@ -1676,7 +1658,7 @@ private:
//
// Add a thread to the global thread list.
//
static void add( Thread t )
static void add( Thread t ) nothrow
in
{
assert( t );
Expand Down Expand Up @@ -3449,9 +3431,9 @@ private

// Look above the definition of 'class Fiber' for some information about the implementation of this routine
version( AsmExternal )
extern (C) void fiber_switchContext( void** oldp, void* newp );
extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow;
else
extern (C) void fiber_switchContext( void** oldp, void* newp )
extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow
{
// NOTE: The data pushed and popped in this routine must match the
// default stack created by Fiber.initStack or the initial
Expand Down Expand Up @@ -3854,7 +3836,7 @@ class Fiber
* In:
* fn must not be null.
*/
this( void function() fn, size_t sz = PAGESIZE*4 )
this( void function() fn, size_t sz = PAGESIZE*4 ) nothrow
in
{
assert( fn );
Expand All @@ -3877,7 +3859,7 @@ class Fiber
* In:
* dg must not be null.
*/
this( void delegate() dg, size_t sz = PAGESIZE*4 )
this( void delegate() dg, size_t sz = PAGESIZE*4 ) nothrow
in
{
assert( dg );
Expand All @@ -3892,7 +3874,7 @@ class Fiber
/**
* Cleans up any remaining resources used by this object.
*/
~this()
~this() nothrow
{
// NOTE: A live reference to this object will exist on its associated
// stack from the first time its call() method has been called
Expand Down Expand Up @@ -3934,7 +3916,35 @@ class Fiber
* Any exception not handled by this fiber if rethrow = false, null
* otherwise.
*/
final Throwable call( bool rethrow = true )
final Throwable call( Rethrow rethrow = Rethrow.yes )
{
return rethrow ? call!(Rethrow.yes)() : call!(Rethrow.no);
}

/// ditto
final Throwable call( Rethrow rethrow )()
{
callImpl();
if( m_unhandled )
{
Throwable t = m_unhandled;
m_unhandled = null;
static if( rethrow )
throw t;
else
return t;
}
return null;
}

/// ditto
deprecated("Please pass Fiber.Rethrow.yes or .no instead of a boolean.")
final Throwable call( bool rethrow )
{
return rethrow ? call!(Rethrow.yes)() : call!(Rethrow.no);
}

private void callImpl() nothrow
in
{
assert( m_state == State.HOLD );
Expand Down Expand Up @@ -3964,17 +3974,10 @@ class Fiber
{
m_ctxt.tstack = m_ctxt.bstack;
}
if( m_unhandled )
{
Throwable t = m_unhandled;
m_unhandled = null;
if( rethrow )
throw t;
return t;
}
return null;
}

/// Flag to control rethrow behavior of $(D $(LREF call))
enum Rethrow : bool { no, yes }

/**
* Resets this fiber so that it may be re-used, optionally with a
Expand All @@ -3987,7 +3990,7 @@ class Fiber
* In:
* This fiber must be in state TERM.
*/
final void reset()
final void reset() nothrow
in
{
assert( m_state == State.TERM || m_state == State.HOLD );
Expand All @@ -4001,15 +4004,15 @@ class Fiber
}

/// ditto
final void reset( void function() fn )
final void reset( void function() fn ) nothrow
{
reset();
m_fn = fn;
m_call = Call.FN;
}

/// ditto
final void reset( void delegate() dg )
final void reset( void delegate() dg ) nothrow
{
reset();
m_dg = dg;
Expand Down Expand Up @@ -4042,7 +4045,7 @@ class Fiber
* Returns:
* The state of this fiber as an enumerated value.
*/
final @property State state() const
final @property State state() const nothrow
{
return m_state;
}
Expand All @@ -4056,7 +4059,7 @@ class Fiber
/**
* Forces a context switch to occur away from the calling fiber.
*/
static void yield()
static void yield() nothrow
{
Fiber cur = getThis();
assert( cur, "Fiber.yield() called with no active fiber" );
Expand All @@ -4081,7 +4084,7 @@ class Fiber
* In:
* t must not be null.
*/
static void yieldAndThrow( Throwable t )
static void yieldAndThrow( Throwable t ) nothrow
in
{
assert( t );
Expand Down Expand Up @@ -4115,7 +4118,7 @@ class Fiber
* The fiber object representing the calling fiber or null if no fiber
* is currently active within this thread. The result of deleting this object is undefined.
*/
static Fiber getThis()
static Fiber getThis() nothrow
{
return sm_this;
}
Expand All @@ -4142,7 +4145,7 @@ private:
//
// Initializes a fiber object which has no associated executable function.
//
this()
this() nothrow
{
m_call = Call.NO;
}
Expand Down Expand Up @@ -4203,7 +4206,7 @@ private:
//
// Allocate a new stack for this fiber.
//
final void allocStack( size_t sz )
final void allocStack( size_t sz ) nothrow
in
{
assert( !m_pmem && !m_ctxt );
Expand Down Expand Up @@ -4232,9 +4235,7 @@ private:
MEM_RESERVE,
PAGE_NOACCESS );
if( !m_pmem )
{
throw new FiberException( "Unable to reserve memory for stack" );
}
onOutOfMemoryError();

version( StackGrowsDown )
{
Expand All @@ -4255,19 +4256,15 @@ private:
MEM_COMMIT,
PAGE_READWRITE );
if( !stack )
{
throw new FiberException( "Unable to allocate memory for stack" );
}
onOutOfMemoryError();

// allocate reserved guard page
guard = VirtualAlloc( guard,
PAGESIZE,
MEM_COMMIT,
PAGE_READWRITE | PAGE_GUARD );
if( !guard )
{
throw new FiberException( "Unable to create guard page for stack" );
}
onOutOfMemoryError();

m_ctxt.bstack = pbase;
m_ctxt.tstack = pbase;
Expand Down Expand Up @@ -4303,9 +4300,7 @@ private:
}

if( !m_pmem )
{
throw new FiberException( "Unable to allocate memory for stack" );
}
onOutOfMemoryError();

version( StackGrowsDown )
{
Expand All @@ -4327,7 +4322,7 @@ private:
//
// Free this fiber's stack.
//
final void freeStack()
final void freeStack() nothrow
in
{
assert( m_pmem && m_ctxt );
Expand Down Expand Up @@ -4369,7 +4364,7 @@ private:
// Initialize the allocated stack.
// Look above the definition of 'class Fiber' for some information about the implementation of this routine
//
final void initStack()
final void initStack() nothrow
in
{
assert( m_ctxt.tstack && m_ctxt.tstack == m_ctxt.bstack );
Expand All @@ -4380,7 +4375,7 @@ private:
void* pstack = m_ctxt.tstack;
scope( exit ) m_ctxt.tstack = pstack;

void push( size_t val )
void push( size_t val ) nothrow
{
version( StackGrowsDown )
{
Expand Down Expand Up @@ -4447,7 +4442,7 @@ private:
__gshared static fp_t finalHandler = null;
if ( finalHandler is null )
{
static EXCEPTION_REGISTRATION* fs0()
static EXCEPTION_REGISTRATION* fs0() nothrow
{
asm pure nothrow @nogc
{
Expand Down Expand Up @@ -4698,7 +4693,7 @@ private:
//
// Sets a thread-local reference to the current fiber object.
//
static void setThis( Fiber f )
static void setThis( Fiber f ) nothrow
{
sm_this = f;
}
Expand All @@ -4715,7 +4710,7 @@ private:
//
// Switches into the stack held by this fiber.
//
final void switchIn()
final void switchIn() nothrow
{
Thread tobj = Thread.getThis();
void** oldp = &tobj.m_curr.tstack;
Expand Down Expand Up @@ -4749,7 +4744,7 @@ private:
//
// Switches out of the current stack and into the enclosing stack.
//
final void switchOut()
final void switchOut() nothrow
{
Thread tobj = Thread.getThis();
void** oldp = &m_ctxt.tstack;
Expand Down Expand Up @@ -4928,6 +4923,22 @@ unittest
assert( x == 1 );
}

nothrow unittest
{
new Fiber({}).call!(Fiber.Rethrow.no)();
}

unittest
{
new Fiber({}).call(Fiber.Rethrow.yes);
new Fiber({}).call(Fiber.Rethrow.no);
}

deprecated unittest
{
new Fiber({}).call(true);
new Fiber({}).call(false);
}

unittest
{
Expand Down

0 comments on commit 0088d0b

Please sign in to comment.