00001 /** @file 00002 00003 A brief file description 00004 00005 @section license License 00006 00007 Licensed to the Apache Software Foundation (ASF) under one 00008 or more contributor license agreements. See the NOTICE file 00009 distributed with this work for additional information 00010 regarding copyright ownership. The ASF licenses this file 00011 to you under the Apache License, Version 2.0 (the 00012 "License"); you may not use this file except in compliance 00013 with the License. You may obtain a copy of the License at 00014 00015 http://www.apache.org/licenses/LICENSE-2.0 00016 00017 Unless required by applicable law or agreed to in writing, software 00018 distributed under the License is distributed on an "AS IS" BASIS, 00019 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00020 See the License for the specific language governing permissions and 00021 limitations under the License. 00022 */ 00023 00024 #ifndef _I_EventProcessor_h_ 00025 #define _I_EventProcessor_h_ 00026 00027 #include "libts.h" 00028 #include "I_Continuation.h" 00029 #include "I_Processor.h" 00030 #include "I_Event.h" 00031 00032 #ifdef TS_MAX_THREADS_IN_EACH_THREAD_TYPE 00033 const int MAX_THREADS_IN_EACH_TYPE = TS_MAX_THREADS_IN_EACH_THREAD_TYPE; 00034 #else 00035 const int MAX_THREADS_IN_EACH_TYPE = 3072; 00036 #endif 00037 00038 #ifdef TS_MAX_NUMBER_EVENT_THREADS 00039 const int MAX_EVENT_THREADS = TS_MAX_NUMBER_EVENT_THREADS; 00040 #else 00041 const int MAX_EVENT_THREADS = 4096; 00042 #endif 00043 00044 class EThread; 00045 00046 /** 00047 Main processor for the Event System. The EventProcessor is the core 00048 component of the Event System. Once started, it is responsible for 00049 creating and managing groups of threads that execute user-defined 00050 tasks asynchronously at a given time or periodically. 00051 00052 The EventProcessor provides a set of scheduling functions through 00053 which you can specify continuations to be called back by one of its 00054 threads. These function calls do not block. Instead they return an 00055 Event object and schedule the callback to the continuation passed in at 00056 a later or specific time, as soon as possible or at certain intervals. 00057 00058 Singleton model: 00059 00060 Every executable that imports and statically links against the 00061 EventSystem library is provided with a global instance of the 00062 EventProcessor called eventProcessor. Therefore, it is not necessary to 00063 create instances of the EventProcessor class because it was designed 00064 as a singleton. It is important to note that none of its functions 00065 are reentrant. 00066 00067 Thread Groups (Event types): 00068 00069 When the EventProcessor is started, the first group of threads is 00070 spawned and it is assigned the special id ET_CALL. Depending on the 00071 complexity of the state machine or protocol, you may be interested 00072 in creating additional threads and the EventProcessor gives you the 00073 ability to create a single thread or an entire group of threads. In 00074 the former case, you call spawn_thread and the thread is independent 00075 of the thread groups and it exists as long as your continuation handle 00076 executes and there are events to process. In the latter, you call 00077 spawn_event_theads which creates a new thread group and you get an id 00078 or event type with wich you must keep for use later on when scheduling 00079 continuations on that group. 00080 00081 Callback event codes: 00082 00083 @b UNIX: For all of the scheduling functions, the callback_event 00084 parameter is not used. On a callback, the event code passed in to 00085 the continuation handler is always EVENT_IMMEDIATE. 00086 00087 @b NT: The value of the event code passed in to the continuation 00088 handler is the value provided in the callback_event parameter. 00089 00090 Event allocation policy: 00091 00092 Events are allocated and deallocated by the EventProcessor. A state 00093 machine may access the returned, non-recurring event until it is 00094 cancelled or the callback from the event is complete. For recurring 00095 events, the Event may be accessed until it is cancelled. Once the event 00096 is complete or cancelled, it's the eventProcessor's responsibility to 00097 deallocate it. 00098 00099 */ 00100 class EventProcessor:public Processor 00101 { 00102 public: 00103 00104 /** 00105 Spawn an additional thread for calling back the continuation. Spawns 00106 a dedicated thread (EThread) that calls back the continuation passed 00107 in as soon as possible. 00108 00109 @param cont continuation that the spawn thread will call back 00110 immediately. 00111 @return event object representing the start of the thread. 00112 00113 */ 00114 Event *spawn_thread(Continuation * cont, const char *thr_name, size_t stacksize = 0); 00115 00116 /** 00117 Spawns a group of threads for an event type. Spawns the number of 00118 event threads passed in (n_threads) creating a thread group and 00119 returns the thread group id (or EventType). See the remarks section 00120 for Thread Groups. 00121 00122 @return EventType or thread id for the new group of threads. 00123 00124 */ 00125 EventType spawn_event_threads(int n_threads, const char* et_name, size_t stacksize); 00126 00127 00128 /** 00129 Schedules the continuation on a specific EThread to receive an event 00130 at the given timeout. Requests the EventProcessor to schedule 00131 the callback to the continuation 'c' at the time specified in 00132 'atimeout_at'. The event is assigned to the specified EThread. 00133 00134 @param c Continuation to be called back at the time specified in 00135 'atimeout_at'. 00136 @param atimeout_at time value at which to callback. 00137 @param ethread EThread on which to schedule the event. 00138 @param callback_event code to be passed back to the continuation's 00139 handler. See the Remarks section. 00140 @param cookie user-defined value or pointer to be passed back in 00141 the Event's object cookie field. 00142 @return reference to an Event object representing the scheduling 00143 of this callback. 00144 00145 */ 00146 Event *schedule_imm(Continuation * c, 00147 EventType event_type = ET_CALL, int callback_event = EVENT_IMMEDIATE, void *cookie = NULL); 00148 /* 00149 provides the same functionality as schedule_imm and also signals the thread immediately 00150 */ 00151 Event *schedule_imm_signal(Continuation * c, 00152 EventType event_type = ET_CALL, int callback_event = EVENT_IMMEDIATE, void *cookie = NULL); 00153 /** 00154 Schedules the continuation on a specific thread group to receive an 00155 event at the given timeout. Requests the EventProcessor to schedule 00156 the callback to the continuation 'c' at the time specified in 00157 'atimeout_at'. The callback is handled by a thread in the specified 00158 thread group (event_type). 00159 00160 @param c Continuation to be called back at the time specified in 00161 'atimeout_at'. 00162 @param atimeout_at Time value at which to callback. 00163 @param event_type thread group id (or event type) specifying the 00164 group of threads on which to schedule the callback. 00165 @param callback_event code to be passed back to the continuation's 00166 handler. See the Remarks section. 00167 @param cookie user-defined value or pointer to be passed back in 00168 the Event's object cookie field. 00169 @return reference to an Event object representing the scheduling of 00170 this callback. 00171 00172 */ 00173 Event *schedule_at(Continuation * c, 00174 ink_hrtime atimeout_at, 00175 EventType event_type = ET_CALL, int callback_event = EVENT_INTERVAL, void *cookie = NULL); 00176 00177 /** 00178 Schedules the continuation on a specific thread group to receive an 00179 event after the specified timeout elapses. Requests the EventProcessor 00180 to schedule the callback to the continuation 'c' after the time 00181 specified in 'atimeout_in' elapses. The callback is handled by a 00182 thread in the specified thread group (event_type). 00183 00184 @param c Continuation to call back aftert the timeout elapses. 00185 @param atimeout_in amount of time after which to callback. 00186 @param event_type Thread group id (or event type) specifying the 00187 group of threads on which to schedule the callback. 00188 @param callback_event code to be passed back to the continuation's 00189 handler. See the Remarks section. 00190 @param cookie user-defined value or pointer to be passed back in 00191 the Event's object cookie field. 00192 @return reference to an Event object representing the scheduling of 00193 this callback. 00194 00195 */ 00196 Event *schedule_in(Continuation * c, 00197 ink_hrtime atimeout_in, 00198 EventType event_type = ET_CALL, int callback_event = EVENT_INTERVAL, void *cookie = NULL); 00199 00200 /** 00201 Schedules the continuation on a specific thread group to receive 00202 an event periodically. Requests the EventProcessor to schedule the 00203 callback to the continuation 'c' everytime 'aperiod' elapses. The 00204 callback is handled by a thread in the specified thread group 00205 (event_type). 00206 00207 @param c Continuation to call back everytime 'aperiod' elapses. 00208 @param aperiod duration of the time period between callbacks. 00209 @param event_type thread group id (or event type) specifying the 00210 group of threads on which to schedule the callback. 00211 @param callback_event code to be passed back to the continuation's 00212 handler. See the Remarks section. 00213 @param cookie user-defined value or pointer to be passed back in 00214 the Event's object cookie field. 00215 @return reference to an Event object representing the scheduling of 00216 this callback. 00217 00218 */ 00219 Event *schedule_every(Continuation * c, 00220 ink_hrtime aperiod, 00221 EventType event_type = ET_CALL, int callback_event = EVENT_INTERVAL, void *cookie = NULL); 00222 00223 00224 //////////////////////////////////////////// 00225 // reschedule an already scheduled event. // 00226 // may be called directly or called by // 00227 // schedule_xxx Event member functions. // 00228 // The returned value may be different // 00229 // from the argument e. // 00230 //////////////////////////////////////////// 00231 00232 Event *reschedule_imm(Event * e, int callback_event = EVENT_IMMEDIATE); 00233 Event *reschedule_at(Event * e, ink_hrtime atimeout_at, int callback_event = EVENT_INTERVAL); 00234 Event *reschedule_in(Event * e, ink_hrtime atimeout_in, int callback_event = EVENT_INTERVAL); 00235 Event *reschedule_every(Event * e, ink_hrtime aperiod, int callback_event = EVENT_INTERVAL); 00236 00237 EventProcessor(); 00238 00239 /** 00240 Initializes the EventProcessor and its associated threads. Spawns the 00241 specified number of threads, initializes their state information and 00242 sets them running. It creates the initial thread group, represented 00243 by the event type ET_CALL. 00244 00245 @return 0 if successful, and a negative value otherwise. 00246 00247 */ 00248 int start(int n_net_threads, size_t stacksize=DEFAULT_STACKSIZE); 00249 00250 /** 00251 Stop the EventProcessor. Attempts to stop the EventProcessor and 00252 all of the threads in each of the thread groups. 00253 00254 */ 00255 virtual void shutdown(); 00256 00257 /** 00258 Allocates size bytes on the event threads. This function is thread 00259 safe. 00260 00261 @param size bytes to be allocated. 00262 00263 */ 00264 off_t allocate(int size); 00265 00266 /** 00267 An array of pointers to all of the EThreads handled by the 00268 EventProcessor. An array of pointers to all of the EThreads created 00269 throughout the existence of the EventProcessor instance. 00270 00271 */ 00272 EThread *all_ethreads[MAX_EVENT_THREADS]; 00273 00274 /** 00275 An array of pointers, organized by thread group, to all of the 00276 EThreads handled by the EventProcessor. An array of pointers to all of 00277 the EThreads created throughout the existence of the EventProcessor 00278 instance. It is a two-dimensional array whose first dimension is the 00279 thread group id and the second the EThread pointers for that group. 00280 00281 */ 00282 EThread *eventthread[MAX_EVENT_TYPES][MAX_THREADS_IN_EACH_TYPE]; 00283 00284 unsigned int next_thread_for_type[MAX_EVENT_TYPES]; 00285 int n_threads_for_type[MAX_EVENT_TYPES]; 00286 00287 /** 00288 Total number of threads controlled by this EventProcessor. This is 00289 the count of all the EThreads spawn by this EventProcessor, excluding 00290 those created by spawn_thread 00291 00292 */ 00293 int n_ethreads; 00294 00295 /** 00296 Total number of thread groups created so far. This is the count of 00297 all the thread groups (event types) created for this EventProcessor. 00298 00299 */ 00300 int n_thread_groups; 00301 00302 private: 00303 // prevent unauthorized copies (Not implemented) 00304 EventProcessor(const EventProcessor &); 00305 EventProcessor & operator =(const EventProcessor &); 00306 00307 public: 00308 00309 /*------------------------------------------------------*\ 00310 | Unix & non NT Interface | 00311 \*------------------------------------------------------*/ 00312 00313 Event * schedule(Event * e, EventType etype, bool fast_signal = false); 00314 EThread *assign_thread(EventType etype); 00315 00316 EThread *all_dthreads[MAX_EVENT_THREADS]; 00317 int n_dthreads; // No. of dedicated threads 00318 volatile int thread_data_used; 00319 }; 00320 00321 extern inkcoreapi class EventProcessor eventProcessor; 00322 00323 #endif /*_EventProcessor_h_*/