1 /******************************************************************************* 2 3 Custom event for use with fibers and epoll, allowing a process to be 4 suspended until the event is triggered. 5 6 Usage example: 7 8 --- 9 10 import ocean.io.select.client.FiberSelectEvent; 11 import ocean.io.select.EpollSelectDispatcher; 12 13 auto fiber = new MessageFiber(&coroutine); 14 15 auto epoll = new EpollSelectDispatcher; 16 auto event = new FiberSelectEvent(fiber, epoll); 17 18 // Fiber method 19 void coroutine ( ) 20 { 21 // Do something. 22 23 // Wait on the event, suspends the fiber. 24 event.wait(); 25 26 // When event.trigger is called (from elsewhere), the fiber is 27 // resumed. 28 } 29 30 --- 31 32 Copyright: 33 Copyright (c) 2009-2016 dunnhumby Germany GmbH. 34 All rights reserved. 35 36 License: 37 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. 38 Alternatively, this file may be distributed under the terms of the Tango 39 3-Clause BSD License (see LICENSE_BSD.txt for details). 40 41 *******************************************************************************/ 42 43 module ocean.io.select.client.FiberSelectEvent; 44 45 46 import ocean.core.MessageFiber; 47 48 import ocean.core.Verify; 49 50 import ocean.sys.EventFD; 51 52 import ocean.io.select.client.model.IFiberSelectClient; 53 54 55 /******************************************************************************* 56 57 Fiber select event class 58 59 *******************************************************************************/ 60 61 public class FiberSelectEvent : IFiberSelectClient 62 { 63 /*************************************************************************** 64 65 Token used when suspending / resuming fiber. 66 67 ***************************************************************************/ 68 69 static private MessageFiber.Token EventFired; 70 71 72 /*************************************************************************** 73 74 Static ctor. Initialises fiber token. 75 76 ***************************************************************************/ 77 78 static this ( ) 79 { 80 EventFired = MessageFiber.Token("event_fired"); 81 } 82 83 84 /*************************************************************************** 85 86 Custom event. 87 88 ***************************************************************************/ 89 90 private EventFD event; 91 92 93 /*************************************************************************** 94 95 Constructor. 96 97 Params: 98 fiber = fiber to suspend / resume with event wait / trigger 99 100 ***************************************************************************/ 101 102 public this ( SelectFiber fiber ) 103 { 104 super(fiber); 105 106 this.event = new EventFD; 107 } 108 109 /*************************************************************************** 110 111 Returs: 112 the epoll events to register for. 113 114 ***************************************************************************/ 115 116 public override Event events ( ) 117 { 118 return Event.EPOLLIN; 119 } 120 121 /*************************************************************************** 122 123 Required by ISelectable interface. 124 125 Returns: 126 file descriptor used to manage custom event 127 128 ***************************************************************************/ 129 130 public override Handle fileHandle ( ) 131 { 132 return this.event.fileHandle; 133 } 134 135 136 /*************************************************************************** 137 138 Triggers the event. 139 140 ***************************************************************************/ 141 142 public void trigger ( ) 143 { 144 this.event.trigger(); 145 } 146 147 148 /*************************************************************************** 149 150 Suspends the fiber until the event is triggered. 151 152 ***************************************************************************/ 153 154 public void wait ( ) 155 { 156 super.fiber.register(this); 157 super.fiber.suspend(EventFired, this, fiber.Message(true)); 158 } 159 160 161 /*************************************************************************** 162 163 Combining trigger() then wait(), this method causes the epoll event loop 164 to be resumed, giving other select clients a chance to do something. 165 166 ***************************************************************************/ 167 168 public void cede ( ) 169 { 170 this.trigger; 171 this.wait; 172 } 173 174 175 /*************************************************************************** 176 177 Handles events which occurred for the custom event fd. 178 179 (Implements an abstract super class method.) 180 181 Returns: 182 false if the fiber is finished or true if it keeps going 183 184 ***************************************************************************/ 185 186 public override bool handle ( Event events ) 187 { 188 verify(super.fiber.waiting); 189 190 this.event.handle(); 191 192 SelectFiber.Message message = super.fiber.resume(EventFired, this); 193 194 return (message.active == message.active.num)? message.num != 0 : false; 195 } 196 } 197