1 /******************************************************************************* 2 3 Custom event which can be registered with the EpollSelectDispatcher. 4 5 An instance of this class can be registered with an EpollSelectDispatcher, 6 and triggered at will, causing it to be selected in the select loop. When it 7 is selected, a user-specified callback (given in the class' constructor) is 8 invoked. 9 10 Two versions of the class exist, one which counts the number of calls to 11 trigger() before the callback is invoked (and passes the count to the 12 callback), and one which does not keep a count. 13 14 Usage example: 15 16 --- 17 18 import ocean.io.select.client.SelectEvent; 19 import ocean.io.select.EpollSelectDispatcher; 20 21 // Event handler 22 void handler ( ) 23 { 24 // Do something 25 } 26 27 auto dispatcher = new EpollSelectDispatcher; 28 auto event = new SelectEvent(&handler); 29 30 dispatcher.register(event); 31 32 dispatcher.eventLoop(); 33 34 // At this point, any time event.trigger is called, the eventLoop will 35 // select the event and invoke its handler callback. 36 37 --- 38 39 Copyright: 40 Copyright (c) 2009-2016 dunnhumby Germany GmbH. 41 All rights reserved. 42 43 License: 44 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. 45 Alternatively, this file may be distributed under the terms of the Tango 46 3-Clause BSD License (see LICENSE_BSD.txt for details). 47 48 *******************************************************************************/ 49 50 module ocean.io.select.client.SelectEvent; 51 52 53 54 55 import ocean.core.Verify; 56 57 import ocean.sys.EventFD; 58 59 import ocean.io.select.client.model.ISelectClient; 60 61 62 63 /******************************************************************************* 64 65 CountingSelectEvent class -- counts and reports the number of times the 66 trigger() method was called preivous to the event being fired in epoll and 67 the class' handle() method being invoked. 68 69 *******************************************************************************/ 70 71 public abstract class ISelectEvent : IAdvancedSelectClient 72 { 73 /*************************************************************************** 74 75 Event file descriptor. 76 77 ***************************************************************************/ 78 79 private EventFD event_fd; 80 81 82 /*************************************************************************** 83 84 Constructor. Creates a custom event and hooks it up to the provided 85 event handler. 86 87 ***************************************************************************/ 88 89 public this ( ) 90 { 91 this.event_fd = new EventFD; 92 } 93 94 95 /*************************************************************************** 96 97 Returs: 98 the epoll events to register for. 99 100 ***************************************************************************/ 101 102 override Event events ( ) 103 { 104 return Event.EPOLLIN; 105 } 106 107 108 /*************************************************************************** 109 110 Required by ISelectable interface. 111 112 Returns: 113 file descriptor used to manage custom event 114 115 ***************************************************************************/ 116 117 public override Handle fileHandle ( ) 118 { 119 return this.event_fd.fileHandle; 120 } 121 122 123 /*************************************************************************** 124 125 Called from the select dispatcher when the event fires. Calls the 126 abstract handle_() method. 127 128 Params: 129 event = select event which fired, must be Read 130 131 Returns: 132 forwards return value of the abstract handle_() method -- false 133 indicates that the event should be unregistered with the selector, 134 true indicates that it should remain registered and able to fire 135 again 136 137 ***************************************************************************/ 138 139 public override bool handle ( Event event ) 140 { 141 verify(event == event.EPOLLIN); 142 143 auto n = this.event_fd.handle(); 144 verify(n > 0); 145 146 return this.handle_(n); 147 } 148 149 150 /*************************************************************************** 151 152 Called from handle() when the event fires. 153 154 Params: 155 n = number of times the event was triggered since the last time 156 handle() was called by the select dispatcher 157 158 Returns: 159 false indicates that the event should be unregistered with the 160 selector, true indicates that it should remain registered and able 161 to fire again 162 163 ***************************************************************************/ 164 165 protected abstract bool handle_ ( ulong n ); 166 167 168 /*************************************************************************** 169 170 Triggers the event. 171 172 ***************************************************************************/ 173 174 public void trigger ( ) 175 { 176 this.event_fd.trigger(); 177 } 178 } 179 180 181 182 /******************************************************************************* 183 184 SelectEvent class -- calls the user-provided callback (passed to the 185 constructor) when the event is fired from epoll. The trigger() method causes 186 the event to fire. 187 188 *******************************************************************************/ 189 190 public class SelectEvent : ISelectEvent 191 { 192 /*************************************************************************** 193 194 Alias for event handler delegate. The return value indicates whether the 195 event should remain registered with the epoll selector, or be 196 unregistered after handling. 197 198 ***************************************************************************/ 199 200 public alias bool delegate ( ) Handler; 201 202 203 /*************************************************************************** 204 205 Event handler delegate. 206 207 ***************************************************************************/ 208 209 private Handler handler; 210 211 212 /*************************************************************************** 213 214 Constructor. 215 216 Params: 217 handler = event handler 218 219 ***************************************************************************/ 220 221 public this ( scope Handler handler ) 222 { 223 this.handler = handler; 224 225 super(); 226 } 227 228 229 /*************************************************************************** 230 231 Called from handle() when the event fires. 232 233 Params: 234 n = number of times the event was triggered since the last time 235 handle() was called by the select dispatcher (ignored) 236 237 Returns: 238 forwards return value of event handler -- false indicates that the 239 event should be unregistered with the selector, true indicates that 240 it should remain registered and able to fire again 241 242 ***************************************************************************/ 243 244 protected override bool handle_ ( ulong n ) 245 { 246 verify(this.handler !is null); 247 return this.handler(); 248 } 249 } 250 251 252 253 /******************************************************************************* 254 255 CountingSelectEvent class -- calls the user-provided callback (passed to the 256 constructor) when the event is fired from epoll. The trigger() method causes 257 the event to fire. The number of calls to trigger() which occurred before 258 the event fires is counted and passed to the callback. 259 260 *******************************************************************************/ 261 262 public class CountingSelectEvent : ISelectEvent 263 { 264 /*************************************************************************** 265 266 Alias for event handler delegate. The return value indicates whether the 267 event should remain registered with the epoll selector, or be 268 unregistered after handling. 269 270 The ulong passed to the delegate is the number of times the event has 271 been triggered since the last time handle() was called from epoll. 272 273 ***************************************************************************/ 274 275 public alias bool delegate ( ulong n ) Handler; 276 277 278 /*************************************************************************** 279 280 Event handler delegate. 281 282 ***************************************************************************/ 283 284 private Handler handler; 285 286 287 /*************************************************************************** 288 289 Constructor. 290 291 Params: 292 handler = event handler 293 294 ***************************************************************************/ 295 296 public this ( scope Handler handler ) 297 { 298 this.handler = handler; 299 300 super(); 301 } 302 303 304 /*************************************************************************** 305 306 Called from handle() when the event fires. 307 308 Params: 309 n = number of times the event was triggered since the last time 310 handle() was called by the select dispatcher 311 312 Returns: 313 forwards return value of event handler -- false indicates that the 314 event should be unregistered with the selector, true indicates that 315 it should remain registered and able to fire again 316 317 ***************************************************************************/ 318 319 protected override bool handle_ ( ulong n ) 320 { 321 return this.handler(n); 322 } 323 } 324