1 /** @file
2 
3   A brief file description
4 
5   @section license License
6 
7   Licensed to the Apache Software Foundation (ASF) under one
8   or more contributor license agreements.  See the NOTICE file
9   distributed with this work for additional information
10   regarding copyright ownership.  The ASF licenses this file
11   to you under the Apache License, Version 2.0 (the
12   "License"); you may not use this file except in compliance
13   with the License.  You may obtain a copy of the License at
14 
15       http://www.apache.org/licenses/LICENSE-2.0
16 
17   Unless required by applicable law or agreed to in writing, software
18   distributed under the License is distributed on an "AS IS" BASIS,
19   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20   See the License for the specific language governing permissions and
21   limitations under the License.
22 
23  */
24 
25 #pragma once
26 
27 #include "tscore/ink_platform.h"
28 #include "I_Action.h"
29 
30 //
31 //  Defines
32 //
33 
34 #define MAX_EVENTS_PER_THREAD 100000
35 
36 // Events
37 
38 #define EVENT_NONE CONTINUATION_EVENT_NONE // 0
39 #define EVENT_IMMEDIATE 1
40 #define EVENT_INTERVAL 2
41 #define EVENT_ERROR 3
42 #define EVENT_CALL 4 // used internally in state machines
43 #define EVENT_POLL 5 // negative event; activated on poll or epoll
44 
45 // Event callback return functions
46 
47 #define EVENT_DONE CONTINUATION_DONE // 0
48 #define EVENT_CONT CONTINUATION_CONT // 1
49 #define EVENT_RETURN 5
50 #define EVENT_RESTART 6
51 #define EVENT_RESTART_DELAYED 7
52 
53 // Event numbers block allocation
54 // ** ALL NEW EVENT TYPES SHOULD BE ALLOCATED FROM BLOCKS LISTED HERE! **
55 
56 #define VC_EVENT_EVENTS_START 100
57 #define NET_EVENT_EVENTS_START 200
58 #define DISK_EVENT_EVENTS_START 300
59 #define HOSTDB_EVENT_EVENTS_START 500
60 #define DNS_EVENT_EVENTS_START 600
61 #define CONFIG_EVENT_EVENTS_START 800
62 #define LOG_EVENT_EVENTS_START 900
63 #define REFCOUNT_CACHE_EVENT_EVENTS_START 1000
64 #define CACHE_EVENT_EVENTS_START 1100
65 #define CACHE_DIRECTORY_EVENT_EVENTS_START 1200
66 #define CACHE_DB_EVENT_EVENTS_START 1300
67 #define HTTP_NET_CONNECTION_EVENT_EVENTS_START 1400
68 #define HTTP_NET_VCONNECTION_EVENT_EVENTS_START 1500
69 #define GC_EVENT_EVENTS_START 1600
70 #define TRANSFORM_EVENTS_START 2000
71 #define STAT_PAGES_EVENTS_START 2100
72 #define HTTP_SESSION_EVENTS_START 2200
73 #define HTTP2_SESSION_EVENTS_START 2250
74 #define HTTP_TUNNEL_EVENTS_START 2300
75 #define HTTP_SCH_UPDATE_EVENTS_START 2400
76 #define NT_ASYNC_CONNECT_EVENT_EVENTS_START 3000
77 #define NT_ASYNC_IO_EVENT_EVENTS_START 3100
78 #define RAFT_EVENT_EVENTS_START 3200
79 #define SIMPLE_EVENT_EVENTS_START 3300
80 #define UPDATE_EVENT_EVENTS_START 3500
81 #define AIO_EVENT_EVENTS_START 3900
82 #define BLOCK_CACHE_EVENT_EVENTS_START 4000
83 #define UTILS_EVENT_EVENTS_START 5000
84 #define INK_API_EVENT_EVENTS_START 60000
85 #define SRV_EVENT_EVENTS_START 62000
86 #define REMAP_EVENT_EVENTS_START 63000
87 
88 // define misc events here
89 #define ONE_WAY_TUNNEL_EVENT_PEER_CLOSE (SIMPLE_EVENT_EVENTS_START + 1)
90 
91 typedef int EventType;
92 const int ET_CALL         = 0;
93 const int MAX_EVENT_TYPES = 8; // conservative, these are dynamically allocated
94 
95 class EThread;
96 
97 /**
98   A type of Action returned by the EventProcessor. The Event class
99   is the type of Action returned by the EventProcessor as a result
100   of scheduling an operation. Unlike asynchronous operations
101   represented by actions, events never call reentrantly.
102 
103   Besides being able to cancel an event (because it is an action),
104   you can also reschedule it once received.
105 
106   <b>Remarks</b>
107 
108   When rescheduling an event through any of the Event class
109   scheduling functions, state machines must not make these calls
110   in other thread other than the one that called them back. They
111   also must have acquired the continuation's lock before calling
112   any of the scheduling functions.
113 
114   The rules for canceling an event are the same as those for
115   actions:
116 
117   The canceler of an event must be the state machine that will be
118   called back by the task and that state machine's lock must be
119   held while calling cancel. Any reference to that event object
120   (ie. pointer) held by the state machine must not be used after
121   the cancellation.
122 
123   Event Codes:
124 
125   At the completion of an event, state machines use the event code
126   passed in through the Continuation's handler function to distinguish
127   the type of event and handle the data parameter accordingly. State
128   machine implementers should be careful when defining the event
129   codes since they can impact on other state machines presents. For
130   this reason, this numbers are usually allocated from a common
131   pool.
132 
133   Time values:
134 
135   The scheduling functions use a time parameter typed as ink_hrtime
136   for specifying the timeouts or periods. This is a nanosecond value
137   supported by libts and you should use the time functions and
138   macros defined in ink_hrtime.h.
139 
140   The difference between the timeout specified for schedule_at and
141   schedule_in is that in the former it is an absolute value of time
142   that is expected to be in the future where in the latter it is
143   an amount of time to add to the current time (obtained with
144   ink_get_hrtime).
145 
146 */
147 class Event : public Action
148 {
149 public:
150   ///////////////////////////////////////////////////////////
151   // Common Interface                                      //
152   ///////////////////////////////////////////////////////////
153 
154   /**
155      Reschedules this event immediately. Instructs the event object
156      to reschedule itself as soon as possible in the EventProcessor.
157 
158      @param callback_event Event code to return at the completion
159       of this event. See the Remarks section.
160 
161   */
162   void schedule_imm(int callback_event = EVENT_IMMEDIATE);
163 
164   /**
165      Reschedules this event to callback at time 'atimeout_at'.
166      Instructs the event object to reschedule itself at the time
167      specified in atimeout_at on the EventProcessor.
168 
169      @param atimeout_at Time at which to callcallback. See the Remarks section.
170      @param callback_event Event code to return at the completion of this event. See the Remarks section.
171 
172   */
173   void schedule_at(ink_hrtime atimeout_at, int callback_event = EVENT_INTERVAL);
174 
175   /**
176      Reschedules this event to callback at time 'atimeout_at'.
177      Instructs the event object to reschedule itself at the time
178      specified in atimeout_at on the EventProcessor.
179 
180      @param atimeout_in Time at which to callcallback. See the Remarks section.
181      @param callback_event Event code to return at the completion of this event. See the Remarks section.
182 
183   */
184   void schedule_in(ink_hrtime atimeout_in, int callback_event = EVENT_INTERVAL);
185 
186   /**
187      Reschedules this event to callback every 'aperiod'. Instructs
188      the event object to reschedule itself to callback every 'aperiod'
189      from now.
190 
191      @param aperiod Time period at which to callcallback. See the Remarks section.
192      @param callback_event Event code to return at the completion of this event. See the Remarks section.
193 
194   */
195   void schedule_every(ink_hrtime aperiod, int callback_event = EVENT_INTERVAL);
196 
197   // inherited from Action::cancel
198   // virtual void cancel(Continuation * c = nullptr);
199 
200   void free();
201 
202   EThread *ethread = nullptr;
203 
204   unsigned int in_the_prot_queue : 1;
205   unsigned int in_the_priority_queue : 1;
206   unsigned int immediate : 1;
207   unsigned int globally_allocated : 1;
208   unsigned int in_heap : 4;
209   int callback_event = 0;
210 
211   ink_hrtime timeout_at = 0;
212   ink_hrtime period     = 0;
213 
214   /**
215     This field can be set when an event is created. It is returned
216     as part of the Event structure to the continuation when handleEvent
217     is called.
218 
219   */
220   void *cookie = nullptr;
221 
222   // Private
223 
224   Event();
225 
226   Event *init(Continuation *c, ink_hrtime atimeout_at = 0, ink_hrtime aperiod = 0);
227 
228 #ifdef ENABLE_TIME_TRACE
229   ink_hrtime start_time;
230 #endif
231 
232   // noncopyable: prevent unauthorized copies (Not implemented)
233   Event(const Event &) = delete;
234   Event &operator=(const Event &) = delete;
235 
236 private:
237   void *operator new(size_t size); // use the fast allocators
238 
239 public:
240   LINK(Event, link);
241 
242   /*-------------------------------------------------------*\
243   | UNIX/non-NT Interface                                   |
244   \*-------------------------------------------------------*/
245 
246 #ifdef ONLY_USED_FOR_FIB_AND_BIN_HEAP
247   void *node_pointer;
248   void
249   set_node_pointer(void *x)
250   {
251     node_pointer = x;
252   }
253   void *
254   get_node_pointer()
255   {
256     return node_pointer;
257   }
258 #endif
259 
260 #if defined(__GNUC__)
261   ~Event() override {}
262 #endif
263 };
264 
265 //
266 // Event Allocator
267 //
268 extern ClassAllocator<Event> eventAllocator;
269 
270 #define EVENT_ALLOC(_a, _t) THREAD_ALLOC(_a, _t)
271 #define EVENT_FREE(_p, _a, _t) \
272   _p->mutex = nullptr;         \
273   if (_p->globally_allocated)  \
274     ::_a.free(_p);             \
275   else                         \
276     THREAD_FREE(_p, _a, _t)
277