[7297] Fixed profession spells sorting in trainer spell list at client.
[getmangos.git] / dep / ACE_wrappers / ace / Token.h
blobf46726aa66c6b96af00774f2c6c1e9e99159d0c0
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file Token.h
7 * $Id: Token.h 80826 2008-03-04 14:51:23Z wotte $
9 * @author Original author
10 * @author Karl-Heinz Dorn (kdorn@erlh.siemens.de)
11 * @author Ported to ACE by
12 * @author Douglas C. Schmidt (schmidt@cs.wustl.edu)
14 //=============================================================================
16 #ifndef ACE_TOKEN_H
17 #define ACE_TOKEN_H
18 #include /**/ "ace/pre.h"
20 #include /**/ "ace/ACE_export.h"
22 #if !defined (ACE_LACKS_PRAGMA_ONCE)
23 # pragma once
24 #endif /* ACE_LACKS_PRAGMA_ONCE */
26 #include "ace/Null_Mutex.h"
28 #if defined (ACE_HAS_THREADS)
30 #include "ace/Thread_Mutex.h"
32 #if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || defined (ACE_HAS_VXTHREADS)
33 // If platforms support semaphores with timed wait, then we use semaphores instead of c.v.
34 # define ACE_TOKEN_USES_SEMAPHORE
35 #endif /* (ACE_WIN32 && !ACE_HAS_WINCE) || VXWORKS */
37 #if defined (ACE_TOKEN_USES_SEMAPHORE)
38 # include "ace/Semaphore.h"
39 #endif /* ACE_TOKEN_USES_SEMAPHORE */
41 #include "ace/Condition_Thread_Mutex.h"
43 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
45 class ACE_Time_Value;
47 /**
48 * @class ACE_Token
50 * @brief Class that acquires, renews, and releases a synchronization
51 * token that is serviced in strict FIFO/LIFO ordering and that also
52 * supports (1) recursion and (2) readers/writer semantics.
54 * This class is a more general-purpose synchronization mechanism
55 * than many native OS mutexes. For example, it implements
56 * "recursive mutex" semantics, where a thread that owns the token
57 * can reacquire it without deadlocking. If the same thread calls
58 * <acquire> multiple times, however, it must call <release> an
59 * equal number of times before the token is actually released.
60 * Threads that are blocked awaiting the token are serviced in
61 * strict FIFO/LIFO order as other threads release the token (Solaris
62 * and Pthread mutexes don't strictly enforce an acquisition
63 * order). There are two lists within the class. Write
64 * acquires always have higher priority over read acquires. Which
65 * means, if you use both write/read operations, care must be
66 * taken to avoid starvation on the readers. Notice that the
67 * read/write acquire operations do not have the usual semantic of
68 * reader/writer locks. Only one reader can acquire the token at
69 * a time (which is different from the usual reader/writer locks
70 * where several readers can acquire a lock at the same time as
71 * long as there is no writer waiting for the lock). We choose
72 * the names to (1) borrow the semantic to give writers higher
73 * priority and (2) support a common interface for all locking
74 * classes in ACE.
76 class ACE_Export ACE_Token
78 public:
80 /**
81 * Available queueing strategies.
83 enum QUEUEING_STRATEGY
85 /// FIFO, First In, First Out.
86 FIFO = -1,
87 /// LIFO, Last In, First Out
88 LIFO = 0
91 // = Initialization and termination.
93 /// Constructor
94 ACE_Token (const ACE_TCHAR *name = 0, void * = 0);
96 /// Destructor
97 virtual ~ACE_Token (void);
99 // = Strategies
101 /// Retrieve the current queueing strategy.
102 int queueing_strategy (void);
104 /// Set the queueing strategy.
105 void queueing_strategy (int queueing_strategy);
107 // = Synchronization operations.
110 * Acquire the token, sleeping until it is obtained or until the
111 * expiration of @a timeout, which is treated as "absolute" time. If
112 * some other thread currently holds the token then <sleep_hook> is
113 * called before our thread goes to sleep. This <sleep_hook> can be
114 * used by the requesting thread to unblock a token-holder that is
115 * sleeping, e.g., by means of writing to a pipe (the ACE
116 * ACE_Reactor uses this functionality). Return values: 0 if
117 * acquires without calling <sleep_hook> 1 if <sleep_hook> is
118 * called. 2 if the token is signaled. -1 if failure or timeout
119 * occurs (if timeout occurs errno == ETIME) If @a timeout ==
120 * <&ACE_Time_Value::zero> then acquire has polling semantics (and
121 * does *not* call <sleep_hook>).
123 int acquire (void (*sleep_hook)(void *),
124 void *arg = 0,
125 ACE_Time_Value *timeout = 0);
128 * This behaves just like the previous <acquire> method, except that
129 * it invokes the virtual function called <sleep_hook> that can be
130 * overridden by a subclass of ACE_Token.
132 int acquire (ACE_Time_Value *timeout = 0);
135 * This should be overridden by a subclass to define the appropriate
136 * behavior before <acquire> goes to sleep. By default, this is a
137 * no-op...
139 virtual void sleep_hook (void);
142 * An optimized method that efficiently reacquires the token if no
143 * other threads are waiting. This is useful for situations where
144 * you don't want to degrade the quality of service if there are
145 * other threads waiting to get the token. If <requeue_position> ==
146 * -1 and there are other threads waiting to obtain the token we are
147 * queued according to the queueing strategy. If <requeue_position>
148 * > -1 then it indicates how many entries to skip over before
149 * inserting our thread into the list of waiters (e.g.,
150 * <requeue_position> == 0 means "insert at front of the queue").
151 * Renew has the rather odd semantics such that if there are other
152 * waiting threads it will give up the token even if the
153 * nesting_level_ > 1. I'm not sure if this is really the right
154 * thing to do (since it makes it possible for shared data to be
155 * changed unexpectedly) so use with caution... This method
156 * maintians the original token priority. As in <acquire>, the
157 * @a timeout value is an absolute time.
159 int renew (int requeue_position = 0,
160 ACE_Time_Value *timeout = 0);
162 /// Become interface-compliant with other lock mechanisms (implements
163 /// a non-blocking <acquire>).
164 int tryacquire (void);
166 /// Shuts down the ACE_Token instance.
167 int remove (void);
169 /// Relinquish the token. If there are any waiters then the next one
170 /// in line gets it.
171 int release (void);
173 /// Behaves like acquire() but at a lower priority. It should probably
174 /// be called acquire_yield() since the semantics aren't really
175 /// what's commonly expected for readers/writer locks. See the class
176 /// documentation above for more details.
177 int acquire_read (void);
179 /// Behaves like acquire() but at a lower priority. It should probably
180 /// be called acquire_yield() since the semantics aren't really
181 /// what's commonly expected for readers/writer locks. See the class
182 /// documentation above for more details.
183 int acquire_read (void (*sleep_hook)(void *),
184 void *arg = 0,
185 ACE_Time_Value *timeout = 0);
187 /// Calls acquire().
188 int acquire_write (void);
190 /// Calls acquire().
191 int acquire_write (void (*sleep_hook)(void *),
192 void *arg = 0,
193 ACE_Time_Value *timeout = 0);
195 /// Lower priority try_acquire().
196 int tryacquire_read (void);
198 /// Just calls <tryacquire>.
199 int tryacquire_write (void);
201 /// Assumes the caller has acquired the token and returns 0.
202 int tryacquire_write_upgrade (void);
204 // = Accessor methods.
206 /// Return the number of threads that are currently waiting to get
207 /// the token.
208 int waiters (void);
210 /// Return the id of the current thread that owns the token.
211 ACE_thread_t current_owner (void);
213 /// Dump the state of an object.
214 void dump (void) const;
216 /// Declare the dynamic allocation hooks.
217 ACE_ALLOC_HOOK_DECLARE;
219 /// The following structure implements a LIFO/FIFO queue of waiter threads
220 /// that are asleep waiting to obtain the token.
221 struct ACE_Token_Queue_Entry
223 /// Constructor
224 ACE_Token_Queue_Entry (ACE_Thread_Mutex &m,
225 ACE_thread_t t_id);
227 /// Constructor using a pre-allocated attributes
228 ACE_Token_Queue_Entry (ACE_Thread_Mutex &m,
229 ACE_thread_t t_id,
230 ACE_Condition_Attributes &attributes);
232 /// Entry blocks on the token.
233 int wait (ACE_Time_Value *timeout, ACE_Thread_Mutex &lock);
235 /// Notify (unblock) the entry.
236 int signal (void);
238 /// Pointer to next waiter.
239 ACE_Token_Queue_Entry *next_;
241 /// ACE_Thread id of this waiter.
242 ACE_thread_t thread_id_;
244 #if defined (ACE_TOKEN_USES_SEMAPHORE)
245 /// ACE_Semaphore object used to wake up waiter when it can run again.
246 ACE_Semaphore cv_;
247 #else
248 /// ACE_Condition object used to wake up waiter when it can run again.
249 ACE_Condition_Thread_Mutex cv_;
250 #endif /* ACE_TOKEN_USES_SEMAPHORE */
252 /// Ok to run.
253 int runable_;
256 private:
257 enum ACE_Token_Op_Type
259 READ_TOKEN = 1,
260 WRITE_TOKEN
263 struct ACE_Token_Queue
265 /// Constructor
266 ACE_Token_Queue (void);
268 /// Remove a waiter from the queue.
269 void remove_entry (ACE_Token_Queue_Entry *);
271 /// Insert a waiter into the queue.
272 void insert_entry (ACE_Token_Queue_Entry &entry,
273 int requeue_position = -1);
275 /// Head of the list of waiting threads.
276 ACE_Token_Queue_Entry *head_;
278 /// Tail of the list of waiting threads.
279 ACE_Token_Queue_Entry *tail_;
282 /// Implements the <acquire> and <tryacquire> methods above.
283 int shared_acquire (void (*sleep_hook_func)(void *),
284 void *arg,
285 ACE_Time_Value *timeout,
286 ACE_Token_Op_Type op_type);
288 /// Wake next in line for ownership.
289 void wakeup_next_waiter (void);
291 /// A queue of writer threads.
292 ACE_Token_Queue writers_;
294 /// A queue of reader threads.
295 ACE_Token_Queue readers_;
297 /// ACE_Thread_Mutex used to lock internal data structures.
298 ACE_Thread_Mutex lock_;
300 /// Current owner of the token.
301 ACE_thread_t owner_;
303 /// Some thread (i.e., <owner_>) is using the token. We need this
304 /// extra variable to deal with POSIX pthreads madness...
305 int in_use_;
307 /// Number of waiters.
308 int waiters_;
310 /// Current nesting level.
311 int nesting_level_;
313 /// The attributes for the condition variables, optimizes lock time.
314 ACE_Condition_Attributes attributes_;
316 /// Queueing strategy, LIFO/FIFO.
317 int queueing_strategy_;
320 ACE_END_VERSIONED_NAMESPACE_DECL
322 #else
324 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
326 class ACE_Export ACE_Token
328 public:
329 int queueing_strategy (void) { ACE_NOTSUP_RETURN (-1); }
330 void queueing_strategy (int /*queueing_strategy*/) { }
331 int acquire (ACE_Time_Value * = 0) { ACE_NOTSUP_RETURN (-1); }
332 int tryacquire (void) { ACE_NOTSUP_RETURN (-1); }
333 int remove (void) { ACE_NOTSUP_RETURN (-1); }
334 int release (void) { ACE_NOTSUP_RETURN (-1); }
337 ACE_END_VERSIONED_NAMESPACE_DECL
339 #endif /* ACE_HAS_THREADS */
341 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
343 class ACE_Export ACE_Noop_Token : public ACE_Null_Mutex
345 public:
346 /// Queueing strategy
347 enum QUEUEING_STRATEGY
349 FIFO = -1,
350 LIFO = 0
353 /// Get queueing strategy.
354 int queueing_strategy (void);
356 /// Set queueing strategy.
357 void queueing_strategy (int queueing_strategy);
359 int renew (int = 0, ACE_Time_Value * =0);
361 /// Dump the state of an object.
362 void dump (void) const;
364 /// Declare the dynamic allocation hooks.
365 ACE_ALLOC_HOOK_DECLARE;
368 ACE_END_VERSIONED_NAMESPACE_DECL
370 #if defined (__ACE_INLINE__)
371 #include "ace/Token.inl"
372 #endif /* __ACE_INLINE__ */
375 #include /**/ "ace/post.h"
376 #endif /* ACE_TOKEN_H */