Skip to content

Commit

Permalink
Fix fiber runtime assertion
Browse files Browse the repository at this point in the history
Fixes #671

In D1 tangort calling `Fiber.reset` immediately puts it into HOLD state,
and it checks for TERM state in contract. Thus it is not legal to reset
fiber twice even if it is never started in between.
  • Loading branch information
Mihails Strasuns authored and mihails-strasuns committed Jan 22, 2019
1 parent 4b5c01e commit 7050fff
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 7 deletions.
13 changes: 9 additions & 4 deletions src/ocean/task/Task.d
Original file line number Diff line number Diff line change
Expand Up @@ -285,10 +285,13 @@ public abstract class Task : ISuspendable
Params:
fiber = the fiber to assign the task to
entry_point = optional custom entry point to replace
`this.entryPoint`
***************************************************************************/

public void assignTo ( WorkerFiber fiber )
public void assignTo ( WorkerFiber fiber,
void delegate() entry_point = null )
{
this.state_bitmask = TaskState.None;

Expand All @@ -297,7 +300,8 @@ public abstract class Task : ISuspendable
if (fiber.state == fiber.state.TERM)
{
// cast to ignore return value
this.fiber.reset(cast(void delegate()) &this.entryPoint);
this.fiber.reset(entry_point ? entry_point
: cast(void delegate()) &this.entryPoint);
}
}

Expand Down Expand Up @@ -784,9 +788,10 @@ public class TaskWith ( Extensions... ) : Task
***************************************************************************/

override public void assignTo ( WorkerFiber fiber )
override public void assignTo ( WorkerFiber fiber,
void delegate() entry_point = null )
{
super.assignTo(fiber);
super.assignTo(fiber, entry_point);

foreach (ref extension; this.extensions.tupleof)
{
Expand Down
2 changes: 1 addition & 1 deletion src/ocean/task/internal/FiberPool.d
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public class FiberPool : ObjectPool!(WorkerFiber)
auto fiber = super.get(if_missing);
if (fiber is null)
return null;
verify(fiber.state() != Fiber.State.EXEC);
verify(fiber.state() == Fiber.State.TERM);
return fiber;
}

Expand Down
3 changes: 1 addition & 2 deletions src/ocean/task/internal/FiberPoolWithQueue.d
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,12 @@ public class FiberPoolWithQueue : FiberPool
auto fiber = this.get();
debug_trace("running task <{}> via worker fiber <{}>",
cast(void*) task, cast(void*) fiber);
task.assignTo(fiber);
// `Task.entryPoint` is supposed to be entry method for worker fiber
// but it does not allow to reuse worker fiber immediately for new tasks
// waititing in the queue. Because of that a custom method is used as
// entry point instead which will internally call `Task.entryPoint`
// directly:
fiber.reset(&this.workerFiberMethod);
task.assignTo(fiber, &this.workerFiberMethod);
task.resume();
}

Expand Down

0 comments on commit 7050fff

Please sign in to comment.