1 /******************************************************************************* 2 3 Manages ITimeoutClient instances where each one has an individual timeout 4 value. Uses a timer event as timeout notification mechanism. 5 6 Objects that can time out, the so-called timeout clients, must implement 7 ITimeoutClient. For each client create an ExpiryRegistration instance and 8 pass the object to the ExpiryRegistration constructor. 9 Call ExpiryRegistration.register() to set a timeout for the corresponding 10 client. The timeout() method of each client is then called when it has 11 timed out. 12 To disable the timeout for a client that has not timed out yet, call 13 ExpiryRegistration.unregister() . 14 15 Initially the object returned by TimerEventTimeoutManager.select_client 16 must be registered to an epoll select dispatcher. 17 18 Link with: 19 -Llibebtree.a 20 21 Build flags: 22 -debug=TimeoutManager = verbose output 23 24 Copyright: 25 Copyright (c) 2009-2016 dunnhumby Germany GmbH. 26 All rights reserved. 27 28 License: 29 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. 30 Alternatively, this file may be distributed under the terms of the Tango 31 3-Clause BSD License (see LICENSE_BSD.txt for details). 32 33 *******************************************************************************/ 34 35 module ocean.io.select.timeout.TimerEventTimeoutManager; 36 37 38 import ocean.meta.types.Qualifiers; 39 40 import ocean.time.timeout.TimeoutManager; 41 42 import ocean.io.select.client.TimerEvent; 43 44 import ocean.io.select.client.model.ISelectClient; 45 46 import core.sys.posix.time: time_t, timespec; 47 48 debug 49 { 50 import core.stdc.time: ctime; 51 import ocean.io.Stdout; 52 } 53 54 55 56 /******************************************************************************/ 57 58 class TimerEventTimeoutManager : TimeoutManager 59 { 60 import ocean.util.container.map.model.IAllocator; 61 62 /*************************************************************************** 63 64 TimerEvent for absolute real-time that calls checkTimeouts() when fired. 65 66 ***************************************************************************/ 67 68 private class TimerEvent : ITimerEvent 69 { 70 /*********************************************************************** 71 72 Constructor 73 74 ***********************************************************************/ 75 76 this ( ) 77 { 78 super(true); // use real-time 79 super.absolute = true; // use absolute time 80 } 81 82 /*********************************************************************** 83 84 Called when the timer event fires; notifies and unregisters the 85 timed out clients. 86 87 Params: 88 n = expiration counter (unused, mandatory) 89 90 Returns: 91 true to stay registered in the epoll select dispatcher. 92 93 ***********************************************************************/ 94 95 protected override bool handle_ ( ulong n ) 96 { 97 debug ( TimeoutManager ) Stderr("******** " ~ typeof (this.outer).stringof ~ " expired\n").flush(); 98 99 this.outer.checkTimeouts(); 100 return true; 101 } 102 } 103 104 /*************************************************************************** 105 106 TimerEvent instance 107 108 ***************************************************************************/ 109 110 private TimerEvent event; 111 112 /*************************************************************************** 113 114 Constructor 115 116 Params: 117 allocator = use this bucket element allocator for the expiry 118 registration to ISelectClient map. If it is null the default map 119 allocator (BucketElementGCAllocator) is used. 120 121 ***************************************************************************/ 122 123 public this ( IAllocator allocator = null ) 124 { 125 super(allocator); 126 this.event = this.new TimerEvent; 127 } 128 129 /*************************************************************************** 130 131 Returns: 132 the timer event instance to register in an epoll select dispatcher. 133 134 ***************************************************************************/ 135 136 public ISelectClient select_client ( ) 137 { 138 return this.event; 139 } 140 141 /*************************************************************************** 142 143 Enables or changes the timer event time. 144 145 Params: 146 next_expiration_us = wall clock time when the next client will time 147 out as UNIX time in microseconds. 148 149 ***************************************************************************/ 150 151 protected override void setTimeout ( ulong next_expiration_us ) 152 { 153 timespec ts = timespec(cast (time_t) (next_expiration_us / 1_000_000), 154 cast (uint) (next_expiration_us % 1_000_000) * 1000); 155 156 this.event.set(ts); 157 } 158 159 /*************************************************************************** 160 161 Disables the timer event. 162 163 ***************************************************************************/ 164 165 protected override void stopTimeout ( ) 166 { 167 this.event.reset(); 168 } 169 }