summaryrefslogtreecommitdiff
path: root/ace/Local_Tokens.h
diff options
context:
space:
mode:
authorlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1996-10-21 21:41:34 +0000
committerlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1996-10-21 21:41:34 +0000
commita5fdebc5f6375078ec1763850a4ca23ec7fe6458 (patch)
treebcf0a25c3d45a209a6e3ac37b233a4812f29c732 /ace/Local_Tokens.h
downloadATCD-a5fdebc5f6375078ec1763850a4ca23ec7fe6458.tar.gz
Initial revision
Diffstat (limited to 'ace/Local_Tokens.h')
-rw-r--r--ace/Local_Tokens.h974
1 files changed, 974 insertions, 0 deletions
diff --git a/ace/Local_Tokens.h b/ace/Local_Tokens.h
new file mode 100644
index 00000000000..6d5786f2658
--- /dev/null
+++ b/ace/Local_Tokens.h
@@ -0,0 +1,974 @@
+/* -*- C++ -*- */
+// $Id$
+
+
+// ============================================================================
+//
+// = LIBRARY
+// ace
+//
+// = FILENAME
+// Local_Tokens
+//
+// = AUTHOR
+// Karl-Heinz Dorn (kdorn@erlh.siemens.de)
+// Douglas C. Schmidt (schmidt@cs.wustl.edu)
+// Tim Harrison (harrison@cs.wustl.edu)
+//
+// = DESCRIPTION
+// This file contains definitions for the following classes:
+//
+// public:
+// 7. ACE_Token_Proxy
+// 8. ACE_Null_Token : public ACE_Token_Proxy
+// 9. ACE_Local_Mutex : public ACE_Token_Proxy
+// *. ACE_Local_RLock : public ACE_Local_Mutex
+// &. ACE_Local_WLock : public ACE_Local_Mutex
+// private:
+// 1. ACE_TOKEN_CONST
+// 3. ACE_TPQ_Entry
+// b. ACE_TSS_TPQ_Entry
+// c. ACE_TPQ_Iterator
+// 4. ACE_Token_Proxy_Queue
+// 5. ACE_Tokens
+// 6. ACE_Mutex_Token : public ACE_Tokens
+// 12. ACE_RW_Token : public ACE_Tokens
+// a. ACE_Token_Name
+//
+// ============================================================================
+
+#if !defined (ACE_LOCAL_MUTEX_H)
+#define ACE_LOCAL_MUTEX_H
+
+#include "ace/Synch.h"
+#include "ace/Stack.h"
+#include "ace/Synch_Options.h"
+#include "ace/Map_Manager.h"
+
+// 1.
+class ACE_Export ACE_TOKEN_CONST
+{
+ // = TITLE
+ // Not a public interface.
+ //
+ // = DESCRIPTION
+ // Constant definitions and typdefs for Token library. Mostly,
+ // this class is necessary to fight the compiler with order of
+ // declaration errors.
+public:
+#if defined (ACE_MT_SAFE)
+ // ACE platform supports some form of threading.
+ typedef ACE_Condition_Thread_Mutex COND_VAR;
+ typedef ACE_Thread_Mutex MUTEX;
+ typedef ACE_Thread_Mutex_Guard GUARD;
+#else
+ typedef ACE_Null_Condition_Mutex COND_VAR;
+ typedef ACE_Null_Mutex MUTEX;
+ typedef ACE_Null_Mutex_Guard GUARD;
+#endif /* ACE_HAS_THREADS */
+};
+
+class ACE_Token_Proxy;
+
+// 3..
+class ACE_Export ACE_TPQ_Entry
+ // = TITLE
+ // Not a public interface.
+ //
+ // = DESCRIPTION
+ // Token Proxy Queue entry.
+ // Used in the ACE_Token_Proxy_Queue
+{
+friend class ACE_Token_Manager;
+public:
+ typedef void (*PTVF) (void *);
+
+ ACE_TPQ_Entry (void);
+ // Null constructor.
+
+ ACE_TPQ_Entry (const ACE_Token_Proxy *proxy,
+ const char *client_id);
+ // Construction.
+
+ ACE_TPQ_Entry (const ACE_TPQ_Entry &rhs);
+ // Copy constructor.
+
+ ~ACE_TPQ_Entry (void);
+ // Death.
+
+ void operator= (const ACE_TPQ_Entry &rhs);
+ // Copy operator use by the queue.
+
+ // = Set/get top of the queue.
+ ACE_Token_Proxy *proxy (void) const;
+ void proxy (ACE_Token_Proxy *);
+
+ // = Delta/get nesting level of the entry.
+ int nesting_level (void) const;
+ void nesting_level (int delta);
+
+ // = Set/get client_id of the entry.
+ const char *client_id (void) const;
+ void client_id (const char *);
+
+ int equal_client_id (const char *id);
+ // Returns 1 if <id> == client id. Does not check for <id> == 0.
+
+ void set (void (*sleep_hook)(void *));
+ // One method for arg and sleep_hook.
+
+ // = Set/get sleep hook of the entry.
+ void sleep_hook (void (*sh)(void *));
+ PTVF sleep_hook (void) const;
+
+ void call_sleep_hook (void);
+ // Call the sleep hook function or method passing arg.
+
+ ACE_TPQ_Entry *next_;
+ // Pointer to next in list.
+
+ void dump (void) const;
+ // Dump the state of the class.
+
+ // = Used to block the thread if an acquire fails with EWOULDBLOCK.
+ ACE_TOKEN_CONST::MUTEX lock_;
+ ACE_TOKEN_CONST::COND_VAR cond_var_;
+
+ // = Get/set whether this client is blocked waiting for a token.
+ int waiting (void) const;
+ void waiting (int w);
+
+private:
+
+ int waiting_;
+ // This client is waiting for a token.
+
+ ACE_Token_Proxy *proxy_;
+ // Proxy.
+
+ int nesting_level_;
+ // Nesting level.
+
+ void *arg_;
+ // Arg.
+
+ char client_id_[ACE_MAXCLIENTIDLEN];
+ // Client id.
+
+ void (*sleep_hook_)(void *);
+ // Sleep hook.
+};
+
+// ************************************************************
+
+// b..
+#if defined (ACE_NO_TSS_TOKENS)
+typedef ACE_TPQ_Entry ACE_TPQ_ENTRY;
+#else
+typedef ACE_TSS<ACE_TPQ_Entry> ACE_TPQ_ENTRY;
+#endif /* ACE_NO_TSS_TOKENS */
+
+class ACE_Export ACE_TSS_TPQ_Entry : public ACE_TPQ_ENTRY
+ // = TITLE
+ // Not a public interface.
+ // = DESCRIPTION
+ // ACE_TSS_TPQ_Entry
+{
+public:
+ ACE_TSS_TPQ_Entry (const ACE_Token_Proxy *proxy,
+ const char *client_id);
+ // These are passed to the constructor of ACE_TPQ_Entry in
+ // make_TSS_TYPE
+
+ virtual ACE_TPQ_Entry *make_TSS_TYPE (void) const;
+ // Allows us to pass args to the construction of the TSS object.
+
+ operator ACE_TPQ_Entry *(void);
+ // Operator overloading and inheritence don't mix.
+
+ void dump (void) const;
+ // Dump the state of the class.
+
+#if defined (ACE_NO_TSS_TOKENS)
+ ACE_TSS_TPQ_Entry *operator-> (void)
+ {
+ return this;
+ }
+#endif
+
+private:
+ // = These are passed to the constructor of ACE_TPQ_Entry in
+ // make_TSS_TYPE
+ const ACE_Token_Proxy *proxy_;
+ // Proxy.
+ const char *client_id_;
+ // Client_id.
+};
+
+// ************************************************************
+
+class ACE_Token_Proxy_Queue;
+
+// c..
+class ACE_Export ACE_TPQ_Iterator
+ // = TITLE
+ // Not a public interface.
+ //
+ // = DESCRIPTION
+ // Iterates through ACE_Token_Proxy_Queues.
+{
+public:
+ ACE_TPQ_Iterator (ACE_Token_Proxy_Queue &q);
+ // Construction.
+
+ int next (ACE_TPQ_Entry *&next_item);
+ // Pass back the <next_item>. Returns 0 when all items have been
+ // seen, else 1.
+
+ void advance (void);
+ // Move forward by one element in the queue.
+
+ void dump (void) const;
+ // Dump the state of an object.
+
+private:
+ ACE_TPQ_Entry *current_;
+};
+
+// 4..
+class ACE_Export ACE_Token_Proxy_Queue
+ // = TITLE
+ // Not a public interface.
+ //
+ // = DESCRIPTION
+ // Token waiter list.
+ // This queue holds all the token proxies waiting for ownership of
+ // a token. Along with the proxy reference, it also stores the
+ // nesting level, client id, and a magic cookie from the proxy.
+ // This queue stores the ACE_TPQ_Entries by pointer values. It
+ // DOES NOT make copies. Thus, the user is responsible to ensure
+ // that the TPQ's stick around. This is motivated by the need to
+ // reduce dynamic memory allocation.
+{
+ friend class ACE_TPQ_Iterator;
+public:
+ ACE_Token_Proxy_Queue (void);
+ // Construction.
+
+ void enqueue (ACE_TPQ_Entry* new_entry,
+ int position);
+ // Enqueue a proxy, nesting level, client_id, and a magic cookie at
+ // the given position in the list. If the position is -1, we
+ // enqueue at the end of the list (I think).
+
+ const ACE_TPQ_Entry* head (void);
+ // Top of the queue.
+
+// int member (const char *id);
+ // Is this id in the waiter list?
+
+ void dequeue (void);
+ // Remove the top waiter.
+
+ void remove (const ACE_TPQ_Entry *remove_me);
+ // Remove the waiter whose proxy ref matches remove_me.
+
+ int size (void);
+ // The number of waiters.
+
+ void dump (void) const;
+ // Dump the state of the class.
+
+protected:
+ ACE_TPQ_Entry *head_;
+ // Head.
+ ACE_TPQ_Entry *tail_;
+ // Tail.
+ int size_;
+ // Size.
+};
+
+// 5..
+class ACE_Export ACE_Tokens
+ // = TITLE
+ // Not a public interface.
+ //
+ // = DESCRIPTION
+ // Abstract representation of ACE tokens.
+ // Currently, I don't see a reason for providing an abstract
+ // interface at this level of the library. As of yet, no one uses
+ // ACE_Tokens derivatives through this abstract interface except
+ // for Token_Manager. It only uses the statistical methods which
+ // are shared by all Tokens. For that reason, it still makes
+ // since to have a common base class. However, acquire, renew,
+ // and release do not need to have matching interfaces throughout
+ // all Tokens.
+
+ // = EXTENDING TOKENS
+ // To add a new type of token (e.g. semaphore), this class must be
+ // subtyped to define the new semantics. See ACE_Token_Manager
+ // for details.
+{
+public:
+
+ ACE_Tokens (void);
+ // Null constructor.
+
+ virtual int acquire (ACE_TPQ_Entry *caller,
+ int ignore_deadlock,
+ int notify) = 0;
+ // No implementation.
+
+ virtual int tryacquire (ACE_TPQ_Entry *caller) = 0;
+ // No implementation.
+
+ virtual int renew (ACE_TPQ_Entry *caller,
+ int requeue_position) = 0;
+ // No implementation.
+
+ virtual int release (ACE_TPQ_Entry *caller) = 0;
+ // No implementation.
+
+ void make_owner (ACE_TPQ_Entry *caller);
+ // Move the caller to the front of the waiter list. This is for use
+ // with remote mutexes and shadow mutexes.
+
+ void remove (ACE_TPQ_Entry *caller);
+ // Remove the caller from the waiter list.
+
+ // = Accessor methods.
+
+ typedef ACE_Unbounded_Stack<ACE_TPQ_Entry *>
+ OWNER_STACK;
+ // Stack of owners.
+
+ virtual int owners (OWNER_STACK &o, const char *id) = 0;
+ // Returns a stack of the current owners. Returns -1 on error, 0 on
+ // success. If <id> is non-zero, returns 1 if id is an owner.
+
+ virtual int is_waiting_for (const char *id) = 0;
+ // Returns 1 if <id> is waiting for this token. 0 otherwise.
+
+ virtual int is_owner (const char *id) = 0;
+ // Returns 1 if <id> is an owner of this token. 0 otherwise.
+
+ virtual ACE_Token_Proxy_Queue *waiters (void);
+ // Return the queue of waiters.
+
+ virtual int no_of_waiters (void);
+ // Return the number of proxies that are currently waiting to get
+ // the token.
+
+ const char *owner_id (void);
+ // The current owner.
+
+ const char* name (void);
+ // Token name.
+
+ // = Reference counting. These are only called by the
+ // Token_Manager.
+ void inc_reference (void);
+ int dec_reference (void);
+
+ void dump (void) const;
+ // Dump the state of the class.
+
+ enum TOKEN_TYPES { MUTEX, RWLOCK };
+ // These are the Token types supported by the library at ship time.
+ // There is no restriction on the number of Token types added by
+ // "3rd parties." These are only necessary for the Token Server.
+
+ virtual int type (void) const = 0;
+ // Provides a manual RTTI mechanism. This method is used only by
+ // ACE_Token_Request so that the type of a token can be sent to a
+ // remote Token Server.
+
+ // = The following methods allow the deadlock detection algorithm to
+ // check if this token has been visited.
+
+ void visit (int v);
+ // Mark or unmark the token as visited.
+
+ int visited (void);
+ // Check if the token has been visited.
+
+ ACE_TPQ_Entry *owner (void);
+ // All the data of the current owner.
+
+protected:
+
+ int visited_;
+ // For the deadlock detection algorithm.
+
+ int reference_count_;
+ // Reference count.
+
+ ACE_Token_Proxy_Queue waiters_;
+ // List of client's owning and waiting the token.
+
+ char token_name_[ACE_MAXTOKENNAMELEN];
+ // Name of token.
+};
+
+class ACE_Local_Mutex;
+
+// 6..
+class ACE_Export ACE_Mutex_Token : public ACE_Tokens
+ // = TITLE
+ // Not a public interface.
+ //
+ // = DESCRIPTION
+ // Class that acquires, renews, and releases a process-local
+ // synchronization token.
+ // This class is a more general-purpose synchronization mechanism
+ // than SunOS 5.x mutexes. For example, it implements "recursive
+ // mutex" semantics, where a thread that owns the token can
+ // reacquire it without deadlocking. In addition, threads that are
+ // blocked awaiting the token are serviced in strict FIFO order as
+ // other threads release the token (SunOS 5.x mutexes don't strictly
+ // enforce an acquisition order).
+{
+public:
+ ACE_Mutex_Token (const char* name);
+ // life
+
+ ~ACE_Mutex_Token (void);
+ // death
+
+ // = Synchronization operations.
+ // With acquire, renew, and release, the caller must be specified so
+ // that multiple proxies (e.g. ACE_Local_Mutex) can use the same
+ // token.
+
+ virtual int acquire (ACE_TPQ_Entry *caller,
+ int ignore_deadlock,
+ int notify);
+ // Returns 0 on success, -1 on failure with ACE_LOG_MSG->errnum() as
+ // the reason. If errnum == EWOULDBLOCK, and notify == 1,
+ // ACE_Token_Proxy::sleep_hook() has been called on the current owner
+ // of the token. If ignore_deadlock is passed as 1 and errnum ==
+ // EDEADLK, then deadlock was detected via ace_token_manager.
+
+ virtual int tryacquire (ACE_TPQ_Entry *caller);
+ // same as acquire, but fails if would block
+
+ virtual int renew (ACE_TPQ_Entry *caller,
+ int requeue_position);
+ // An optimized method that efficiently reacquires the token if no
+ // other threads are waiting. This is useful for situations where
+ // you don't want to degrade the quality of service if there are
+ // other threads waiting to get the token. If <requeue_position> ==
+ // -1 and there are other threads waiting to obtain the token we are
+ // queued at the end of the list of waiters. If <requeue_position>
+ // > -1 then it indicates how many entries to skip over before
+ // inserting our thread into the list of waiters (e.g.,
+ // <requeue_position> == 0 means "insert at front of the queue").
+ // Renew has the rather odd semantics such that if there are other
+ // waiting threads it will give up the token even if the
+ // nesting_level_ > 1. I'm not sure if this is really the right
+ // thing to do (since it makes it possible for shared data to be
+ // changed unexpectedly) so use with caution...
+ // Returns 0 on success, -1 on failure with ACE_LOG_MSG->errnum() as
+ // the reason. If errnum == EWOULDBLOCK, and notify == 1,
+ // ACE_Token_Proxy::sleep_hook() has been called on the current owner
+ // of the token.
+
+ virtual int release (ACE_TPQ_Entry *caller);
+ // Relinquish the token. If there are any waiters then the next one
+ // in line gets it. If the caller is not the owner, caller is
+ // removed from the waiter list.
+
+ void dump (void) const;
+ // Dump the state of the class.
+
+ virtual int type (void) const;
+ // Returns ACE_Tokens::MUTEX.
+
+ virtual int owners (OWNER_STACK &o, const char *id);
+ // Returns a stack of the current owners. Returns -1 on error, 0 on
+ // success. If <id> is non-zero, returns 1 if id is an owner.
+
+ virtual int is_waiting_for (const char *id);
+ // Returns 1 if <id> is waiting for this token. 0 otherwise.
+
+ virtual int is_owner (const char *id);
+ // Returns 1 if <id> is an owner of this token. 0 otherwise.
+
+private:
+ ACE_TOKEN_CONST::MUTEX lock_;
+ // ACE_Mutex_Token used to lock internal data structures.
+};
+
+// 12..
+class ACE_Export ACE_RW_Token : public ACE_Tokens
+ // = TITLE
+ // Not a public interface.
+ //
+ // = DESCRIPTION
+ // Class that acquires, renews, and releases a process-local
+ // synchronization token.
+ // This class is a more general-purpose synchronization mechanism
+ // than SunOS 5.x mutexes. For example, it implements "recursive
+ // mutex" semantics, where a thread that owns the token can
+ // reacquire it without deadlocking. In addition, threads that are
+ // blocked awaiting the token are serviced in strict FIFO order as
+ // other threads release the token (SunOS 5.x mutexes don't strictly
+ // enforce an acquisition order).
+{
+public:
+ ACE_RW_Token (const char* name);
+ // Life.
+
+ ~ACE_RW_Token (void);
+ // Death.
+
+ // = Synchronization operations.
+ // With acquire, renew, and release, the caller must be specified so
+ // that multiple proxies (e.g. ACE_Local_Mutex) can use the same
+ // token.
+
+ virtual int acquire (ACE_TPQ_Entry *caller,
+ int ignore_deadlock,
+ int notify);
+ // Returns 0 on success, -1 on failure with ACE_LOG_MSG->errnum() as
+ // the reason. If errnum == EWOULDBLOCK, and notify == 1,
+ // ACE_Token_Proxy::sleep_hook() has been called on the current owner
+ // of the token. If ignore_deadlock is passed as 1 and errnum ==
+ // EDEADLK, then deadlock was detected via ace_token_manager.
+
+ virtual int tryacquire (ACE_TPQ_Entry *caller);
+ // same as acquire except fails on would block
+
+ virtual int renew (ACE_TPQ_Entry *caller,
+ int requeue_position);
+ // An optimized method that efficiently reacquires the token if no
+ // other threads are waiting. This is useful for situations where
+ // you don't want to degrade the quality of service if there are
+ // other threads waiting to get the token. If <requeue_position> ==
+ // -1 and there are other threads waiting to obtain the token we are
+ // queued at the end of the list of waiters. If <requeue_position>
+ // > -1 then it indicates how many entries to skip over before
+ // inserting our thread into the list of waiters (e.g.,
+ // <requeue_position> == 0 means "insert at front of the queue").
+ // Renew has the rather odd semantics such that if there are other
+ // waiting threads it will give up the token even if the
+ // nesting_level_ > 1. I'm not sure if this is really the right
+ // thing to do (since it makes it possible for shared data to be
+ // changed unexpectedly) so use with caution...
+ // Returns 0 on success, -1 on failure with ACE_LOG_MSG->errnum() as
+ // the reason. If errnum == EWOULDBLOCK, and notify == 1,
+ // ACE_Token_Proxy::sleep_hook() has been called on the current owner
+ // of the token.
+
+ virtual int release (ACE_TPQ_Entry *caller);
+ // Relinquish the token. If there are any waiters then the next one
+ // in line gets it. If the caller is not the owner, caller is
+ // removed from the waiter list.
+
+ void dump (void) const;
+ // Dump the state of the class.
+
+ enum PROXY_TYPE { READER, WRITER };
+ // These are the types that proxies can be.
+
+ virtual int type (void) const;
+ // Returns READER or WRITER.
+
+ virtual int owners (OWNER_STACK &o, const char *id);
+ // Returns a stack of the current owners. Returns -1 on error, 0 on
+ // success. If <id> is non-zero, returns 1 if id is an owner.
+
+ virtual int is_waiting_for (const char *id);
+ // Returns 1 if <id> is waiting for this token. 0 otherwise.
+
+ virtual int is_owner (const char *id);
+ // Returns 1 if <id> is an owner of this token. 0 otherwise.
+
+protected:
+ int num_writers_;
+ // the number of waiting writers.
+
+ ACE_TOKEN_CONST::MUTEX lock_;
+ // ACE_Mutex_Token used to lock internal data structures.
+
+ void notify_new_owner (ACE_TPQ_Entry *caller);
+ // Sets the new owner.
+};
+
+// a..
+class ACE_Token_Name
+ // = TITLE
+ // Allows Token_Manger to identify tokens.
+ //
+ // = DESCRIPTION
+ // For now, this is just a string. We need a string class anyway
+ // to use in ACE_Map_Manager. Having this class (instead of
+ // SString) allows us to easily change if needed. For instance,
+ // we may choose to identify tokens by name and *type* in the
+ // future.
+{
+public:
+ ACE_Token_Name (const char *token_name = 0);
+ // Construction.
+
+ ACE_Token_Name (const ACE_Token_Name &rhs);
+ // Copy construction.
+
+ ~ACE_Token_Name (void);
+ // Death.
+
+ void operator= (const ACE_Token_Name &rhs);
+ // Copy.
+
+ int operator== (const ACE_Token_Name &rhs) const;
+ // Comparison.
+
+ const char *name (void) const;
+ // Token name.
+
+ void name (const char *new_name);
+ // Token name.
+
+ void dump (void) const;
+ // Dump the state of the class.
+
+private:
+ char token_name_[ACE_MAXTOKENNAMELEN];
+ // Name of the token.
+};
+
+
+// 7..
+class ACE_Export ACE_Token_Proxy
+ // = TITLE
+ // Abstract representation of ACE tokens.
+ //
+ // = DESCRIPTION
+ // Interface for all Tokens in ACE. This class implements the
+ // synchronization needed for tokens (condition variables etc.)
+ // The algorithms for the operations (acquire, release, etc.)
+ // operate on the generic ACE_Tokens interface. Thus, the _type_
+ // of token (mutex, rwlock) can be set at construction of
+ // ACE_Token_Proxy. You can use all Tokens in ACE through the
+ // ACE_Token_Proxy by passing the proper values at construction.
+ // Alternatively, there are class definitions which "know" how to
+ // do this (ACE_Local_Mutex, ACE_Local_RLock, ACE_Local_WLock).
+
+ // = EXTENDING TOKENS
+ // To add a new type of token (e.g. semaphore), this class is not
+ // changed. See ACE_Token_Manager for details.
+
+ // = RESTRICTIONS
+ // Tokens (e.g. ACE_Mutex_Token) assume that it can always call
+ // ACE_Token_Proxy::token_acquired () on a new token owner. This
+ // is not a problem for synchronous use of token proxies (that is,
+ // when acquires block until successful.) However, for
+ // implementations of the Token Server, which may use asynch
+ // operations, the proxy can not go away after an acquire until
+ // the token is acquired. This is not really a problem, but
+ // should be understood.
+{
+friend class ACE_Token_Manager;
+friend class ACE_Token_Invariant_Manager; // For testing.
+public:
+
+ // Initialization and termination methods.
+ ACE_Token_Proxy (void);
+ // Construction.
+
+ ~ACE_Token_Proxy (void);
+ // Death.
+
+ virtual int open (const char *name,
+ int ignore_deadlock = 0,
+ int debug = 0);
+ // <name> is the string uniquely identifying the token.
+ // <ignore_deadlock> can be 1 to disable deadlock notifications.
+ // <debug> prints debug messages.
+
+ // = The following methods have implementations which are
+ // independent of the token semantics (mutex, rwlock, etc.) They
+ // forward operations to the underlying token and perform the
+ // necessary blocking semantics for operations (condition variables
+ // etc.) This allows reuse of the blocking code as well as having
+ // multiple proxies to the same token.
+
+ virtual int acquire (int notify = 0,
+ void (*sleep_hook)(void *) = 0,
+ ACE_Synch_Options &options =
+ ACE_Synch_Options::defaults);
+ // Calls acquire on the token. Blocks the calling thread if would
+ // block.
+
+ virtual int renew (int requeue_position = -1,
+ ACE_Synch_Options &options =
+ ACE_Synch_Options::defaults);
+ // Calls renew on the token. Blocks the calling thread if would
+ // block.
+
+ virtual int tryacquire (void (*sleep_hook)(void *) = 0);
+ // Calls renew on the token.
+
+ virtual int release (ACE_Synch_Options &options =
+ ACE_Synch_Options::defaults);
+ // Calls release on the token.
+
+ virtual int remove (ACE_Synch_Options &options =
+ ACE_Synch_Options::defaults);
+ // Calls remove on the token.
+
+ // = Utility methods.
+
+ virtual const char *client_id (void) const;
+ // Get the client id of the proxy. This is implemented as
+ // thread-specific data.
+
+ virtual void client_id (const char *client_id);
+ // Set the client_id for the calling thread. I strongly recommend
+ // that this not be used unless you really know what you're doing.
+ // I use this in the Token Server, and it caused many headaches.
+
+ virtual const char *name (void) const;
+ // Return the name of the token. This is important for use within
+ // the token servers (local and remote) as well as with token
+ // collections. So, all derivations of ACE_Token_Proxy must be able to
+ // stringify some name. The name must uniquely identify a token.
+ // So, for instance, the token within the reactor should probably be
+ // called "Reactor Token."
+
+ virtual void sleep_hook (void);
+ // This should really be called someone_waiting ().
+ // This is called by ACE_Token_xx's when another proxy enters the
+ // waiting list and requests that the current token holder be notified.
+
+ virtual void token_acquired (ACE_TPQ_Entry *);
+ // This is called when a queued (waiting) proxy is removed from the
+ // waiters list and given the token.
+
+ virtual const char *owner_id (void);
+ // the client id of the current token holder
+
+ virtual ACE_Token_Proxy *clone (void) const = 0;
+ // Return a dynamically allocated clone of the derived class.
+
+ void dump (void) const;
+ // Dump the state of the class.
+
+ virtual int type (void) const;
+ // This method can be used be Tokens (e.g. Readers/Writer Tokens) to
+ // distinguish between Proxy types. For instance a Reader proxy
+ // should return a different type value than a Writer proxy. The
+ // default implementation returns 0.
+
+protected:
+ ACE_Token_Proxy (const ACE_Token_Proxy &);
+ // Duplication.
+
+ int ignore_deadlock_;
+ // If this is set, we ignore deadlock.
+
+ int debug_;
+ // Print a bunch of debug messages.
+
+ ACE_Tokens *token_;
+ // Reference to the actual logical token. Many ACE_Local_Mutex
+ // proxies can reference the same ACE_Mutex_Token.
+
+ int handle_options (ACE_Synch_Options &options,
+ ACE_TOKEN_CONST::COND_VAR &cv);
+ // Handles cond_var waits.
+
+ ACE_TSS_TPQ_Entry waiter_;
+ // Waiter info used for asynchronous transactions.
+
+ virtual ACE_Tokens *create_token (const char *name) = 0;
+ // Make the correct type of ACE_Tokens. This is called by the Token
+ // Manager.
+};
+
+// 8..
+class ACE_Export ACE_Null_Token : public ACE_Token_Proxy
+ // = TITLE
+ // No op class for nonthreaded platform protocols.
+{
+public:
+ ACE_Null_Token (void) {};
+ // Construction.
+
+ virtual int acquire (int /* notify */ = 0,
+ void (* /* sleep_hook */ )(void *) = 0,
+ ACE_Synch_Options & /* options */ =
+ ACE_Synch_Options::defaults) { return 0; }
+ // Acquire.
+
+ virtual int renew (int /* requeue_position */ = -1,
+ ACE_Synch_Options & /* options */ =
+ ACE_Synch_Options::defaults) { return 0; }
+ // Renew.
+
+ virtual int tryacquire (void (* /* sleep_hook */)(void *) = 0) { return 0; }
+ // Try acquire.
+
+ virtual int release (ACE_Synch_Options & /* options */ =
+ ACE_Synch_Options::defaults) { return 0; }
+ // Release.
+
+ virtual int remove (ACE_Synch_Options & /* options */ =
+ ACE_Synch_Options::defaults) { return 0; }
+ // Remove.
+
+ virtual ACE_Token_Proxy *clone (void) const { return new ACE_Null_Token; }
+ // Return a dynamically allocated clone of the derived class.
+
+ void dump (void) const;
+ // Dump the state of the class.
+
+ virtual ACE_Tokens *create_token (const char *) { return 0; }
+ // Do not allow the Token Manager to create us.
+};
+
+// 9..
+class ACE_Export ACE_Local_Mutex : public ACE_Token_Proxy
+ // = TITLE
+ // Class that acquires, renews, and releases a synchronization
+ // token local to the process.
+ //
+ // = DESCRIPTION
+ // This class is a more general-purpose synchronization mechanism
+ // than SunOS 5.x mutexes. For example, it implements "recursive
+ // mutex" semantics, where a thread that owns the token can
+ // reacquire it without deadlocking. In addition, threads that
+ // are blocked awaiting the token are serviced in strict FIFO
+ // order as other threads release the token (SunOS 5.x mutexes
+ // don't strictly enforce an acquisition order). Lastly,
+ // ACE_Local_Mutex performs deadlock detection on acquire calls.
+ //
+ // = Synchronization operations.
+ // The interfaces for acquire, tryacquire, renew, release,
+ // etc. are defined in ACE_Token_Proxy. The semantics for
+ // ACE_Local_Mutex are that of a mutex.
+{
+public:
+ ACE_Local_Mutex (const char *token_name = 0,
+ int ignore_deadlock = 0,
+ int debug = 0);
+ // <token_name> uniquely id's the token.
+ // <ignore_deadlock> will allow deadlock to occur (useful for
+ // testing). <debug> prints a bunch of messages.
+
+ void dump (void) const;
+ // Dump the state of the class.
+
+ virtual ACE_Token_Proxy *clone (void) const;
+ // Return deep copy.
+
+protected:
+ virtual ACE_Tokens *create_token (const char *name);
+ // Return a new ACE_Local_Mutex.
+};
+
+// *.
+class ACE_Export ACE_Local_RLock : public ACE_Token_Proxy
+// = TITLE
+// Class that acquires, renews, and releases a readers lock that
+// is local to the process.
+//
+// = DESCRIPTION
+// This class implements the reader interface to canonical
+// readers/writer locks. Multiple readers can hold the lock
+// simultaneously when no writers have the lock. Alternatively,
+// when a writer holds the lock, no other participants (readers or
+// writers) may hold the lock. This class is a more
+// general-purpose synchronization mechanism than SunOS 5.x RLocks.
+// For example, it implements "recursive RLock" semantics, where a
+// thread that owns the token can reacquire it without deadlocking.
+// In addition, threads that are blocked awaiting the token are
+// serviced in strict FIFO order as other threads release the token
+// (SunOS 5.x RLockes don't strictly enforce an acquisition
+// order).
+//
+// = Synchronization operations.
+// The interfaces for acquire, tryacquire, renew, release, etc. are
+// defined in ACE_Token_Proxy. The semantics for ACE_Local_RLock
+// are that of a readers/writers lock. Acquire for this class
+// implies a reader acquisition. That is, multiple clients may
+// acquire a lock for read only.
+{
+public:
+ // = Initialization and termination.
+
+ ACE_Local_RLock (const char *token_name = 0,
+ int ignore_deadlock = 0,
+ int debug = 0);
+ // <token_name> uniquely id's the token.
+ // <ignore_deadlock> will allow deadlock to occur (useful for
+ // testing). <debug> prints a bunch of messages.
+
+ void dump (void) const;
+ // Dump the state of the class.
+
+ virtual int type (void) const;
+ // Returns ACE_RW_Token::RLOCK.
+
+ virtual ACE_Token_Proxy *clone (void) const;
+ // Return deep copy.
+
+protected:
+ virtual ACE_Tokens *create_token (const char *name);
+ // Return a new ACE_Local_Mutex.
+};
+
+// *.
+class ACE_Export ACE_Local_WLock : public ACE_Token_Proxy
+// = TITLE
+// Class that acquires, renews, and releases a writer lock that
+// is local to the process.
+//
+// = DESCRIPTION
+// This class implements the writer interface to canonical
+// readers/writer locks. Multiple readers can hold the lock
+// simultaneously when no writers have the lock. Alternatively,
+// when a writer holds the lock, no other participants (readers or
+// writers) may hold the lock. This class is a more
+// general-purpose synchronization mechanism than SunOS 5.x WLock.
+// For example, it implements "recursive WLock" semantics, where a
+// thread that owns the token can reacquire it without deadlocking.
+// In addition, threads that are blocked awaiting the token are
+// serviced in strict FIFO order as other threads release the token
+// (SunOS 5.x WLocks don't strictly enforce an acquisition order).
+//
+// = Synchronization operations.
+// The interfaces for acquire, tryacquire, renew, release,
+// etc. are defined in ACE_Token_Proxy. The semantics for
+// ACE_Local_WLock are that of a readers/writers lock. Acquire
+// for this class implies a writer acquisition. That is, only one
+// client may hold the lock for writing.
+{
+public:
+ // = Initialization and termination.
+
+ ACE_Local_WLock (const char *token_name = 0,
+ int ignore_deadlock = 0,
+ int debug = 0);
+ // <token_name> uniquely id's the token.
+ // <ignore_deadlock> will allow deadlock to occur (useful for
+ // testing). <debug> prints a bunch of messages.
+
+ void dump (void) const;
+ // Dump the state of the class.
+
+ virtual int type (void) const;
+ // Returns ACE_RW_Token::WLOCK.
+
+ virtual ACE_Token_Proxy *clone (void) const;
+ // Return deep copy.
+
+protected:
+ ACE_Tokens *create_token (const char *name);
+ // Return a new ACE_Local_Mutex.
+};
+
+#if defined (__ACE_INLINE__)
+#include "ace/Local_Tokens.i"
+#endif /* __ACE_INLINE__ */
+#endif /* ACE_LOCAL_MUTEX_H */