Local_Tokens.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    Local_Tokens.h
00006  *
00007  *  Local_Tokens.h,v 4.52 2006/02/10 10:00:29 jwillemsen Exp
00008  *
00009  *  @author Karl-Heinz Dorn <kdorn@erlh.siemens.de>
00010  *  @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
00011  *  @author Tim Harrison <harrison@cs.wustl.edu>
00012  *
00013  * This file contains definitions for the following classes:
00014  *
00015  * public:
00016  *   7. ACE_Token_Proxy
00017  *   8. ACE_Null_Token : public ACE_Token_Proxy
00018  *   9. ACE_Local_Mutex : public ACE_Token_Proxy
00019  *   *. ACE_Local_RLock : public ACE_Local_Mutex
00020  *   &. ACE_Local_WLock : public ACE_Local_Mutex
00021  * private:
00022  *   1. ACE_TOKEN_CONST
00023  *   3. ACE_TPQ_Entry
00024  *   b. ACE_TSS_TPQ_Entry
00025  *   c. ACE_TPQ_Iterator
00026  *   4. ACE_Token_Proxy_Queue
00027  *   5. ACE_Tokens
00028  *   6. ACE_Mutex_Token : public ACE_Tokens
00029  *   12. ACE_RW_Token : public ACE_Tokens
00030  *   a. ACE_Token_Name
00031  *
00032  *  Note that the locking classes defined in this file are *not*
00033  *  intended to be used as general-purpose synchronization
00034  *  mechanisms, such as mutexes or semaphores.  Instead, you should
00035  *  use the ACE_Recursive_Thread_Mutex, ACE_Thread_Mutex,
00036  *  ACE_Thread_Semaphore, etc., that are defined in
00037  *  $ACE_ROOT/ace/Synch.h and $ACE_ROOT/ace/Synch_T.h or the
00038  *  ACE_Token that's defined in $ACE_ROOT/ace/Token.h.
00039  *
00040  *
00041  */
00042 //=============================================================================
00043 
00044 #ifndef ACE_LOCAL_MUTEX_H
00045 #define ACE_LOCAL_MUTEX_H
00046 #include /**/ "ace/pre.h"
00047 
00048 #include "ace/config-all.h"
00049 
00050 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00051 # pragma once
00052 #endif /* ACE_LACKS_PRAGMA_ONCE */
00053 
00054 #if defined (ACE_HAS_TOKENS_LIBRARY)
00055 
00056 #include "ace/Synch_Traits.h"
00057 #include "ace/Condition_Thread_Mutex.h"
00058 #include "ace/TSS_T.h"
00059 #include "ace/Containers.h"
00060 #include "ace/Synch_Options.h"
00061 #include "ace/Map_Manager.h"
00062 #include "ace/Log_Msg.h"
00063 #include "ace/OS_NS_string.h"
00064 #include "ace/os_include/os_netdb.h"
00065 
00066 #if !(defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE))
00067 # define ACE_NO_TSS_TOKENS 1
00068 #endif /* !(defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)) */
00069 
00070 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00071 
00072 // 1.
00073 /**
00074  * @class ACE_TOKEN_CONST
00075  *
00076  * @brief Not a public interface.
00077  *
00078  * Constant definitions and typedefs for Token library.  Mostly,
00079  * this class is necessary to fight the compiler with order of
00080  * declaration errors.
00081  */
00082 namespace ACE_TOKEN_CONST
00083 {
00084 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00085   // ACE platform supports some form of threading.
00086   typedef ACE_Condition_Thread_Mutex COND_VAR;
00087   typedef ACE_Thread_Mutex MUTEX;
00088   typedef ACE_Guard<ACE_Thread_Mutex> GUARD;
00089 #else
00090   typedef ACE_Null_Condition COND_VAR;
00091   typedef ACE_Null_Mutex MUTEX;
00092   typedef ACE_Guard<ACE_Null_Mutex> GUARD;
00093 #endif /* ACE_HAS_THREADS */
00094 }
00095 
00096 // Forward decl.
00097 class ACE_Token_Proxy;
00098 
00099 // 3..
00100 /**
00101  * @class ACE_TPQ_Entry
00102  *
00103  * @brief Token Proxy Queue entry.  Used in the ACE_Token_Proxy_Queue
00104  *
00105  * Not a public interface.
00106  */
00107 class ACE_Export ACE_TPQ_Entry
00108 {
00109   friend class ACE_Token_Manager;
00110 public:
00111   typedef void (*PTVF) (void *);
00112 
00113   /// Null constructor.
00114   ACE_TPQ_Entry (void);
00115 
00116   /// Constructor.
00117   ACE_TPQ_Entry (const ACE_Token_Proxy *proxy,
00118                  const ACE_TCHAR *client_id);
00119 
00120   /// Copy constructor.
00121   ACE_TPQ_Entry (const ACE_TPQ_Entry &rhs);
00122 
00123   /// Destructor.
00124   ~ACE_TPQ_Entry (void);
00125 
00126   /// Copy operator use by the queue.
00127   void operator= (const ACE_TPQ_Entry &rhs);
00128 
00129   /// Get top of the queue.
00130   ACE_Token_Proxy *proxy (void) const;
00131 
00132   /// Set top of the queue.
00133   void proxy (ACE_Token_Proxy *);
00134 
00135   /// Get nesting level of the entry.
00136   int nesting_level (void) const;
00137 
00138   /// Delta nesting level of the entry.
00139   void nesting_level (int delta);
00140 
00141   /// Get client_id of the entry.
00142   const ACE_TCHAR *client_id (void) const;
00143 
00144   /// Set client_id of the entry.
00145   void client_id (const ACE_TCHAR *);
00146 
00147   /// Returns 1 if @a id == client id.  Does not check for @a id == 0.
00148   int equal_client_id (const ACE_TCHAR *id);
00149 
00150   /// One method for arg and sleep_hook.
00151   void set (void (*sleep_hook)(void *));
00152 
00153   /// Set sleep hook of the entry.
00154   void sleep_hook (void (*sh)(void *));
00155 
00156   /// Get sleep hook of the entry.
00157   PTVF sleep_hook (void) const;
00158 
00159   /// Call the sleep hook function or method passing arg.
00160   void call_sleep_hook (void);
00161 
00162   /// Dump the state of the class.
00163   void dump (void) const;
00164 
00165   // = Used to block the thread if an acquire fails with EWOULDBLOCK.
00166   ACE_TOKEN_CONST::COND_VAR cond_var_;
00167   ACE_TOKEN_CONST::MUTEX lock_;
00168 
00169   /// Pointer to next in list.
00170   ACE_TPQ_Entry *next_;
00171 
00172   /// Get whether this client is blocked waiting for a token.
00173   int waiting (void) const;
00174 
00175   /// Set whether this client is blocked waiting for a token.
00176   void waiting (int w);
00177 
00178 private:
00179   /// This client is waiting for a token.
00180   int waiting_;
00181 
00182   /// Proxy.
00183   ACE_Token_Proxy *proxy_;
00184 
00185   /// Nesting level.
00186   int nesting_level_;
00187 
00188   /// Arg.
00189   void *arg_;
00190 
00191   /// Client id.
00192   ACE_TCHAR client_id_[ACE_MAXCLIENTIDLEN];
00193 
00194   /// Sleep hook.
00195   void (*sleep_hook_)(void *);
00196 };
00197 
00198 // b..
00199 #if defined (ACE_NO_TSS_TOKENS)
00200 typedef ACE_TPQ_Entry ACE_TPQ_ENTRY;
00201 #else
00202 typedef ACE_TSS<ACE_TPQ_Entry> ACE_TPQ_ENTRY;
00203 #endif /* ACE_NO_TSS_TOKENS */
00204 
00205 /**
00206  * @class ACE_TSS_TPQ_Entry
00207  *
00208  * @brief ACE_TSS_TPQ_Entry
00209  *
00210  * Not a public interface.
00211  */
00212 class ACE_Export ACE_TSS_TPQ_Entry : public ACE_TPQ_ENTRY
00213 {
00214 public:
00215   /// These are passed to the constructor of ACE_TPQ_Entry in
00216   /// make_TSS_TYPE
00217   ACE_TSS_TPQ_Entry (const ACE_Token_Proxy *proxy,
00218                      const ACE_TCHAR *client_id);
00219 
00220   /// Destructor.
00221   virtual ~ACE_TSS_TPQ_Entry (void);
00222 
00223   /// Allows us to pass args to the construction of the TSS object.
00224   virtual ACE_TPQ_Entry *make_TSS_TYPE (void) const;
00225 
00226   /// Operator overloading and inheritence don't mix.
00227   operator ACE_TPQ_Entry *(void);
00228 
00229   /// Dump the state of the class.
00230   void dump (void) const;
00231 
00232 #if defined (ACE_NO_TSS_TOKENS)
00233   ACE_TPQ_Entry *operator-> (void)
00234     {
00235       return (ACE_TPQ_Entry *) this;
00236     }
00237 #endif /* ACE_NO_TSS_TOKENS */
00238 
00239 private:
00240   /// Private: should not be used
00241   ACE_TSS_TPQ_Entry (const ACE_TSS_TPQ_Entry &);
00242   void operator= (const ACE_TSS_TPQ_Entry &);
00243 
00244   // = These are passed to the constructor of ACE_TPQ_Entry in
00245   // make_TSS_TYPE
00246 
00247   /// Proxy.
00248   const ACE_Token_Proxy *proxy_;
00249 
00250   /// Client_id.
00251   const ACE_TCHAR *client_id_;
00252 };
00253 
00254 class ACE_Token_Proxy_Queue;
00255 
00256 // c..
00257 /**
00258  * @class ACE_TPQ_Iterator
00259  *
00260  * @brief Iterates through ACE_Token_Proxy_Queues.
00261  *
00262  * Not a public interface.
00263  */
00264 class ACE_Export ACE_TPQ_Iterator
00265 {
00266 public:
00267   /// Constructor.
00268   ACE_TPQ_Iterator (ACE_Token_Proxy_Queue &q);
00269 
00270   /// Destructor.
00271   ~ACE_TPQ_Iterator (void);
00272 
00273   /// Pass back the <next_item>.
00274   int next (ACE_TPQ_Entry *&next_item);
00275 
00276   /// Returns 1 when all items have been seen, else 0.
00277   int done (void) const;
00278 
00279   /// Move forward by one element in the queue.
00280   void advance (void);
00281 
00282   /// Dump the state of an object.
00283   void dump (void) const;
00284 
00285 private:
00286   ACE_TPQ_Entry *current_;
00287 };
00288 
00289 // 4..
00290 /**
00291  * @class ACE_Token_Proxy_Queue
00292  *
00293  * @brief Token waiter list.
00294  *
00295  * Not a public interface.
00296  * This queue holds all the token proxies waiting for ownership
00297  * of a token.  Along with the proxy reference, it also stores
00298  * the nesting level, client id, and a magic cookie from the
00299  * proxy.  This queue stores the ACE_TPQ_Entries by pointer
00300  * values.  It DOES NOT make copies.  Thus, the user is
00301  * responsible to ensure that the TPQ's stick around.  This is
00302  * motivated by the need to reduce dynamic memory allocation.
00303  */
00304 class ACE_Export ACE_Token_Proxy_Queue
00305 {
00306 public:
00307   friend class ACE_TPQ_Iterator;
00308 
00309   /// Constructor.
00310   ACE_Token_Proxy_Queue (void);
00311 
00312   /// Destructor.
00313   ~ACE_Token_Proxy_Queue (void);
00314 
00315   /**
00316    * Enqueue a proxy, nesting level, client_id, and a magic cookie at
00317    * the given position in the list.  If the position is -1, we
00318    * enqueue at the end of the list (I think).
00319    */
00320   void enqueue (ACE_TPQ_Entry* new_entry,
00321                 int position);
00322 
00323   /// Top of the queue.
00324   const ACE_TPQ_Entry* head (void);
00325 
00326 //  int member (const ACE_TCHAR *id);
00327   // Is this id in the waiter list?
00328 
00329   /// Remove the top waiter.
00330   void dequeue (void);
00331 
00332   /// Remove the waiter whose proxy ref matches @a remove_me.
00333   void remove (const ACE_TPQ_Entry *remove_me);
00334 
00335   /// The number of waiters.
00336   int size (void);
00337 
00338   /// Dump the state of the class.
00339   void dump (void) const;
00340 
00341 protected:
00342   /// Head.
00343   ACE_TPQ_Entry *head_;
00344 
00345   /// Tail.
00346   ACE_TPQ_Entry *tail_;
00347 
00348   /// Size.
00349   int size_;
00350 };
00351 
00352 // 5..
00353 /**
00354  * @class ACE_Tokens
00355  *
00356  * @brief Abstract representation of ACE tokens.
00357  *
00358  * Not a public interface.
00359  * Currently, I don't see a reason for providing an abstract
00360  * interface at this level of the library.  As of yet, no one
00361  * uses ACE_Tokens derivatives through this abstract interface
00362  * except for ACE_Token_Manager.  It only uses the statistical
00363  * methods which are shared by all Tokens.  For that reason, it
00364  * still makes since to have a common base class.  However,
00365  * acquire, renew, and release do not need to have matching
00366  * interfaces throughout all Tokens.
00367  * To add a new type of token (e.g. semaphore), this class must
00368  * be subtyped to define the new semantics.  See
00369  * ACE_Token_Manager for details.
00370  */
00371 class ACE_Export ACE_Tokens
00372 {
00373 public:
00374 
00375   /// Null constructor.
00376   ACE_Tokens (void);
00377 
00378   /// Destructor
00379   virtual ~ACE_Tokens (void);
00380 
00381   /// No implementation.
00382   virtual int acquire (ACE_TPQ_Entry *caller,
00383                        int ignore_deadlock,
00384                        int notify) = 0;
00385 
00386   /// No implementation.
00387   virtual int tryacquire (ACE_TPQ_Entry *caller) = 0;
00388 
00389   /// No implementation.
00390   virtual int renew (ACE_TPQ_Entry *caller,
00391                      int requeue_position) = 0;
00392 
00393   /// No implementation.
00394   virtual int release (ACE_TPQ_Entry *caller) = 0;
00395 
00396   /// Move the caller to the front of the waiter list.  This is for use
00397   /// with remote mutexes and shadow mutexes.
00398   void make_owner (ACE_TPQ_Entry *caller);
00399 
00400   /// Remove the caller from the waiter list.
00401   void remove (ACE_TPQ_Entry *caller);
00402 
00403   // = Accessor methods.
00404 
00405   /// Stack of owners.
00406   typedef ACE_Unbounded_Stack<ACE_TPQ_Entry *> OWNER_STACK;
00407 
00408   /// Returns a stack of the current owners.  Returns -1 on error, 0 on
00409   /// success.  If <id> is non-zero, returns 1 if id is an owner.
00410   virtual int owners (OWNER_STACK &o, const ACE_TCHAR *id) = 0;
00411 
00412   /// Returns 1 if <id> is waiting for this token.  0 otherwise.
00413   virtual int is_waiting_for (const ACE_TCHAR *id) = 0;
00414 
00415   /// Returns 1 if <id> is an owner of this token.  0 otherwise.
00416   virtual int is_owner (const ACE_TCHAR *id) = 0;
00417 
00418   /// Return the queue of waiters.
00419   virtual ACE_Token_Proxy_Queue *waiters (void);
00420 
00421   /// Return the number of proxies that are currently waiting to get
00422   /// the token.
00423   virtual int no_of_waiters (void);
00424 
00425   /// The current owner.
00426   const ACE_TCHAR *owner_id (void);
00427 
00428   /// Token name.
00429   const ACE_TCHAR* name (void);
00430 
00431   // = Reference counting.  These are only called by the
00432   // Token_Manager.
00433   void inc_reference (void);
00434   int dec_reference (void);
00435 
00436   /// Dump the state of the class.
00437   void dump (void) const;
00438 
00439   /**
00440    * These are the Token types supported by the library at ship time.
00441    * There is no restriction on the number of Token types added by
00442    * "3rd parties."  These are only necessary for the Token Server.
00443    */
00444   enum TOKEN_TYPES { MUTEX, RWLOCK };
00445 
00446   /**
00447    * Provides a manual RTTI mechanism.  This method is used only by
00448    * ACE_Token_Request so that the type of a token can be sent to a
00449    * remote Token Server.
00450    */
00451   virtual int type (void) const = 0;
00452 
00453   // = The following methods allow the deadlock detection algorithm to
00454   // check if this token has been visited.
00455 
00456   /// Mark or unmark the token as visited.
00457   void visit (int v);
00458 
00459   /// Check if the token has been visited.
00460   int visited (void);
00461 
00462   /// All the data of the current owner.
00463   ACE_TPQ_Entry *owner (void);
00464 
00465 protected:
00466 
00467   /// For the deadlock detection algorithm.
00468   int visited_;
00469 
00470   /// Reference count.
00471   int reference_count_;
00472 
00473   /// List of client's owning and waiting the token.
00474   ACE_Token_Proxy_Queue waiters_;
00475 
00476   /// Name of token.
00477   ACE_TCHAR token_name_[ACE_MAXTOKENNAMELEN];
00478 };
00479 
00480 class ACE_Local_Mutex;
00481 
00482 // 6..
00483 /**
00484  * @class ACE_Mutex_Token
00485  *
00486  * @brief Class that acquires, renews, and releases a process-local
00487  * synchronization token.
00488  *
00489  * Not a public interface.
00490  * This class is a more general-purpose synchronization mechanism
00491  * than SunOS 5.x mutexes.  For example, it implements "recursive
00492  * mutex" semantics, where a thread that owns the token can
00493  * reacquire it without deadlocking.  In addition, threads that
00494  * are blocked awaiting the token are serviced in strict FIFO
00495  * order as other threads release the token (SunOS 5.x mutexes
00496  * don't strictly enforce an acquisition order).
00497  */
00498 class ACE_Export ACE_Mutex_Token : public ACE_Tokens
00499 {
00500 public:
00501   /// Constructor
00502   explicit ACE_Mutex_Token (const ACE_TCHAR* name);
00503 
00504   /// Destructor
00505   virtual ~ACE_Mutex_Token (void);
00506 
00507   // = Synchronization operations.
00508   // With acquire, renew, and release, the caller must be specified so
00509   // that multiple proxies (e.g. ACE_Local_Mutex) can use the same
00510   // token.
00511 
00512   /**
00513    * Returns 0 on success, -1 on failure with <ACE_Log_Msg::errnum> as
00514    * the reason.  If errnum == EWOULDBLOCK, and notify == 1,
00515    * <ACE_Token_Proxy::sleep_hook> has been called on the current
00516    * owner of the token.  If ignore_deadlock is passed as 1 and errnum
00517    * == EDEADLK, then deadlock was detected via ace_token_manager.
00518    */
00519   virtual int acquire (ACE_TPQ_Entry *caller,
00520                        int ignore_deadlock,
00521                        int notify);
00522 
00523   /// Same as acquire, but fails if would block
00524   virtual int tryacquire (ACE_TPQ_Entry *caller);
00525 
00526   /**
00527    * An optimized method that efficiently reacquires the token if no
00528    * other threads are waiting.  This is useful for situations where
00529    * you don't want to degrade the quality of service if there are
00530    * other threads waiting to get the token.  If <requeue_position> ==
00531    * -1 and there are other threads waiting to obtain the token we are
00532    * queued at the end of the list of waiters.  If <requeue_position>
00533    * > -1 then it indicates how many entries to skip over before
00534    * inserting our thread into the list of waiters (e.g.,
00535    * <requeue_position> == 0 means "insert at front of the queue").
00536    * Renew has the rather odd semantics such that if there are other
00537    * waiting threads it will give up the token even if the
00538    * nesting_level_ > 1.  I'm not sure if this is really the right
00539    * thing to do (since it makes it possible for shared data to be
00540    * changed unexpectedly) so use with caution...  Returns 0 on
00541    * success, -1 on failure with <ACE_Log_Msg::errnum> as the reason.
00542    * If errnum == EWOULDBLOCK, and notify == 1,
00543    * <ACE_Token_Proxy::sleep_hook> has been called on the current
00544    * owner of the token.
00545    */
00546   virtual int renew (ACE_TPQ_Entry *caller,
00547                      int requeue_position);
00548 
00549   /**
00550    * Relinquish the token.  If there are any waiters then the next one
00551    * in line gets it.  If the caller is not the owner, caller is
00552    * removed from the waiter list.
00553    */
00554   virtual int release (ACE_TPQ_Entry *caller);
00555 
00556   /// Dump the state of the class.
00557   void dump (void) const;
00558 
00559   /// Returns ACE_Tokens::MUTEX.
00560   virtual int type (void) const;
00561 
00562   /// Returns a stack of the current owners.  Returns -1 on error, 0 on
00563   /// success.  If <id> is non-zero, returns 1 if id is an owner.
00564   virtual int owners (OWNER_STACK &o, const ACE_TCHAR *id);
00565 
00566   /// Returns 1 if <id> is waiting for this token.  0 otherwise.
00567   virtual int is_waiting_for (const ACE_TCHAR *id);
00568 
00569   /// Returns 1 if <id> is an owner of this token.  0 otherwise.
00570   virtual int is_owner (const ACE_TCHAR *id);
00571 
00572 private:
00573   /// ACE_Mutex_Token used to lock internal data structures.
00574   ACE_TOKEN_CONST::MUTEX lock_;
00575 };
00576 
00577 // 12..
00578 /**
00579  * @class ACE_RW_Token
00580  *
00581  * @brief Class that acquires, renews, and releases a process-local
00582  * synchronization token.
00583  *
00584  * Not a public interface.
00585  * This class is a more general-purpose synchronization mechanism
00586  * than SunOS 5.x mutexes.  For example, it implements "recursive
00587  * mutex" semantics, where a thread that owns the token can
00588  * reacquire it without deadlocking.  In addition, threads that are
00589  * blocked awaiting the token are serviced in strict FIFO order as
00590  * other threads release the token (SunOS 5.x mutexes don't strictly
00591  * enforce an acquisition order).
00592  */
00593 class ACE_Export ACE_RW_Token : public ACE_Tokens
00594 {
00595 public:
00596   /// Constructor.
00597   explicit ACE_RW_Token (const ACE_TCHAR* name);
00598 
00599   /// Destructor.
00600   virtual ~ACE_RW_Token (void);
00601 
00602   // = Synchronization operations.
00603   // With acquire, renew, and release, the caller must be specified so
00604   // that multiple proxies (e.g. ACE_Local_Mutex) can use the same
00605   // token.
00606 
00607   /**
00608    * Returns 0 on success, -1 on failure with <ACE_Log_Msg::errnum> as
00609    * the reason.  If errnum == EWOULDBLOCK, and notify == 1,
00610    * <ACE_Token_Proxy::sleep_hook> has been called on the current
00611    * owner of the token.  If @a ignore_deadlock is passed as 1 and errnum
00612    * == EDEADLK, then deadlock was detected via ACE_Token_Manager.
00613    */
00614   virtual int acquire (ACE_TPQ_Entry *caller,
00615                        int ignore_deadlock,
00616                        int notify);
00617 
00618   /// Same as acquire except fails on would block
00619   virtual int tryacquire (ACE_TPQ_Entry *caller);
00620 
00621   /**
00622    * An optimized method that efficiently reacquires the token if no
00623    * other threads are waiting.  This is useful for situations where
00624    * you don't want to degrade the quality of service if there are
00625    * other threads waiting to get the token.  If <requeue_position> ==
00626    * -1 and there are other threads waiting to obtain the token we are
00627    * queued at the end of the list of waiters.  If <requeue_position>
00628    * > -1 then it indicates how many entries to skip over before
00629    * inserting our thread into the list of waiters (e.g.,
00630    * <requeue_position> == 0 means "insert at front of the queue").
00631    * Renew has the rather odd semantics such that if there are other
00632    * waiting threads it will give up the token even if the
00633    * nesting_level_ > 1.  I'm not sure if this is really the right
00634    * thing to do (since it makes it possible for shared data to be
00635    * changed unexpectedly) so use with caution...  Returns 0 on
00636    * success, -1 on failure with <ACE_Log_Msg::errnum> as the reason.
00637    * If errnum == EWOULDBLOCK, and notify == 1,
00638    * <ACE_Token_Proxy::sleep_hook> has been called on the current
00639    * owner of the token.
00640    */
00641   virtual int renew (ACE_TPQ_Entry *caller,
00642                      int requeue_position);
00643 
00644   /**
00645    * Relinquish the token.  If there are any waiters then the next one
00646    * in line gets it.  If the caller is not the owner, caller is
00647    * removed from the waiter list.
00648    */
00649   virtual int release (ACE_TPQ_Entry *caller);
00650 
00651   /// Dump the state of the class.
00652   void dump (void) const;
00653 
00654   /// These are the types that proxies can be.
00655   enum PROXY_TYPE { READER, WRITER };
00656 
00657   /// Returns READER or WRITER.
00658   virtual int type (void) const;
00659 
00660   /// Returns a stack of the current owners.  Returns -1 on error, 0 on
00661   /// success.  If <id> is non-zero, returns 1 if id is an owner.
00662   virtual int owners (OWNER_STACK &o, const ACE_TCHAR *id);
00663 
00664   /// Returns 1 if <id> is waiting for this token.  0 otherwise.
00665   virtual int is_waiting_for (const ACE_TCHAR *id);
00666 
00667   /// Returns 1 if <id> is an owner of this token.  0 otherwise.
00668   virtual int is_owner (const ACE_TCHAR *id);
00669 
00670 protected:
00671   /// The number of waiting writers.
00672   int num_writers_;
00673 
00674   /// ACE_Mutex_Token used to lock internal data structures.
00675   ACE_TOKEN_CONST::MUTEX lock_;
00676 
00677   /// Sets the new owner.
00678   void notify_new_owner (ACE_TPQ_Entry *caller);
00679 };
00680 
00681 // a..
00682 /**
00683  * @class ACE_Token_Name
00684  *
00685  * @brief Allows Token_Manger to identify tokens.
00686  *
00687  * For now, this is just a string.  We need a string class
00688  * anyway to use in <ACE_Map_Manager>.  Having this class
00689  * (instead of <ACE_SString>) allows us to easily change if
00690  * needed.  For instance, we may choose to identify tokens by
00691  * name and *type* in the future.
00692  */
00693 class ACE_Export ACE_Token_Name
00694 {
00695 public:
00696   /// Construction.
00697   ACE_Token_Name (const ACE_TCHAR *token_name = 0);
00698 
00699   /// Copy construction.
00700   ACE_Token_Name (const ACE_Token_Name &rhs);
00701 
00702   /// Destructor.
00703   virtual ~ACE_Token_Name (void);
00704 
00705   /// Copy.
00706   void operator= (const ACE_Token_Name &rhs);
00707 
00708   /// Comparison.
00709   bool operator== (const ACE_Token_Name &rhs) const;
00710 
00711   /// Get the token name.
00712   const ACE_TCHAR *name (void) const;
00713 
00714   /// Set the token name.
00715   void name (const ACE_TCHAR *new_name);
00716 
00717   /// Dump the state of the class.
00718   void dump (void) const;
00719 
00720 private:
00721   /// Name of the token.
00722   ACE_TCHAR token_name_[ACE_MAXTOKENNAMELEN];
00723 };
00724 
00725 // 7..
00726 /**
00727  * @class ACE_Token_Proxy
00728  *
00729  * @brief Abstract representation of ACE tokens.
00730  *
00731  * Interface for all Tokens in ACE.  This class implements the
00732  * synchronization needed for tokens (condition variables etc.)
00733  * The algorithms for the operations (acquire, release, etc.)
00734  * operate on the generic ACE_Tokens interface.  Thus, the _type_
00735  * of token (mutex, rwlock) can be set at construction of
00736  * ACE_Token_Proxy.  You can use all Tokens in ACE through the
00737  * ACE_Token_Proxy by passing the proper values at construction.
00738  * Alternatively, there are class definitions which "know" how to
00739  * do this (ACE_Local_Mutex, ACE_Local_RLock, ACE_Local_WLock).
00740  * To add a new type of token (e.g. semaphore), this class is not
00741  * changed.  See ACE_Token_Manager for details.
00742  * Tokens (e.g. ACE_Mutex_Token) assume that it can always call
00743  * <ACE_Token_Proxy::token_acquired> on a new token owner.  This
00744  * is not a problem for synchronous use of token proxies (that is,
00745  * when acquires block until successful.)  However, for
00746  * implementations of the Token Server, which may use asynch
00747  * operations, the proxy can not go away after an acquire until
00748  * the token is acquired.  This is not really a problem, but
00749  * should be understood.
00750  */
00751 class ACE_Export ACE_Token_Proxy
00752 {
00753 public:
00754   friend class ACE_Token_Manager;
00755   friend class ACE_Token_Invariant_Manager; // For testing.
00756 
00757   // Initialization and termination methods.
00758   /// Construction.
00759   ACE_Token_Proxy (void);
00760 
00761   /// Destructor.
00762   virtual ~ACE_Token_Proxy (void);
00763 
00764   /**
00765    * Open the <ACE_Token>.
00766    * @param name The string uniquely identifying the token.
00767    * @param ignore_deadlock Can be 1 to disable deadlock notifications.
00768    * @param debug Prints debug messages.
00769    */
00770   virtual int open (const ACE_TCHAR *name,
00771                     int ignore_deadlock = 0,
00772                     int debug = 0);
00773 
00774   // = The following methods have implementations which are
00775   // independent of the token semantics (mutex, rwlock, etc.)  They
00776   // forward operations to the underlying token and perform the
00777   // necessary blocking semantics for operations (condition variables
00778   // etc.)  This allows reuse of the blocking code as well as having
00779   // multiple proxies to the same token.
00780 
00781   /// Calls acquire on the token.  Blocks the calling thread if would
00782   /// block.
00783   virtual int acquire (int notify = 0,
00784                        void (*sleep_hook)(void *) = 0,
00785                        ACE_Synch_Options &options =
00786                        ACE_Synch_Options::defaults);
00787 
00788   /// Calls renew on the token.  Blocks the calling thread if would block.
00789   virtual int renew (int requeue_position = -1,
00790                      ACE_Synch_Options &options =
00791                      ACE_Synch_Options::defaults);
00792 
00793   /// Calls renew on the token.
00794   virtual int tryacquire (void (*sleep_hook)(void *) = 0);
00795 
00796   /// Calls release on the token.
00797   virtual int release (ACE_Synch_Options &options =
00798                        ACE_Synch_Options::defaults);
00799 
00800   /// Calls remove on the token.
00801   virtual int remove (ACE_Synch_Options &options =
00802                       ACE_Synch_Options::defaults);
00803 
00804   /// Since the locking mechanism doesn't support read locks then this
00805   /// just calls <acquire>.
00806   virtual int acquire_read (int notify = 0,
00807                             void (*sleep_hook)(void *) = 0,
00808                             ACE_Synch_Options &options =
00809                             ACE_Synch_Options::defaults);
00810 
00811   /// Since the locking mechanism doesn't support write locks then this
00812   /// just calls <acquire>.
00813   virtual int acquire_write (int notify = 0,
00814                              void (*sleep_hook)(void *) = 0,
00815                              ACE_Synch_Options &options =
00816                              ACE_Synch_Options::defaults);
00817 
00818   /// Since the locking mechanism doesn't support read locks then this
00819   /// just calls <tryacquire>.
00820   virtual int tryacquire_read (void (*sleep_hook)(void *) = 0);
00821 
00822   /// Since the locking mechanism doesn't support write locks then this
00823   /// just calls <tryacquire>.
00824   virtual int tryacquire_write (void (*sleep_hook)(void *) = 0);
00825 
00826   // = Utility methods.
00827 
00828   /// Get the client id of the proxy.  This is implemented as
00829   /// thread-specific data.
00830   virtual const ACE_TCHAR *client_id (void) const;
00831 
00832   /**
00833    * Set the client_id for the calling thread.  I strongly recommend
00834    * that this not be used unless you really know what you're doing.
00835    * I use this in the Token Server, and it caused many headaches.
00836    */
00837   virtual void client_id (const ACE_TCHAR *client_id);
00838 
00839   /**
00840    * Return the name of the token.  This is important for use within
00841    * the token servers (local and remote) as well as with token
00842    * collections.  So, all derivations of ACE_Token_Proxy must be able to
00843    * stringify some name.  The name must uniquely identify a token.
00844    * So, for instance, the token within the reactor should probably be
00845    * called "Reactor Token."
00846    */
00847   virtual const ACE_TCHAR *name (void) const;
00848 
00849   /**
00850    * This should really be called <someone_waiting>.  This is called
00851    * by ACE_Token_xx's when another proxy enters the waiting list and
00852    * requests that the current token holder be notified.
00853    */
00854   virtual void sleep_hook (void);
00855 
00856   /// This is called when a queued (waiting) proxy is removed from the
00857   /// waiters list and given the token.
00858   virtual void token_acquired (ACE_TPQ_Entry *);
00859 
00860   /// The client id of the current token holder
00861   virtual const ACE_TCHAR *owner_id (void);
00862 
00863   /// Return a dynamically allocated clone of the derived class.
00864   virtual ACE_Token_Proxy *clone (void) const = 0;
00865 
00866   /// Dump the state of the class.
00867   void dump (void) const;
00868 
00869   /**
00870    * This method can be used be Tokens (e.g. Readers/Writer Tokens) to
00871    * distinguish between Proxy types.  For instance a Reader proxy
00872    * should return a different type value than a Writer proxy.  The
00873    * default implementation returns 0.
00874    */
00875   virtual int type (void) const;
00876 
00877 protected:
00878   /// Duplication.
00879   ACE_Token_Proxy (const ACE_Token_Proxy &);
00880 
00881   /// If this is set, we ignore deadlock.
00882   int ignore_deadlock_;
00883 
00884   /// Print a bunch of debug messages.
00885   int debug_;
00886 
00887   /// Reference to the actual logical token.  Many ACE_Local_Mutex
00888   /// proxies can reference the same ACE_Mutex_Token.
00889   ACE_Tokens *token_;
00890 
00891   /// Handles cond_var waits.
00892   int handle_options (ACE_Synch_Options &options,
00893                       ACE_TOKEN_CONST::COND_VAR &cv);
00894 
00895   /// Waiter info used for asynchronous transactions.
00896   ACE_TSS_TPQ_Entry waiter_;
00897 
00898   /// Make the correct type of ACE_Tokens.  This is called by the Token
00899   /// Manager.
00900   virtual ACE_Tokens *create_token (const ACE_TCHAR *name) = 0;
00901 };
00902 
00903 // 8..
00904 /**
00905  * @class ACE_Null_Token
00906  *
00907  * @brief No op class for nonthreaded platform protocols.
00908  */
00909 class ACE_Export ACE_Null_Token : public ACE_Token_Proxy
00910 {
00911 public:
00912 #if defined (ACE_LACKS_INLINE_FUNCTIONS)
00913   // @@ Hopefully, we can remove this ridicules ifdef when CE's compiler becomes more normal.
00914   /// Construction.
00915   ACE_Null_Token (void);
00916 
00917   /// Destructor.
00918   ~ACE_Null_Token (void);
00919 #endif /* ACE_LACKS_INLINE_FUNCTION */
00920 
00921   /// Acquire.
00922   virtual int acquire (int /* notify */ = 0,
00923                        void (* /* sleep_hook */ )(void *) = 0,
00924                        ACE_Synch_Options & /* options */ =
00925                        ACE_Synch_Options::defaults) { return 0; }
00926 
00927   /// Renew.
00928   virtual int renew (int /* requeue_position */ = -1,
00929                      ACE_Synch_Options & /* options */ =
00930                      ACE_Synch_Options::defaults) { return 0; }
00931 
00932   /// Try acquire.
00933   virtual int tryacquire (void (* /* sleep_hook */)(void *) = 0) { return 0; }
00934 
00935   /// Release.
00936   virtual int release (ACE_Synch_Options & /* options */ =
00937                        ACE_Synch_Options::defaults) { return 0; }
00938 
00939   /// Remove.
00940   virtual int remove (ACE_Synch_Options & /* options */ =
00941                       ACE_Synch_Options::defaults) { return 0; }
00942 
00943   /// Return a dynamically allocated clone of the derived class.
00944   virtual ACE_Token_Proxy *clone (void) const { return new ACE_Null_Token; }
00945 
00946   /// Dump the state of the class.
00947   void dump (void) const;
00948 
00949   /// Do not allow the Token Manager to create us.
00950   virtual ACE_Tokens *create_token (const ACE_TCHAR *) { return 0; }
00951 };
00952 
00953 // 9..
00954 /**
00955  * @class ACE_Local_Mutex
00956  *
00957  * @brief Class that acquires, renews, and releases a synchronization
00958  * token local to the process.
00959  *
00960  * This class is a more general-purpose synchronization mechanism
00961  * than SunOS 5.x mutexes.  For example, it implements "recursive
00962  * mutex" semantics, where a thread that owns the token can
00963  * reacquire it without deadlocking.  In addition, threads that
00964  * are blocked awaiting the token are serviced in strict FIFO
00965  * order as other threads release the token (SunOS 5.x mutexes
00966  * don't strictly enforce an acquisition order).  Lastly,
00967  * ACE_Local_Mutex performs deadlock detection on acquire calls.
00968  * The interfaces for acquire, tryacquire, renew, release,
00969  * etc. are defined in ACE_Token_Proxy.  The semantics for
00970  * ACE_Local_Mutex are that of a mutex.
00971  */
00972 class ACE_Export ACE_Local_Mutex : public ACE_Token_Proxy
00973 {
00974 public:
00975   /**
00976    * Constructor.
00977    * @param token_name Uniquely id's the token.
00978    * @param ignore_deadlock Will allow deadlock to occur (useful for testing).
00979    * @param debug Prints a bunch of messages.
00980    */
00981   ACE_Local_Mutex (const ACE_TCHAR *token_name = 0,
00982                    int ignore_deadlock = 0,
00983                    int debug = 0);
00984 
00985   /// Destructor
00986   ~ACE_Local_Mutex (void);
00987 
00988   /// Dump the state of the class.
00989   void dump (void) const;
00990 
00991   /// Return deep copy.
00992   virtual ACE_Token_Proxy *clone (void) const;
00993 
00994 protected:
00995   /// Return a new ACE_Local_Mutex.
00996   virtual ACE_Tokens *create_token (const ACE_TCHAR *name);
00997 };
00998 
00999 // *.
01000 /**
01001  * @class ACE_Local_RLock
01002  *
01003  * @brief Class that acquires, renews, and releases a readers lock that
01004  * is local to the process.
01005  *
01006  * This class implements the reader interface to canonical
01007  * readers/writer locks.  Multiple readers can hold the lock
01008  * simultaneously when no writers have the lock.  Alternatively,
01009  * when a writer holds the lock, no other participants (readers
01010  * or writers) may hold the lock.  This class is a more
01011  * general-purpose synchronization mechanism than SunOS 5.x
01012  * RLocks.  For example, it implements "recursive RLock"
01013  * semantics, where a thread that owns the token can reacquire it
01014  * without deadlocking.  In addition, threads that are blocked
01015  * awaiting the token are serviced in strict FIFO order as other
01016  * threads release the token (SunOS 5.x RLockes don't strictly
01017  * enforce an acquisition order).
01018  * The interfaces for acquire, tryacquire, renew, release,
01019  * etc. are defined in ACE_Token_Proxy.  The semantics for
01020  * ACE_Local_RLock are that of a readers/writers lock.  Acquire
01021  * for this class implies a reader acquisition.  That is,
01022  * multiple clients may acquire a lock for read only.
01023  */
01024 class ACE_Export ACE_Local_RLock : public ACE_Token_Proxy
01025 {
01026 public:
01027   // = Initialization and termination.
01028 
01029   /**
01030    * Constructor.
01031    * @param token_name Uniquely id's the token.
01032    * @param ignore_deadlock Will allow deadlock to occur (useful for testing).
01033    * @param debug Prints a bunch of messages.
01034    */
01035   ACE_Local_RLock (const ACE_TCHAR *token_name = 0,
01036                    int ignore_deadlock = 0,
01037                    int debug = 0);
01038 
01039   /// Destructor
01040   ~ACE_Local_RLock (void);
01041 
01042   /// Dump the state of the class.
01043   void dump (void) const;
01044 
01045   /// Returns ACE_RW_Token::RLOCK.
01046   virtual int type (void) const;
01047 
01048   /// Return deep copy.
01049   virtual ACE_Token_Proxy *clone (void) const;
01050 
01051 protected:
01052   /// Return a new ACE_Local_Mutex.
01053   virtual ACE_Tokens *create_token (const ACE_TCHAR *name);
01054 };
01055 
01056 // *.
01057 /**
01058  * @class ACE_Local_WLock
01059  *
01060  * @brief Class that acquires, renews, and releases a writer lock that
01061  * is local to the process.
01062  *
01063  * This class implements the writer interface to canonical
01064  * readers/writer locks. Multiple readers can hold the lock
01065  * simultaneously when no writers have the lock.  Alternatively,
01066  * when a writer holds the lock, no other participants (readers
01067  * or writers) may hold the lock.  This class is a more
01068  * general-purpose synchronization mechanism than SunOS 5.x
01069  * WLock.  For example, it implements "recursive WLock"
01070  * semantics, where a thread that owns the token can reacquire it
01071  * without deadlocking.  In addition, threads that are blocked
01072  * awaiting the token are serviced in strict FIFO order as other
01073  * threads release the token (SunOS 5.x WLocks don't strictly
01074  * enforce an acquisition order).
01075  * The interfaces for acquire, tryacquire, renew, release,
01076  * etc. are defined in ACE_Token_Proxy.  The semantics for
01077  * ACE_Local_WLock are that of a readers/writers lock.  Acquire
01078  * for this class implies a writer acquisition.  That is, only
01079  * one client may hold the lock for writing.
01080  */
01081 class ACE_Export ACE_Local_WLock : public ACE_Token_Proxy
01082 {
01083 public:
01084   // = Initialization and termination.
01085 
01086   /**
01087    * Constructor.
01088    * @param token_name Uniquely id's the token.
01089    * @param ignore_deadlock Will allow deadlock to occur (useful for testing).
01090    * @param debug Prints a bunch of messages.
01091    */
01092   ACE_Local_WLock (const ACE_TCHAR *token_name = 0,
01093                    int ignore_deadlock = 0,
01094                    int debug = 0);
01095 
01096   /// Destructor
01097   ~ACE_Local_WLock (void);
01098 
01099   /// Dump the state of the class.
01100   void dump (void) const;
01101 
01102   /// Returns ACE_RW_Token::WLOCK.
01103   virtual int type (void) const;
01104 
01105   /// Return deep copy.
01106   virtual ACE_Token_Proxy *clone (void) const;
01107 
01108 protected:
01109   /// Return a new ACE_Local_Mutex.
01110   ACE_Tokens *create_token (const ACE_TCHAR *name);
01111 };
01112 
01113 ACE_END_VERSIONED_NAMESPACE_DECL
01114 
01115 #endif /* ACE_HAS_TOKENS_LIBRARY */
01116 
01117 #if defined (__ACE_INLINE__)
01118 #include "ace/Local_Tokens.inl"
01119 #endif /* __ACE_INLINE__ */
01120 #include /**/ "ace/post.h"
01121 #endif /* ACE_LOCAL_MUTEX_H */

Generated on Thu Nov 9 09:41:53 2006 for ACE by doxygen 1.3.6