1 /*******************************************************************************
2 
3     Shortcut wrapper for `ocean.task.Task` to suspend/resume on certain
4     conditions.
5 
6     Copyright:
7         Copyright (c) 2017 dunnhumby Germany GmbH.
8         All rights reserved.
9 
10     License:
11         Boost Software License Version 1.0. See LICENSE_BOOST.txt for details.
12         Alternatively, this file may be distributed under the terms of the Tango
13         3-Clause BSD License (see LICENSE_BSD.txt for details).
14 
15 *******************************************************************************/
16 
17 module ocean.task.util.Event;
18 
19 import ocean.meta.types.Qualifiers;
20 import ocean.task.Task;
21 
22 debug (TaskScheduler)
23 {
24     import ocean.io.Stdout;
25 }
26 
27 /*******************************************************************************
28 
29     Binds together a task reference and a boolean flag to indicate the event
30     status.
31 
32     Allows calling wait/trigger in any order as opposed to the plain
33     resume/suspend.
34 
35 *******************************************************************************/
36 
37 struct TaskEvent
38 {
39     /// indicates that event this instance described was triggered
40     private bool triggered;
41     /// refers to the task instance that must be resumed on the event
42     private Task task;
43 
44     /***************************************************************************
45 
46         Pauses execution of the current task until `trigger()` is called.
47         If `trigger()` has already been called before, does nothing.
48 
49     ***************************************************************************/
50 
51     public void wait ( )
52     {
53         if (!this.triggered)
54         {
55             this.task = Task.getThis();
56             debug_trace("Task {} suspended waiting for event {}",
57                 cast(void*) this.task, cast(void*) &this);
58             this.task.suspend();
59         }
60 
61         this.triggered = false;
62     }
63 
64     /***************************************************************************
65 
66         Triggers resuming a task paused via `wait`. If no task is currently
67         paused, raises the flag so that the next `wait` becomes no-op.
68 
69     ***************************************************************************/
70 
71     public void trigger ( )
72     {
73         this.triggered = true;
74         if (this.task !is null && this.task.suspended())
75         {
76             debug_trace("Resuming task {} by trigger of event {}",
77                 cast(void*) this.task, cast(void*) &this);
78             this.task.resume();
79         }
80     }
81 }
82 
83 private void debug_trace ( T... ) ( cstring format, T args )
84 {
85     debug ( TaskScheduler )
86     {
87         Stdout.formatln( "[ocean.task.util.Event] " ~ format, args ).flush();
88     }
89 }