summaryrefslogtreecommitdiff
path: root/ace/Token.h
diff options
context:
space:
mode:
Diffstat (limited to 'ace/Token.h')
-rw-r--r--ace/Token.h242
1 files changed, 126 insertions, 116 deletions
diff --git a/ace/Token.h b/ace/Token.h
index 06e286d3a67..54835a1ef1f 100644
--- a/ace/Token.h
+++ b/ace/Token.h
@@ -1,19 +1,18 @@
/* -*- C++ -*- */
-// $Id$
-
-// ============================================================================
-//
-// = LIBRARY
-// ace
-//
-// = FILENAME
-// Token.h
-//
-// = AUTHOR
-// Original author -- Karl-Heinz Dorn (kdorn@erlh.siemens.de)
-// Ported to ACE by Douglas C. Schmidt (schmidt@cs.wustl.edu)
-//
-// ============================================================================
+
+//=============================================================================
+/**
+ * @file Token.h
+ *
+ * $Id$
+ *
+ * @author Original author
+ * @author Karl-Heinz Dorn (kdorn@erlh.siemens.de)
+ * @author Ported to ACE by
+ * @author Douglas C. Schmidt (schmidt@cs.wustl.edu)
+ */
+//=============================================================================
+
#ifndef ACE_TOKEN_H
#define ACE_TOKEN_H
@@ -32,36 +31,37 @@
# define ACE_TOKEN_USES_SEMAPHORE
#endif /* (ACE_WIN32 && !ACE_HAS_WINCE) || VXWORKS || ACE_PSOS */
+/**
+ * @class ACE_Token
+ *
+ * @brief Class that acquires, renews, and releases a synchronization
+ * token that is serviced in strict FIFO ordering and that also
+ * supports (1) recursion and (2) readers/writer semantics.
+ *
+ * This class is a more general-purpose synchronization mechanism
+ * than many native OS mutexes. For example, it implements
+ * "recursive mutex" semantics, where a thread that owns the token
+ * can reacquire it without deadlocking. If the same thread calls
+ * <acquire> multiple times, however, it must call <release> an
+ * equal number of times before the token is actually released.
+ * Threads that are blocked awaiting the token are serviced in
+ * strict FIFO order as other threads release the token (Solaris
+ * and Pthread mutexes don't strictly enforce an acquisition
+ * order). There are two FIFO lists within the class. Write
+ * acquires always have higher priority over read acquires. Which
+ * means, if you use both write/read operations, care must be
+ * taken to avoid starvation on the readers. Notice that the
+ * read/write acquire operations do not have the usual semantic of
+ * reader/writer locks. Only one reader can acquire the token at
+ * a time (which is different from the usual reader/writer locks
+ * where several readers can acquire a lock at the same time as
+ * long as there is no writer waiting for the lock). We choose
+ * the names to (1) borrow the semantic to give writers higher
+ * priority and (2) support a common interface for all locking
+ * classes in ACE.
+ */
class ACE_Export ACE_Token
{
- // = TITLE
- // Class that acquires, renews, and releases a synchronization
- // token that is serviced in strict FIFO ordering and that also
- // supports (1) recursion and (2) readers/writer semantics.
- //
- // = DESCRIPTION
- // This class is a more general-purpose synchronization mechanism
- // than many native OS mutexes. For example, it implements
- // "recursive mutex" semantics, where a thread that owns the token
- // can reacquire it without deadlocking. If the same thread calls
- // <acquire> multiple times, however, it must call <release> an
- // equal number of times before the token is actually released.
- //
- // Threads that are blocked awaiting the token are serviced in
- // strict FIFO order as other threads release the token (Solaris
- // and Pthread mutexes don't strictly enforce an acquisition
- // order). There are two FIFO lists within the class. Write
- // acquires always have higher priority over read acquires. Which
- // means, if you use both write/read operations, care must be
- // taken to avoid starvation on the readers. Notice that the
- // read/write acquire operations do not have the usual semantic of
- // reader/writer locks. Only one reader can acquire the token at
- // a time (which is different from the usual reader/writer locks
- // where several readers can acquire a lock at the same time as
- // long as there is no writer waiting for the lock). We choose
- // the names to (1) borrow the semantic to give writers higher
- // priority and (2) support a common interface for all locking
- // classes in ACE.
public:
// = Initialization and termination.
@@ -70,113 +70,123 @@ public:
// = Synchronization operations.
+ /**
+ * Acquire the token, sleeping until it is obtained or until the
+ * expiration of <timeout>, which is treated as "absolute" time. If
+ * some other thread currently holds the token then <sleep_hook> is
+ * called before our thread goes to sleep. This <sleep_hook> can be
+ * used by the requesting thread to unblock a token-holder that is
+ * sleeping, e.g., by means of writing to a pipe (the ACE
+ * ACE_Reactor uses this functionality). Return values: 0 if
+ * acquires without calling <sleep_hook> 1 if <sleep_hook> is
+ * called. 2 if the token is signaled. -1 if failure or timeout
+ * occurs (if timeout occurs errno == ETIME) If <timeout> ==
+ * <&ACE_Time_Value::zero> then acquire has polling semantics (and
+ * does *not* call <sleep_hook>).
+ */
int acquire (void (*sleep_hook)(void *),
void *arg = 0,
ACE_Time_Value *timeout = 0);
- // Acquire the token, sleeping until it is obtained or until the
- // expiration of <timeout>, which is treated as "absolute" time. If
- // some other thread currently holds the token then <sleep_hook> is
- // called before our thread goes to sleep. This <sleep_hook> can be
- // used by the requesting thread to unblock a token-holder that is
- // sleeping, e.g., by means of writing to a pipe (the ACE
- // ACE_Reactor uses this functionality). Return values: 0 if
- // acquires without calling <sleep_hook> 1 if <sleep_hook> is
- // called. 2 if the token is signaled. -1 if failure or timeout
- // occurs (if timeout occurs errno == ETIME) If <timeout> ==
- // <&ACE_Time_Value::zero> then acquire has polling semantics (and
- // does *not* call <sleep_hook>).
+ /**
+ * This behaves just like the previous <acquire> method, except that
+ * it invokes the virtual function called <sleep_hook> that can be
+ * overridden by a subclass of ACE_Token.
+ */
int acquire (ACE_Time_Value *timeout = 0);
- // This behaves just like the previous <acquire> method, except that
- // it invokes the virtual function called <sleep_hook> that can be
- // overridden by a subclass of ACE_Token.
+ /**
+ * This should be overridden by a subclass to define the appropriate
+ * behavior before <acquire> goes to sleep. By default, this is a
+ * no-op...
+ */
virtual void sleep_hook (void);
- // This should be overridden by a subclass to define the appropriate
- // behavior before <acquire> goes to sleep. By default, this is a
- // no-op...
+ /**
+ * 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 degrad 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... This method
+ * maintians the original token priority. As in <acquire>, the
+ * <timeout> value is an absolute time.
+ */
int renew (int requeue_position = 0,
ACE_Time_Value *timeout = 0);
- // 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 degrad 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... This method
- // maintians the original token priority. As in <acquire>, the
- // <timeout> value is an absolute time.
+ /// Become interface-compliant with other lock mechanisms (implements
+ /// a non-blocking <acquire>).
int tryacquire (void);
- // Become interface-compliant with other lock mechanisms (implements
- // a non-blocking <acquire>).
+ /// Shuts down the ACE_Token instance.
int remove (void);
- // Shuts down the ACE_Token instance.
+ /// Relinquish the token. If there are any waiters then the next one
+ /// in line gets it.
int release (void);
- // Relinquish the token. If there are any waiters then the next one
- // in line gets it.
+ /// Behave like acquire but in a lower priority. It should probably
+ /// be called acquire_yield.
int acquire_read (void);
- // Behave like acquire but in a lower priority. It should probably
- // be called acquire_yield.
+ /// More sophisticate version of acquire_read.
int acquire_read (void (*sleep_hook)(void *),
void *arg = 0,
ACE_Time_Value *timeout = 0);
- // More sophisticate version of acquire_read.
+ /// Just calls <acquire>.
int acquire_write (void);
- // Just calls <acquire>.
+ /// More sophisticate version of acquire_write.
int acquire_write (void (*sleep_hook)(void *),
void *arg = 0,
ACE_Time_Value *timeout = 0);
- // More sophisticate version of acquire_write.
+ /// Lower priority try_acquire.
int tryacquire_read (void);
- // Lower priority try_acquire.
+ /// Just calls <tryacquire>.
int tryacquire_write (void);
- // Just calls <tryacquire>.
+ /// Assumes the caller has acquired the token and returns 0.
int tryacquire_write_upgrade (void);
- // Assumes the caller has acquired the token and returns 0.
// = Accessor methods.
+ /// Return the number of threads that are currently waiting to get
+ /// the token.
int waiters (void);
- // Return the number of threads that are currently waiting to get
- // the token.
+ /// Return the id of the current thread that owns the token.
ACE_thread_t current_owner (void);
- // Return the id of the current thread that owns the token.
+ /**
+ * Force all threads waiting to acquire the token to return one by
+ * one. The method sets the <signal_all_thread_> to non-zero if
+ * there're threads waiting, and returns the number of threads
+ * waiting. If there's no thread waiting for the token, the call
+ * returns 0 and doesn't do anything. The last thread releases the
+ * token also reset the <singal_all_thread_> flag to 0. This means,
+ * any threads that try to acquire the token after the call is
+ * issued will also get "signaled" and the number of threads waiting
+ * the token is only a snapshot.
+ */
int signal_all_threads (void);
- // Force all threads waiting to acquire the token to return one by
- // one. The method sets the <signal_all_thread_> to non-zero if
- // there're threads waiting, and returns the number of threads
- // waiting. If there's no thread waiting for the token, the call
- // returns 0 and doesn't do anything. The last thread releases the
- // token also reset the <singal_all_thread_> flag to 0. This means,
- // any threads that try to acquire the token after the call is
- // issued will also get "signaled" and the number of threads waiting
- // the token is only a snapshot.
+ /// Dump the state of an object.
void dump (void) const;
- // Dump the state of an object.
+ /// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
- // Declare the dynamic allocation hooks.
// = The following structure implements a ACE_FIFO of waiter threads
// that are asleep waiting to obtain the token.
@@ -241,42 +251,42 @@ private:
// Tail of the list of waiting threads.
};
+ /// Implements the <acquire> and <tryacquire> methods above.
int shared_acquire (void (*sleep_hook_func)(void *),
void *arg,
ACE_Time_Value *timeout,
ACE_Token_Op_Type op_type);
- // Implements the <acquire> and <tryacquire> methods above.
+ /// Wake next in line for ownership.
void wakeup_next_waiter (void);
- // Wake next in line for ownership.
+ /// A queue of writer threads.
ACE_Token_Queue writers_;
- // A queue of writer threads.
+ /// A queue of reader threads.
ACE_Token_Queue readers_;
- // A queue of reader threads.
+ /// ACE_Thread_Mutex used to lock internal data structures.
ACE_Thread_Mutex lock_;
- // ACE_Thread_Mutex used to lock internal data structures.
+ /// Current owner of the token.
ACE_thread_t owner_;
- // Current owner of the token.
+ /// Some thread (i.e., <owner_>) is using the token. We need this
+ /// extra variable to deal with POSIX pthreads madness...
int in_use_;
- // Some thread (i.e., <owner_>) is using the token. We need this
- // extra variable to deal with POSIX pthreads madness...
+ /// Number of waiters.
int waiters_;
- // Number of waiters.
+ /// Current nesting level.
int nesting_level_;
- // Current nesting level.
+ /// Whether we are "signaling" all threads or not.
int signal_all_threads_;
- // Whether we are "signaling" all threads or not.
+ /// The attributes for the condition variables, optimizes lock time.
ACE_Condition_Attributes attributes_;
- // The attributes for the condition variables, optimizes lock time.
};
#if defined (__ACE_INLINE__)