• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

I_Action.h

Go to the documentation of this file.
00001 /** @file
00002 
00003   Generic interface which enables any event or async activity to be cancelled
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 _I_Action_h_
00026 #define _I_Action_h_
00027 
00028 #include "libts.h"
00029 #include "I_Thread.h"
00030 #include "I_Continuation.h"
00031 
00032 /**
00033   Represents an operation initiated on a Processor.
00034 
00035   The Action class is an abstract representation of an operation
00036   being executed by some Processor. A reference to an Action object
00037   allows you to cancel an ongoing asynchronous operation before it
00038   completes. This means that the Continuation specified for the
00039   operation will not be called back.
00040 
00041   Actions or classes derived from Action are the typical return
00042   type of methods exposed by Processors in the Event System and
00043   throughout the IO Core libraries.
00044 
00045   The canceller of an action must be the state machine that will
00046   be called back by the task and that state machine's lock must be
00047   held while calling cancel.
00048 
00049   Processor implementers:
00050 
00051   You must ensure that no events are sent to the state machine after
00052   the operation has been cancelled appropriately.
00053 
00054   Returning an Action:
00055 
00056   Processor functions that are asynchronous must return actions to
00057   allow the calling state machine to cancel the task before completion.
00058   Because some processor functions are reentrant, they can call
00059   back the state machine before the returning from the call that
00060   creates the actions. To handle this case, special values are
00061   returned in place of an action to indicate to the state machine
00062   that the action is already completed.
00063 
00064     - @b ACTION_RESULT_DONE The processor has completed the task
00065       and called the state machine back inline.
00066     - @b ACTION_RESULT_INLINE Not currently used.
00067     - @b ACTION_RESULT_IO_ERROR Not currently used.
00068 
00069   To make matters more complicated, it's possible if the result is
00070   ACTION_RESULT_DONE that state machine deallocated itself on the
00071   reentrant callback. Thus, state machine implementers MUST either
00072   use a scheme to never deallocate their machines on reentrant
00073   callbacks OR immediately check the returned action when creating
00074   an asynchronous task and if it is ACTION_RESULT_DONE neither read
00075   nor write any state variables. With either method, it's imperative
00076   that the returned action always be checked for special values and
00077   the value handled accordingly.
00078 
00079   Allocation policy:
00080 
00081   Actions are allocated by the Processor performing the actions.
00082   It is the processor's responsbility to handle deallocation once
00083   the action is complete or cancelled. A state machine MUST NOT
00084   access an action once the operation that returned the Action has
00085   completed or it has cancelled the Action.
00086 
00087 */
00088 class Action
00089 {
00090 
00091 public:
00092 
00093   /**
00094     Contination that initiated this action.
00095 
00096     The reference to the initiating continuation is only used to
00097     verify that the action is being cancelled by the correct
00098     continuation.  This field should not be accesed or modified
00099     directly by the state machine.
00100 
00101   */
00102   Continuation * continuation;
00103 
00104 
00105   /**
00106     Reference to the Continuation's lock.
00107 
00108     Keeps a reference to the Continuation's lock to preserve the
00109     access to the cancelled field valid even when the state machine
00110     has been deallocated. This field should not be accesed or
00111     modified directly by the state machine.
00112 
00113   */
00114   Ptr<ProxyMutex> mutex;
00115 
00116   /**
00117     Internal flag used to indicate whether the action has been
00118     cancelled.
00119 
00120     This flag is set after a call to cancel or cancel_action and
00121     it should not be accesed or modified directly by the state
00122     machine.
00123 
00124   */
00125   volatile int cancelled;
00126 
00127   /**
00128     Cancels the asynchronous operation represented by this action.
00129 
00130     This method is called by state machines willing to cancel an
00131     ongoing asynchronous operation. Classes derived from Action may
00132     perform additional steps before flagging this action as cancelled.
00133     There are certain rules that must be followed in order to cancel
00134     an action (see the Remarks section).
00135 
00136     @param c Continuation associated with this Action.
00137 
00138   */
00139   virtual void cancel(Continuation * c = NULL) {
00140     ink_assert(!c || c == continuation);
00141 #ifdef DEBUG
00142     ink_assert(!cancelled);
00143     cancelled = true;
00144 #else
00145     if (!cancelled)
00146       cancelled = true;
00147 #endif
00148   }
00149 
00150   /**
00151     Cancels the asynchronous operation represented by this action.
00152 
00153     This method is called by state machines willing to cancel an
00154     ongoing asynchronous operation. There are certain rules that
00155     must be followed in order to cancel an action (see the Remarks
00156     section).
00157 
00158     @param c Continuation associated with this Action.
00159 
00160   */
00161   void cancel_action(Continuation * c = NULL) {
00162     ink_assert(!c || c == continuation);
00163 #ifdef DEBUG
00164     ink_assert(!cancelled);
00165     cancelled = true;
00166 #else
00167     if (!cancelled)
00168       cancelled = true;
00169 #endif
00170   }
00171 
00172   Continuation *operator =(Continuation * acont)
00173   {
00174     continuation = acont;
00175     if (acont)
00176       mutex = acont->mutex;
00177     else
00178       mutex = 0;
00179     return acont;
00180   }
00181 
00182   /**
00183     Constructor of the Action object. Processor implementers are
00184     responsible for associating this action with the proper
00185     Continuation.
00186 
00187   */
00188 Action():continuation(NULL), cancelled(false) {
00189   }
00190 
00191 #if defined(__GNUC__)
00192   virtual ~ Action() {
00193   }
00194 #endif
00195 };
00196 
00197 #define ACTION_RESULT_NONE           MAKE_ACTION_RESULT(0)
00198 #define ACTION_RESULT_DONE           MAKE_ACTION_RESULT(1)
00199 #define ACTION_IO_ERROR              MAKE_ACTION_RESULT(2)
00200 #define ACTION_RESULT_INLINE         MAKE_ACTION_RESULT(3)
00201 
00202 // Use these classes by
00203 // #define ACTION_RESULT_HOST_DB_OFFLINE
00204 //   MAKE_ACTION_RESULT(ACTION_RESULT_HOST_DB_BASE + 0)
00205 
00206 #define MAKE_ACTION_RESULT(_x) (Action*)(((uintptr_t)((_x<<1)+1)))
00207 
00208 #define ACTION_RESULT(_x) \
00209   (int)((((uintptr_t)_x)&1)!=0?(((uintptr_t)>>1):(uintptr_t)0))
00210 
00211 #define IS_ACTION_RESULT(_x) ((((uintptr_t)_x)&1) != 0)
00212 
00213 #endif /*_Action_h_*/

Generated by  doxygen 1.7.1