#include <ace/Token.h>
class ACE_Token {
public:
ACE_Token (LPCTSTR name = 0, void * = 0);
virtual ~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 acquire_read (void);
int acquire_write (void);
int tryacquire_read (void);
int tryacquire_write (void);
int waiters (void);
ACE_thread_t current_owner (void);
void dump (void) const;
ACE_ALLOC_HOOK_DECLARE;
inline int acquire (ACE_Time_Value * = 0);
inline int tryacquire (void);
inline int remove (void);
inline int release (void);
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_;
};
ACE_Token (LPCTSTR name = 0, void * = 0);
virtual ~ACE_Token (void);
int acquire (void (*sleep_hook)(
void *),
void *arg = 0,
ACE_Time_Value *timeout = 0
);
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);
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);
acquire
goes to sleep.
By default, this is a no-op...
int renew (int requeue_position = 0, ACE_Time_Value *timeout = 0);
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);
acquire
).
int remove (void);
int release (void);
int acquire_read (void);
acquire
.
int acquire_write (void);
acquire
.
int tryacquire_read (void);
tryacquire
.
int tryacquire_write (void);
tryacquire
.
int waiters (void);
ACE_thread_t current_owner (void);
void dump (void) const;
ACE_ALLOC_HOOK_DECLARE;
int shared_acquire (void (*sleep_hook_func)(
void *),
void *arg,
ACE_Time_Value *timeout
);
acquire
and tryacquire
methods above.
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_;
owner_
) is using the token. We need this
extra variable to deal with POSIX pthreads madness...
int waiters_;
int nesting_level_;