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 }