Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Local_Tokens.h

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

Generated on Mon Jun 16 11:19:58 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002