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 @section details Details 00024 00025 Continuations have a handleEvent() method to invoke them. Users 00026 can determine the behavior of a Continuation by suppling a 00027 "ContinuationHandler" (member function name) which is invoked 00028 when events arrive. This function can be changed with the 00029 "setHandler" method. 00030 00031 Continuations can be subclassed to add additional state and 00032 methods. 00033 00034 */ 00035 00036 #ifndef _I_Continuation_h_ 00037 #define _I_Continuation_h_ 00038 00039 #include "libts.h" 00040 #include "I_Lock.h" 00041 00042 class Continuation; 00043 class ContinuationQueue; 00044 class Processor; 00045 class ProxyMutex; 00046 class EThread; 00047 00048 ////////////////////////////////////////////////////////////////////////////// 00049 // 00050 // Constants and Type Definitions 00051 // 00052 ////////////////////////////////////////////////////////////////////////////// 00053 00054 #define CONTINUATION_EVENT_NONE 0 00055 00056 #define CONTINUATION_DONE 0 00057 #define CONTINUATION_CONT 1 00058 00059 typedef int (Continuation::*ContinuationHandler) (int event, void *data); 00060 00061 class force_VFPT_to_top 00062 { 00063 public: 00064 virtual ~force_VFPT_to_top() 00065 { 00066 } 00067 }; 00068 00069 /** 00070 Base class for all state machines to receive notification of 00071 events. 00072 00073 The Continuation class represents the main abstraction mechanism 00074 used throughout the IO Core Event System to communicate its users 00075 the occurrence of an event. A Continuation is a lightweight data 00076 structure that implements a single method with which the user is 00077 called back. 00078 00079 Continuations are typically subclassed in order to implement 00080 event-driven state machines. By including additional state and 00081 methods, continuations can combine state with control flow, and 00082 they are generally used to support split-phase, event-driven 00083 control flow. 00084 00085 Given the multithreaded nature of the Event System, every 00086 continuation carries a reference to a ProxyMutex object to protect 00087 its state and ensure atomic operations. This ProxyMutex object 00088 must be allocated by continuation-derived classes or by clients 00089 of the IO Core Event System and it is required as a parameter to 00090 the Continuation's class constructor. 00091 00092 */ 00093 00094 class Continuation: private force_VFPT_to_top 00095 { 00096 public: 00097 00098 /** 00099 The current continuation handler function. 00100 00101 The current handler should not be set directly. In order to 00102 change it, first aquire the Continuation's lock and then use 00103 the SET_HANDLER macro which takes care of the type casting 00104 issues. 00105 00106 */ 00107 ContinuationHandler handler; 00108 00109 #ifdef DEBUG 00110 const char *handler_name; 00111 #endif 00112 00113 /** 00114 The Contination's lock. 00115 00116 A reference counted pointer to the Continuation's lock. This 00117 lock is initialized in the constructor and should not be set 00118 directly. 00119 00120 */ 00121 Ptr<ProxyMutex> mutex; 00122 00123 /** 00124 Link to other continuations. 00125 00126 A doubly-linked element to allow Lists of Continuations to be 00127 assembled. 00128 00129 */ 00130 LINK(Continuation, link); 00131 00132 /** 00133 Receives the event code and data for an Event. 00134 00135 This function receives the event code and data for an event and 00136 forwards them to the current continuation handler. The processor 00137 calling back the continuation is responsible for acquiring its 00138 lock. 00139 00140 @param event Event code to be passed at callback (Processor specific). 00141 @param data General purpose data related to the event code (Processor specific). 00142 @return State machine and processor specific return code. 00143 00144 */ 00145 int handleEvent(int event = CONTINUATION_EVENT_NONE, void *data = 0) { 00146 return (this->*handler) (event, data); 00147 } 00148 00149 /** 00150 Contructor of the Continuation object. It should not be used 00151 directly. Instead create an object of a derived type. 00152 00153 @param amutex Lock to be set for this Continuation. 00154 00155 */ 00156 Continuation(ProxyMutex * amutex = NULL); 00157 }; 00158 00159 /** 00160 Sets the Continuation's handler. The preferred mechanism for 00161 setting the Continuation's handler. 00162 00163 @param _h Pointer to the function used to callback with events. 00164 00165 */ 00166 #ifdef DEBUG 00167 #define SET_HANDLER(_h) \ 00168 (handler = ((ContinuationHandler)_h),handler_name = #_h) 00169 #else 00170 #define SET_HANDLER(_h) \ 00171 (handler = ((ContinuationHandler)_h)) 00172 #endif 00173 00174 /** 00175 Sets a Continuation's handler. 00176 00177 The preferred mechanism for setting the Continuation's handler. 00178 00179 @param _c Pointer to a Continuation whose handler is being set. 00180 @param _h Pointer to the function used to callback with events. 00181 00182 */ 00183 #ifdef DEBUG 00184 #define SET_CONTINUATION_HANDLER(_c,_h) \ 00185 (_c->handler = ((ContinuationHandler) _h),_c->handler_name = #_h) 00186 #else 00187 #define SET_CONTINUATION_HANDLER(_c,_h) \ 00188 (_c->handler = ((ContinuationHandler) _h)) 00189 #endif 00190 00191 inline 00192 Continuation::Continuation(ProxyMutex * amutex) 00193 : handler(NULL), 00194 #ifdef DEBUG 00195 handler_name(NULL), 00196 #endif 00197 mutex(amutex) 00198 { } 00199 00200 #endif /*_Continuation_h_*/