00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Token_Collection.h 00006 * 00007 * $Id: Token_Collection.h 78460 2007-05-23 13:33:56Z johnnyw $ 00008 * 00009 * The ACE_Token class offers methods for acquiring, renewing, 00010 * and releasing a synchronization token on a per-token basis. The 00011 * ACE_Token_Collection offers an interface for performing 00012 * operations on groups of tokens as a whole, or on a single token 00013 * within the collection. 00014 * 00015 * The atomic group operations are not yet implemented. 00016 * 00017 * 00018 * @author Douglas C. Schmidt (schmidt@cs.wustl.edu) 00019 * @author Tim Harrison (harrison@cs.wustl.edu) 00020 */ 00021 //============================================================================= 00022 00023 #ifndef ACE_TOKEN_COLLECTION_H 00024 #define ACE_TOKEN_COLLECTION_H 00025 #include /**/ "ace/pre.h" 00026 00027 #include "ace/Map_Manager.h" 00028 00029 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00030 # pragma once 00031 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00032 00033 #if defined (ACE_HAS_TOKENS_LIBRARY) 00034 00035 #include "ace/Local_Tokens.h" 00036 #include "ace/Null_Mutex.h" 00037 00038 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00039 00040 /** 00041 * @class ACE_Token_Collection 00042 * 00043 * @brief Allows atomic token group operations AND 00044 * provides a ACE_Token manager interface. 00045 * 00046 * There are two types of operations offered by 00047 * ACE_Token_Collection. The first is atomic operations on 00048 * collections of Token_Proxies. In this respect, the 00049 * ACE_Token_Collection can be thought of as a single token 00050 * consisting of multiple Token_Proxies. The second role of the 00051 * ACE_Token_Collection is as a ACE_Token manager. 00052 * ACE_Token_Collection allows individual operations on single 00053 * members of a collection of Token_Proxies. This provides a 00054 * single access point for operations on multiple tokens. 00055 * 00056 * @bug Although ACE_Token_Collection inherits from ACE_Token_Proxy, it 00057 * can not be including in a collection. This is because <clone> 00058 * returns zero for now. 00059 * 00060 */ 00061 class ACE_Export ACE_Token_Collection : public ACE_Token_Proxy 00062 { 00063 public: 00064 /** 00065 * @a debug print out verbose debugging messages. @a name will give a 00066 * name to the collection. Collections don't really need names, but 00067 * are sometimes useful for debugging. 00068 */ 00069 ACE_Token_Collection (bool debug = false, 00070 const ACE_TCHAR *name = 0); 00071 00072 // Collection Management operations 00073 00074 /** 00075 * Insert a Token into the collection. All ACE_Token type 00076 * operations performed on the collection will also be performed on 00077 * the new_proxy until it is removed. Note that no operations 00078 * performed prior to the insertion will be performed. Returns: 0 00079 * on success, -1 on failure with @c errno == problem. If a token 00080 * proxy already exists in the collection with the same name, the 00081 * insertion will fail. Also, <token> is copied. Note that during 00082 * the copy, client_id's are *not* inherited. The client ID of the 00083 * thread using the collection will be used. Client ID's can be 00084 * changed explicity on each proxy using is_member. 00085 */ 00086 int insert (ACE_Token_Proxy &token); 00087 00088 /** 00089 * Removes the ACE_Token matching the given token_name from the 00090 * collection. On success, extract returns 0. On failure 00091 * (token_name was not in the collection,) extract returns -1. On 00092 * success, the state of the token found is copied into proxy. 00093 * The returned ACE_Token_Proxy* must be deleted by the user. 00094 */ 00095 int extract (const ACE_TCHAR *token_name, ACE_Token_Proxy *&proxy); 00096 00097 /// Returns the proxy if true. 0 otherwise. 00098 ACE_Token_Proxy *is_member (const ACE_TCHAR *token_name); 00099 00100 /** 00101 * Is the specified token in the collection? 00102 * 1, yes. 00103 * 0, no. 00104 */ 00105 int is_member (const ACE_Token_Proxy &token); 00106 00107 // = Collective operation semantics. 00108 00109 // For acquire, renew, and release, there are two interfaces. Once 00110 // interface allows an operation on a single token in the 00111 // collection. The collective interfaces perform atomic operations 00112 // on the entire collection. For instance, a collective acquire 00113 // will perform an acquire for each and every token in the 00114 // collection or the operation will fail. Currently, these 00115 // operations are performed with no ordering heuristics. That is, 00116 // the Collection steps through the tokens in the order they were 00117 // inserted. For each one it performs the operation (acquire, 00118 // renew, or release). 00119 00120 /** 00121 * Acquire "atomically" all resources in the collection. This is 00122 * only successfull if all tokens in the collection could be 00123 * acquired. options contains the blocking semantics, timeout 00124 * value, etc. Returns: 0 on success, -1 on failure with @c errno == 00125 * problem. If and error or deadlock occurs for one of the tokens, 00126 * all the tokens will be released and the method will return -1. 00127 * Note that returning on detection of deadlock prevents livelock 00128 * between competing collections. If a collection returns after 00129 * detecting deadlock, it is the application's responsibility to not 00130 * to blindly loop on the collection::acquire operation. In other 00131 * words, once the collection reports deadlock, it is out of our 00132 * hands. 00133 */ 00134 virtual int acquire (int notify = 0, 00135 void (*sleep_hook)(void *) = 0, 00136 ACE_Synch_Options &options = 00137 ACE_Synch_Options::defaults); 00138 00139 /// Acquire the token corresponding to @a token_name. The other 00140 /// parameters are passed to <token>::acquire. 00141 virtual int acquire (const ACE_TCHAR *token_name, 00142 int notify = 0, 00143 void (*sleep_hook)(void *) = 0, 00144 ACE_Synch_Options &options = 00145 ACE_Synch_Options::defaults); 00146 00147 /// Try to acquire all tokens in collection. 00148 virtual int tryacquire (void (*sleep_hook)(void *) = 0); 00149 00150 /// Try to acquire @a token_name. 00151 virtual int tryacquire (const ACE_TCHAR *token_name, 00152 void (*sleep_hook)(void *) = 0); 00153 00154 /** 00155 * Renews "atomically" all resources in the collection. This is 00156 * only successfull if all tokens in the collection could be 00157 * renewed. options contains the blocking semantics, timeout 00158 * value, etc. Returns: 0 on success, -1 on failure with @c errno == 00159 * problem. 00160 */ 00161 virtual int renew (int requeue_position = 0, 00162 ACE_Synch_Options &options = 00163 ACE_Synch_Options::defaults); 00164 00165 00166 /// Renew the token corresponding to @a token_name. The other 00167 /// parameters are passed to <token>::renew. 00168 virtual int renew (const ACE_TCHAR *token_name, 00169 int requeue_position = 0, 00170 ACE_Synch_Options &options = 00171 ACE_Synch_Options::defaults); 00172 00173 /** 00174 * Releases "atomically" all resources in the collection. This is 00175 * only successfull if all tokens in the collection could be 00176 * released. options contains the blocking semantics, timeout 00177 * value, etc. Returns: 0 on success, -1 on failure with @c errno == 00178 * problem. 00179 */ 00180 virtual int release (ACE_Synch_Options &options = 00181 ACE_Synch_Options::defaults); 00182 00183 00184 /// Release the token corresponding to <token_name>. The other 00185 /// parameters are passed to <token>::release. 00186 virtual int release (const ACE_TCHAR *token_name, 00187 ACE_Synch_Options &options = 00188 ACE_Synch_Options::defaults); 00189 00190 ~ACE_Token_Collection (void); 00191 00192 /// Dump the state of the class. 00193 void dump (void) const; 00194 00195 /// Return the name of the collection. Not very functionally 00196 /// important, but sometimes a useful debugging tool. 00197 virtual const ACE_TCHAR *name (void) const; 00198 00199 protected: 00200 00201 typedef ACE_Token_Name TOKEN_NAME; 00202 00203 /// COLLECTION maintains a mapping from token names to ACE_Tokens* 00204 typedef ACE_Map_Manager<TOKEN_NAME, ACE_Token_Proxy *, ACE_Null_Mutex> 00205 COLLECTION; 00206 00207 /// Allows iterations through collection_ 00208 /** 00209 * @deprecated Deprecated typedef. Use COLLECTION::ITERATOR trait instead. 00210 */ 00211 typedef COLLECTION::ITERATOR COLLECTION_ITERATOR; 00212 00213 /// Allows iterations through collection_ 00214 /** 00215 * @deprecated Deprecated typedef. Use COLLECTION::ENTRY trait instead. 00216 */ 00217 typedef COLLECTION::ENTRY COLLECTION_ENTRY; 00218 00219 /// COLLECTION maintains a mapping from token names to ACE_Tokens*. 00220 COLLECTION collection_; 00221 00222 /// Whether to print out debug messages or not. 00223 bool debug_; 00224 00225 /// Name of the collection. 00226 ACE_TCHAR name_[ACE_MAXTOKENNAMELEN]; 00227 00228 // = I'm not sure what these mean, but they have to be defined since they're 00229 // pure virtual in ACE_Token_Proxy. 00230 virtual ACE_Token_Proxy *clone (void) const; 00231 virtual ACE_Tokens *create_token (const ACE_TCHAR *name); 00232 }; 00233 00234 ACE_END_VERSIONED_NAMESPACE_DECL 00235 00236 #if defined (__ACE_INLINE__) 00237 #include "ace/Token_Collection.inl" 00238 #endif /* __ACE_INLINE__ */ 00239 00240 #endif /* ACE_HAS_TOKENS_LIBRARY */ 00241 00242 #include /**/ "ace/post.h" 00243 #endif /* ACE_TOKEN_COLLECTION_H */