00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Reactor_Token_T.h 00006 * 00007 * $Id: Reactor_Token_T.h 72551 2006-05-05 11:42:02Z jwillemsen $ 00008 * 00009 * @author Steve Huston <shuston@riverace.com> 00010 */ 00011 //============================================================================= 00012 00013 00014 #ifndef ACE_REACTOR_TOKEN_T_H 00015 #define ACE_REACTOR_TOKEN_T_H 00016 #include /**/ "ace/pre.h" 00017 00018 #include "ace/Reactor_Impl.h" 00019 #include "ace/Token.h" 00020 00021 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00022 00023 /** 00024 * @class ACE_Reactor_Token_T 00025 * 00026 * @internal For ACE internal use only. 00027 * 00028 * @brief Used as a synchronization mechanism to coordinate concurrent 00029 * access to an ACE_Reactor_Impl object. 00030 * 00031 * This class is used to make access to a reactor's internals and 00032 * demultiplexing mechanism thread-safe. By default, the thread that 00033 * runs the handle_events() loop holds the token, even when it is blocked 00034 * in the demultiplexer. Whenever another thread wants to access the 00035 * reactor, such as via the register_handler(), remove_handler(), etc. 00036 * methods, it must ask the token owner for temporary release of the token. 00037 * To accomplish this, this class reimplements the ACE_Token::sleep_hook() 00038 * method through which the owning thread can be notified to temporarily 00039 * release the token if the current situation permits. 00040 * 00041 * The owner of the token is responsible for deciding which 00042 * request for the token can be granted. By using the 00043 * ACE_Token::renew() method, the thread that releases the token 00044 * temporarily can specify to get the token back right after the 00045 * other thread has completed using the token. Thus, there is a 00046 * dedicated thread that owns the token by default. This 00047 * thread grants other threads access to the token by ensuring 00048 * that whenever somebody else has finished using the token the 00049 * original owner reclaims the token again, i.e., the owner has the 00050 * chance to schedule other threads. The thread that most likely needs 00051 * the token most of the time is the thread running the dispatch loop. 00052 */ 00053 template <class ACE_TOKEN_TYPE> 00054 class ACE_Reactor_Token_T : public ACE_TOKEN_TYPE 00055 { 00056 public: 00057 ACE_Reactor_Token_T (ACE_Reactor_Impl &r, 00058 int s_queue = ACE_TOKEN_TYPE::FIFO); 00059 ACE_Reactor_Token_T (int s_queue = ACE_TOKEN_TYPE::FIFO); 00060 virtual ~ACE_Reactor_Token_T (void); 00061 00062 /// Called just before a token waiter goes to sleep. 00063 /// @see ACE_Token::sleep_hook 00064 virtual void sleep_hook (void); 00065 00066 /// Get the reactor implementation 00067 ACE_Reactor_Impl &reactor (void); 00068 00069 /// Set the reactor implementation 00070 void reactor (ACE_Reactor_Impl &); 00071 00072 /// Dump the state of an object. 00073 virtual void dump (void) const; 00074 00075 /// Declare the dynamic allocation hooks. 00076 ACE_ALLOC_HOOK_DECLARE; 00077 00078 private: 00079 ACE_Reactor_Impl *reactor_; 00080 }; 00081 00082 ACE_END_VERSIONED_NAMESPACE_DECL 00083 00084 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) 00085 #include "ace/Reactor_Token_T.cpp" 00086 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ 00087 00088 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) 00089 #pragma implementation ("Reactor_Token_T.cpp") 00090 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ 00091 00092 #include /**/ "ace/post.h" 00093 #endif /* ACE_REACTOR_TOKEN_T_H */