NAME
ACE_Token -
Class that acquires, renews, and releases a synchronization
token that is local to the process.
SYNOPSIS
#include <ace/Token.h>
class ACE_Token
{
public:
ACE_Token (const char *name = 0, void * = 0);
~ACE_Token (void);
int acquire (void (*sleep_hook)(
void *),
void *arg = 0,
ACE_Time_Value *timeout = 0
);
int acquire (ACE_Time_Value *timeout = 0);
virtual void sleep_hook (void);
int renew (int requeue_position = 0, ACE_Time_Value *timeout = 0);
int tryacquire (void);
int remove (void);
int release (void);
int waiters (void);
ACE_thread_t current_owner (void);
void dump (void) const;
ACE_ALLOC_HOOK_DECLARE;
private:
int shared_acquire (void (*sleep_hook_func)(
void *),
void *arg,
ACE_Time_Value *timeout
);
void remove_entry (ACE_Queue_Entry *);
ACE_Queue_Entry *head_;
ACE_Queue_Entry *tail_;
ACE_Thread_Mutex lock_;
ACE_thread_t owner_;
int in_use_;
int waiters_;
int nesting_level_;
};
Initialization and termination.
ACE_Token (const char *name = 0, void * = 0);
~ACE_Token (void);
Synchronization operations.
int acquire (void (*sleep_hook)(
void *),
void *arg = 0,
ACE_Time_Value *timeout = 0
);
Acquire the token, sleeping until it is obtained or until
timeout expires. 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.
-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 (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.
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...
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...
int tryacquire (void);
Become interface-compliant with other lock mechanisms (implements
a non-blocking acquire).
int remove (void);
Shuts down the ACE_Token instance.
int release (void);
Relinquish the token. If there are any waiters then the next one
in line gets it.
Accessor methods.
int waiters (void);
Return the number of threads that are currently waiting to get
the token.
ACE_thread_t current_owner (void);
Return the id of the current thread that owns the token.
void dump (void) const;
Dump the state of an object.
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.
int shared_acquire (void (*sleep_hook_func)(
void *),
void *arg,
ACE_Time_Value *timeout
);
Implements the acquire and tryacquire methods above.
void remove_entry (ACE_Queue_Entry *);
Remove a waiter from the queue (used when a timeout occurs).
ACE_Queue_Entry *head_;
Head of the list of waiting threads.
ACE_Queue_Entry *tail_;
Tail of the list of waiting threads.
ACE_Thread_Mutex lock_;
ACE_Thread_Mutex used to lock internal data structures.
ACE_thread_t owner_;
Current owner of the token.
int in_use_;
Some thread (i.e., owner_) is using the token. We need this
extra variable to deal with POSIX pthreads madness...
int waiters_;
int nesting_level_;
AUTHOR
Original author -- Karl-Heinz Dorn (kdorn@erlh.siemens.de)
Ported to ACE by Douglas C. Schmidt (schmidt@cs.wustl.edu)
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).
LIBRARY
ace