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 QUIC_EVENT_EVENTS_START 2500
77 #define HTTP3_SESSION_EVENTS_START 2600
78 #define QPACK_EVENT_EVENTS_START 2700
79 #define NT_ASYNC_CONNECT_EVENT_EVENTS_START 3000
80 #define NT_ASYNC_IO_EVENT_EVENTS_START 3100
81 #define RAFT_EVENT_EVENTS_START 3200
82 #define SIMPLE_EVENT_EVENTS_START 3300
83 #define UPDATE_EVENT_EVENTS_START 3500
84 #define AIO_EVENT_EVENTS_START 3900
85 #define BLOCK_CACHE_EVENT_EVENTS_START 4000
86 #define UTILS_EVENT_EVENTS_START 5000
87 #define INK_API_EVENT_EVENTS_START 60000
88 #define SRV_EVENT_EVENTS_START 62000
89 #define REMAP_EVENT_EVENTS_START 63000
90 
91 // define misc events here
92 #define ONE_WAY_TUNNEL_EVENT_PEER_CLOSE (SIMPLE_EVENT_EVENTS_START + 1)
93 
94 typedef int EventType;
95 const int ET_CALL         = 0;
96 const int MAX_EVENT_TYPES = 8; // conservative, these are dynamically allocated
97 
98 class EThread;
99 
100 /**
101   A type of Action returned by the EventProcessor. The Event class
102   is the type of Action returned by the EventProcessor as a result
103   of scheduling an operation. Unlike asynchronous operations
104   represented by actions, events never call reentrantly.
105 
106   Besides being able to cancel an event (because it is an action),
107   you can also reschedule it once received.
108 
109   <b>Remarks</b>
110 
111   When rescheduling an event through any of the Event class
112   scheduling functions, state machines must not make these calls
113   in other thread other than the one that called them back. They
114   also must have acquired the continuation's lock before calling
115   any of the scheduling functions.
116 
117   The rules for canceling an event are the same as those for
118   actions:
119 
120   The canceler of an event must be the state machine that will be
121   called back by the task and that state machine's lock must be
122   held while calling cancel. Any reference to that event object
123   (ie. pointer) held by the state machine must not be used after
124   the cancellation.
125 
126   Event Codes:
127 
128   At the completion of an event, state machines use the event code
129   passed in through the Continuation's handler function to distinguish
130   the type of event and handle the data parameter accordingly. State
131   machine implementers should be careful when defining the event
132   codes since they can impact on other state machines presents. For
133   this reason, this numbers are usually allocated from a common
134   pool.
135 
136   Time values:
137 
138   The scheduling functions use a time parameter typed as ink_hrtime
139   for specifying the timeouts or periods. This is a nanosecond value
140   supported by libts and you should use the time functions and
141   macros defined in ink_hrtime.h.
142 
143   The difference between the timeout specified for schedule_at and
144   schedule_in is that in the former it is an absolute value of time
145   that is expected to be in the future where in the latter it is
146   an amount of time to add to the current time (obtained with
147   ink_get_hrtime).
148 
149 */
150 class Event : public Action
151 {
152 public:
153   ///////////////////////////////////////////////////////////
154   // Common Interface                                      //
155   ///////////////////////////////////////////////////////////
156 
157   /**
158      Reschedules this event immediately. Instructs the event object
159      to reschedule itself as soon as possible in the EventProcessor.
160 
161      @param callback_event Event code to return at the completion
162       of this event. See the Remarks section.
163 
164   */
165   void schedule_imm(int callback_event = EVENT_IMMEDIATE);
166 
167   /**
168      Reschedules this event to callback at time 'atimeout_at'.
169      Instructs the event object to reschedule itself at the time
170      specified in atimeout_at on the EventProcessor.
171 
172      @param atimeout_at Time at which to call the callback. See the Remarks section.
173      @param callback_event Event code to return at the completion of this event. See the Remarks section.
174 
175   */
176   void schedule_at(ink_hrtime atimeout_at, int callback_event = EVENT_INTERVAL);
177 
178   /**
179      Reschedules this event to callback at time 'atimeout_at'.
180      Instructs the event object to reschedule itself at the time
181      specified in atimeout_at on the EventProcessor.
182 
183      @param atimeout_in Time at which to call the callback. See the Remarks section.
184      @param callback_event Event code to return at the completion of this event. See the Remarks section.
185 
186   */
187   void schedule_in(ink_hrtime atimeout_in, int callback_event = EVENT_INTERVAL);
188 
189   /**
190      Reschedules this event to callback every 'aperiod'. Instructs
191      the event object to reschedule itself to callback every 'aperiod'
192      from now.
193 
194      @param aperiod Time period at which to call the callback. See the Remarks section.
195      @param callback_event Event code to return at the completion of this event. See the Remarks section.
196 
197   */
198   void schedule_every(ink_hrtime aperiod, int callback_event = EVENT_INTERVAL);
199 
200   // inherited from Action::cancel
201   // virtual void cancel(Continuation * c = nullptr);
202 
203   void free();
204 
205   EThread *ethread = nullptr;
206 
207   unsigned int in_the_prot_queue : 1;
208   unsigned int in_the_priority_queue : 1;
209   unsigned int immediate : 1;
210   unsigned int globally_allocated : 1;
211   unsigned int in_heap : 4;
212   int callback_event = 0;
213 
214   ink_hrtime timeout_at = 0;
215   ink_hrtime period     = 0;
216 
217   /**
218     This field can be set when an event is created. It is returned
219     as part of the Event structure to the continuation when handleEvent
220     is called.
221 
222   */
223   void *cookie = nullptr;
224 
225   // Private
226 
227   Event();
228 
229   Event *init(Continuation *c, ink_hrtime atimeout_at = 0, ink_hrtime aperiod = 0);
230 
231 #ifdef ENABLE_TIME_TRACE
232   ink_hrtime start_time;
233 #endif
234 
235   // noncopyable: prevent unauthorized copies (Not implemented)
236   Event(const Event &) = delete;
237   Event &operator=(const Event &) = delete;
238 
239 private:
240   void *operator new(size_t size); // use the fast allocators
241 
242 public:
243   LINK(Event, link);
244 
245   /*-------------------------------------------------------*\
246   | UNIX/non-NT Interface                                   |
247   \*-------------------------------------------------------*/
248 
249 #ifdef ONLY_USED_FOR_FIB_AND_BIN_HEAP
250   void *node_pointer;
251   void
set_node_pointer(void * x)252   set_node_pointer(void *x)
253   {
254     node_pointer = x;
255   }
256   void *
get_node_pointer()257   get_node_pointer()
258   {
259     return node_pointer;
260   }
261 #endif
262 
263 #if defined(__GNUC__)
~Event()264   ~Event() override {}
265 #endif
266 };
267 
268 //
269 // Event Allocator
270 //
271 extern ClassAllocator<Event> eventAllocator;
272 
273 #define EVENT_ALLOC(_a, _t) THREAD_ALLOC(_a, _t)
274 #define EVENT_FREE(_p, _a, _t) \
275   _p->mutex = nullptr;         \
276   if (_p->globally_allocated)  \
277     ::_a.free(_p);             \
278   else                         \
279     THREAD_FREE(_p, _a, _t)
280