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 00025 #ifndef _EThread_h_ 00026 #define _EThread_h_ 00027 00028 #include "libts.h" 00029 #include "I_Thread.h" 00030 #include "I_PriorityEventQueue.h" 00031 #include "I_ProtectedQueue.h" 00032 00033 // TODO: This would be much nicer to have "run-time" configurable (or something), 00034 // perhaps based on proxy.config.stat_api.max_stats_allowed or other configs. XXX 00035 #define PER_THREAD_DATA (1024*1024) 00036 00037 // This is not used by the cache anymore, it uses proxy.config.cache.mutex_retry_delay 00038 // instead. 00039 #define MUTEX_RETRY_DELAY HRTIME_MSECONDS(20) 00040 00041 /** Maximum number of accept events per thread. */ 00042 #define MAX_ACCEPT_EVENTS 20 00043 00044 struct DiskHandler; 00045 struct EventIO; 00046 00047 class ServerSessionPool; 00048 class Event; 00049 class Continuation; 00050 00051 enum ThreadType { 00052 REGULAR = 0, 00053 MONITOR, 00054 DEDICATED 00055 }; 00056 00057 00058 /** 00059 Event System specific type of thread. 00060 00061 The EThread class is the type of thread created and managed by 00062 the Event System. It is one of the available interfaces for 00063 schedulling events in the event system (another two are the Event 00064 and EventProcessor classes). 00065 00066 In order to handle events, each EThread object has two event 00067 queues, one external and one internal. The external queue is 00068 provided for users of the EThread (clients) to append events to 00069 that particular thread. Since it can be accessed by other threads 00070 at the same time, operations using it must proceed in an atomic 00071 fashion. 00072 00073 The internal queue, in the other hand, is used exclusively by the 00074 EThread to process timed events within a certain time frame. These 00075 events are queued internally and they may come from the external 00076 queue as well. 00077 00078 Scheduling Interface: 00079 00080 There are eight schedulling functions provided by EThread and 00081 they are a wrapper around their counterparts in EventProcessor. 00082 00083 @see EventProcessor 00084 @see Event 00085 00086 */ 00087 class EThread: public Thread 00088 { 00089 public: 00090 /*-------------------------------------------------------*\ 00091 | Common Interface | 00092 \*-------------------------------------------------------*/ 00093 00094 /** 00095 Schedules the continuation on this EThread to receive an event 00096 as soon as possible. 00097 00098 Forwards to the EventProcessor the schedule of the callback to 00099 the continuation 'c' as soon as possible. The event is assigned 00100 to EThread. 00101 00102 @param c Continuation to be called back as soon as possible. 00103 @param callback_event Event code to be passed back to the 00104 continuation's handler. See the the EventProcessor class. 00105 @param cookie User-defined value or pointer to be passed back 00106 in the Event's object cookie field. 00107 @return Reference to an Event object representing the schedulling 00108 of this callback. 00109 00110 */ 00111 Event *schedule_imm(Continuation *c, int callback_event = EVENT_IMMEDIATE, void *cookie = NULL); 00112 Event *schedule_imm_signal(Continuation *c, int callback_event = EVENT_IMMEDIATE, void *cookie = NULL); 00113 00114 /** 00115 Schedules the continuation on this EThread to receive an event 00116 at the given timeout. 00117 00118 Forwards the request to the EventProcessor to schedule the 00119 callback to the continuation 'c' at the time specified in 00120 'atimeout_at'. The event is assigned to this EThread. 00121 00122 @param c Continuation to be called back at the time specified 00123 in 'atimeout_at'. 00124 @param atimeout_at Time value at which to callback. 00125 @param callback_event Event code to be passed back to the 00126 continuation's handler. See the EventProcessor class. 00127 @param cookie User-defined value or pointer to be passed back 00128 in the Event's object cookie field. 00129 @return A reference to an Event object representing the schedulling 00130 of this callback. 00131 00132 */ 00133 Event *schedule_at(Continuation *c, 00134 ink_hrtime atimeout_at, int callback_event = EVENT_INTERVAL, void *cookie = NULL); 00135 00136 /** 00137 Schedules the continuation on this EThread to receive an event 00138 after the timeout elapses. 00139 00140 Instructs the EventProcessor to schedule the callback to the 00141 continuation 'c' after the time specified in atimeout_in elapses. 00142 The event is assigned to this EThread. 00143 00144 @param c Continuation to be called back after the timeout elapses. 00145 @param atimeout_in Amount of time after which to callback. 00146 @param callback_event Event code to be passed back to the 00147 continuation's handler. See the EventProcessor class. 00148 @param cookie User-defined value or pointer to be passed back 00149 in the Event's object cookie field. 00150 @return A reference to an Event object representing the schedulling 00151 of this callback. 00152 00153 */ 00154 Event *schedule_in(Continuation *c, 00155 ink_hrtime atimeout_in, int callback_event = EVENT_INTERVAL, void *cookie = NULL); 00156 00157 /** 00158 Schedules the continuation on this EThread to receive an event 00159 periodically. 00160 00161 Schedules the callback to the continuation 'c' in the EventProcessor 00162 to occur every time 'aperiod' elapses. It is scheduled on this 00163 EThread. 00164 00165 @param c Continuation to call back everytime 'aperiod' elapses. 00166 @param aperiod Duration of the time period between callbacks. 00167 @param callback_event Event code to be passed back to the 00168 continuation's handler. See the Remarks section in the 00169 EventProcessor class. 00170 @param cookie User-defined value or pointer to be passed back 00171 in the Event's object cookie field. 00172 @return A reference to an Event object representing the schedulling 00173 of this callback. 00174 00175 */ 00176 Event *schedule_every(Continuation *c, ink_hrtime aperiod, int callback_event = EVENT_INTERVAL, void *cookie = NULL); 00177 00178 /** 00179 Schedules the continuation on this EThread to receive an event 00180 as soon as possible. 00181 00182 Schedules the callback to the continuation 'c' as soon as 00183 possible. The event is assigned to this EThread. 00184 00185 @param c Continuation to be called back as soon as possible. 00186 @param callback_event Event code to be passed back to the 00187 continuation's handler. See the EventProcessor class. 00188 @param cookie User-defined value or pointer to be passed back 00189 in the Event's object cookie field. 00190 @return A reference to an Event object representing the schedulling 00191 of this callback. 00192 00193 */ 00194 Event *schedule_imm_local(Continuation *c, int callback_event = EVENT_IMMEDIATE, void *cookie = NULL); 00195 00196 /** 00197 Schedules the continuation on this EThread to receive an event 00198 at the given timeout. 00199 00200 Schedules the callback to the continuation 'c' at the time 00201 specified in 'atimeout_at'. The event is assigned to this 00202 EThread. 00203 00204 @param c Continuation to be called back at the time specified 00205 in 'atimeout_at'. 00206 @param atimeout_at Time value at which to callback. 00207 @param callback_event Event code to be passed back to the 00208 continuation's handler. See the EventProcessor class. 00209 @param cookie User-defined value or pointer to be passed back 00210 in the Event's object cookie field. 00211 @return A reference to an Event object representing the schedulling 00212 of this callback. 00213 00214 */ 00215 Event *schedule_at_local(Continuation *c, 00216 ink_hrtime atimeout_at, int callback_event = EVENT_INTERVAL, void *cookie = NULL); 00217 00218 /** 00219 Schedules the continuation on this EThread to receive an event 00220 after the timeout elapses. 00221 00222 Schedules the callback to the continuation 'c' after the time 00223 specified in atimeout_in elapses. The event is assigned to this 00224 EThread. 00225 00226 @param c Continuation to be called back after the timeout elapses. 00227 @param atimeout_in Amount of time after which to callback. 00228 @param callback_event Event code to be passed back to the 00229 continuation's handler. See the Remarks section in the 00230 EventProcessor class. 00231 @param cookie User-defined value or pointer to be passed back 00232 in the Event's object cookie field. 00233 @return A reference to an Event object representing the schedulling 00234 of this callback. 00235 00236 */ 00237 Event *schedule_in_local(Continuation *c, 00238 ink_hrtime atimeout_in, int callback_event = EVENT_INTERVAL, void *cookie = NULL); 00239 00240 /** 00241 Schedules the continuation on this EThread to receive an event 00242 periodically. 00243 00244 Schedules the callback to the continuation 'c' to occur every 00245 time 'aperiod' elapses. It is scheduled on this EThread. 00246 00247 @param c Continuation to call back everytime 'aperiod' elapses. 00248 @param aperiod Duration of the time period between callbacks. 00249 @param callback_event Event code to be passed back to the 00250 continuation's handler. See the Remarks section in the 00251 EventProcessor class. 00252 @param cookie User-defined value or pointer to be passed back 00253 in the Event's object cookie field. 00254 @return A reference to an Event object representing the schedulling 00255 of this callback. 00256 00257 */ 00258 Event *schedule_every_local(Continuation *c, 00259 ink_hrtime aperiod, int callback_event = EVENT_INTERVAL, void *cookie = NULL); 00260 00261 /* private */ 00262 00263 Event *schedule_local(Event *e); 00264 00265 InkRand generator; 00266 00267 private: 00268 // prevent unauthorized copies (Not implemented) 00269 EThread(const EThread &); 00270 EThread & operator =(const EThread &); 00271 00272 /*-------------------------------------------------------*\ 00273 | UNIX Interface | 00274 \*-------------------------------------------------------*/ 00275 00276 public: 00277 EThread(); 00278 EThread(ThreadType att, int anid); 00279 EThread(ThreadType att, Event *e); 00280 virtual ~EThread(); 00281 00282 Event *schedule_spawn(Continuation *cont); 00283 Event *schedule(Event *e, bool fast_signal = false); 00284 00285 /** Block of memory to allocate thread specific data e.g. stat system arrays. */ 00286 char thread_private[PER_THREAD_DATA]; 00287 00288 /** Private Data for the Disk Processor. */ 00289 DiskHandler *diskHandler; 00290 00291 /** Private Data for AIO. */ 00292 Que(Continuation, link) aio_ops; 00293 00294 ProtectedQueue EventQueueExternal; 00295 PriorityEventQueue EventQueue; 00296 00297 EThread **ethreads_to_be_signalled; 00298 int n_ethreads_to_be_signalled; 00299 00300 Event *accept_event[MAX_ACCEPT_EVENTS]; 00301 int main_accept_index; 00302 00303 int id; 00304 unsigned int event_types; 00305 bool is_event_type(EventType et); 00306 void set_event_type(EventType et); 00307 00308 // Private Interface 00309 00310 void execute(); 00311 void process_event(Event *e, int calling_code); 00312 void free_event(Event *e); 00313 void (*signal_hook)(EThread *); 00314 00315 #if HAVE_EVENTFD 00316 int evfd; 00317 #else 00318 int evpipe[2]; 00319 #endif 00320 EventIO *ep; 00321 00322 ThreadType tt; 00323 Event *oneevent; // For dedicated event thread 00324 00325 ServerSessionPool* server_session_pool; 00326 }; 00327 00328 /** 00329 This is used so that we dont use up operator new(size_t, void *) 00330 which users might want to define for themselves. 00331 00332 */ 00333 class ink_dummy_for_new 00334 { 00335 }; 00336 00337 inline void *operator 00338 new(size_t, ink_dummy_for_new *p) 00339 { 00340 return (void *) p; 00341 } 00342 #define ETHREAD_GET_PTR(thread, offset) ((void*)((char*)(thread)+(offset))) 00343 00344 extern EThread *this_ethread(); 00345 #endif /*_EThread_h_*/