[7297] Fixed profession spells sorting in trainer spell list at client.
[getmangos.git] / dep / ACE_wrappers / ace / Local_Tokens.h
blob373e846719eae767d5cd0015f19fa67736fa9d46
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file Local_Tokens.h
7 * $Id: Local_Tokens.h 80826 2008-03-04 14:51:23Z wotte $
9 * @author Karl-Heinz Dorn <kdorn@erlh.siemens.de>
10 * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
11 * @author Tim Harrison <harrison@cs.wustl.edu>
13 * This file contains definitions for the following classes:
15 * public:
16 * 7. ACE_Token_Proxy
17 * 8. ACE_Null_Token : public ACE_Token_Proxy
18 * 9. ACE_Local_Mutex : public ACE_Token_Proxy
19 * *. ACE_Local_RLock : public ACE_Local_Mutex
20 * &. ACE_Local_WLock : public ACE_Local_Mutex
21 * private:
22 * 1. ACE_TOKEN_CONST
23 * 3. ACE_TPQ_Entry
24 * b. ACE_TSS_TPQ_Entry
25 * c. ACE_TPQ_Iterator
26 * 4. ACE_Token_Proxy_Queue
27 * 5. ACE_Tokens
28 * 6. ACE_Mutex_Token : public ACE_Tokens
29 * 12. ACE_RW_Token : public ACE_Tokens
30 * a. ACE_Token_Name
32 * Note that the locking classes defined in this file are *not*
33 * intended to be used as general-purpose synchronization
34 * mechanisms, such as mutexes or semaphores. Instead, you should
35 * use the ACE_Recursive_Thread_Mutex, ACE_Thread_Mutex,
36 * ACE_Thread_Semaphore, etc., that are defined in
37 * $ACE_ROOT/ace/Synch.h and $ACE_ROOT/ace/Synch_T.h or the
38 * ACE_Token that's defined in $ACE_ROOT/ace/Token.h.
42 //=============================================================================
44 #ifndef ACE_LOCAL_MUTEX_H
45 #define ACE_LOCAL_MUTEX_H
46 #include /**/ "ace/pre.h"
48 #include /**/ "ace/config-all.h"
50 #if !defined (ACE_LACKS_PRAGMA_ONCE)
51 # pragma once
52 #endif /* ACE_LACKS_PRAGMA_ONCE */
54 #if defined (ACE_HAS_TOKENS_LIBRARY)
56 #include "ace/Synch_Traits.h"
57 #include "ace/Condition_Thread_Mutex.h"
58 #include "ace/TSS_T.h"
59 #include "ace/Containers.h"
60 #include "ace/Synch_Options.h"
61 #include "ace/Map_Manager.h"
62 #include "ace/Log_Msg.h"
63 #include "ace/OS_NS_string.h"
64 #include "ace/os_include/os_netdb.h"
66 #if !(defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE))
67 # define ACE_NO_TSS_TOKENS 1
68 #endif /* !(defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)) */
70 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
72 // 1.
73 /**
74 * @class ACE_TOKEN_CONST
76 * @brief Not a public interface.
78 * Constant definitions and typedefs for Token library. Mostly,
79 * this class is necessary to fight the compiler with order of
80 * declaration errors.
82 namespace ACE_TOKEN_CONST
84 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
85 // ACE platform supports some form of threading.
86 typedef ACE_Condition_Thread_Mutex COND_VAR;
87 typedef ACE_Thread_Mutex MUTEX;
88 typedef ACE_Guard<ACE_Thread_Mutex> GUARD;
89 #else
90 typedef ACE_Null_Condition COND_VAR;
91 typedef ACE_Null_Mutex MUTEX;
92 typedef ACE_Guard<ACE_Null_Mutex> GUARD;
93 #endif /* ACE_HAS_THREADS */
96 // Forward decl.
97 class ACE_Token_Proxy;
99 // 3..
101 * @class ACE_TPQ_Entry
103 * @brief Token Proxy Queue entry. Used in the ACE_Token_Proxy_Queue
105 * Not a public interface.
107 class ACE_Export ACE_TPQ_Entry
109 friend class ACE_Token_Manager;
110 public:
111 typedef void (*PTVF) (void *);
113 /// Null constructor.
114 ACE_TPQ_Entry (void);
116 /// Constructor.
117 ACE_TPQ_Entry (const ACE_Token_Proxy *proxy,
118 const ACE_TCHAR *client_id);
120 /// Copy constructor.
121 ACE_TPQ_Entry (const ACE_TPQ_Entry &rhs);
123 /// Destructor.
124 ~ACE_TPQ_Entry (void);
126 /// Copy operator use by the queue.
127 void operator= (const ACE_TPQ_Entry &rhs);
129 /// Get top of the queue.
130 ACE_Token_Proxy *proxy (void) const;
132 /// Set top of the queue.
133 void proxy (ACE_Token_Proxy *);
135 /// Get nesting level of the entry.
136 int nesting_level (void) const;
138 /// Delta nesting level of the entry.
139 void nesting_level (int delta);
141 /// Get client_id of the entry.
142 const ACE_TCHAR *client_id (void) const;
144 /// Set client_id of the entry.
145 void client_id (const ACE_TCHAR *);
147 /// Returns 1 if @a id == client id. Does not check for @a id == 0.
148 int equal_client_id (const ACE_TCHAR *id);
150 /// One method for arg and sleep_hook.
151 void set (void (*sleep_hook)(void *));
153 /// Set sleep hook of the entry.
154 void sleep_hook (void (*sh)(void *));
156 /// Get sleep hook of the entry.
157 PTVF sleep_hook (void) const;
159 /// Call the sleep hook function or method passing arg.
160 void call_sleep_hook (void);
162 /// Dump the state of the class.
163 void dump (void) const;
165 // = Used to block the thread if an acquire fails with EWOULDBLOCK.
166 ACE_TOKEN_CONST::COND_VAR cond_var_;
167 ACE_TOKEN_CONST::MUTEX lock_;
169 /// Pointer to next in list.
170 ACE_TPQ_Entry *next_;
172 /// Get whether this client is blocked waiting for a token.
173 int waiting (void) const;
175 /// Set whether this client is blocked waiting for a token.
176 void waiting (int w);
178 private:
179 /// This client is waiting for a token.
180 int waiting_;
182 /// Proxy.
183 ACE_Token_Proxy *proxy_;
185 /// Nesting level.
186 int nesting_level_;
188 /// Arg.
189 void *arg_;
191 /// Client id.
192 ACE_TCHAR client_id_[ACE_MAXCLIENTIDLEN];
194 /// Sleep hook.
195 void (*sleep_hook_)(void *);
198 // b..
199 #if defined (ACE_NO_TSS_TOKENS)
200 typedef ACE_TPQ_Entry ACE_TPQ_ENTRY;
201 #else
202 typedef ACE_TSS<ACE_TPQ_Entry> ACE_TPQ_ENTRY;
203 #endif /* ACE_NO_TSS_TOKENS */
206 * @class ACE_TSS_TPQ_Entry
208 * @brief ACE_TSS_TPQ_Entry
210 * Not a public interface.
212 class ACE_Export ACE_TSS_TPQ_Entry : public ACE_TPQ_ENTRY
214 public:
215 /// These are passed to the constructor of ACE_TPQ_Entry in
216 /// make_TSS_TYPE
217 ACE_TSS_TPQ_Entry (const ACE_Token_Proxy *proxy,
218 const ACE_TCHAR *client_id);
220 /// Destructor.
221 virtual ~ACE_TSS_TPQ_Entry (void);
223 /// Allows us to pass args to the construction of the TSS object.
224 virtual ACE_TPQ_Entry *make_TSS_TYPE (void) const;
226 /// Operator overloading and inheritence don't mix.
227 operator ACE_TPQ_Entry *(void);
229 /// Dump the state of the class.
230 void dump (void) const;
232 #if defined (ACE_NO_TSS_TOKENS)
233 ACE_TPQ_Entry *operator-> (void)
235 return (ACE_TPQ_Entry *) this;
237 #endif /* ACE_NO_TSS_TOKENS */
239 private:
240 /// Private: should not be used
241 ACE_TSS_TPQ_Entry (const ACE_TSS_TPQ_Entry &);
242 void operator= (const ACE_TSS_TPQ_Entry &);
244 // = These are passed to the constructor of ACE_TPQ_Entry in
245 // make_TSS_TYPE
247 /// Proxy.
248 const ACE_Token_Proxy *proxy_;
250 /// Client_id.
251 const ACE_TCHAR *client_id_;
254 class ACE_Token_Proxy_Queue;
256 // c..
258 * @class ACE_TPQ_Iterator
260 * @brief Iterates through ACE_Token_Proxy_Queues.
262 * Not a public interface.
264 class ACE_Export ACE_TPQ_Iterator
266 public:
267 /// Constructor.
268 ACE_TPQ_Iterator (ACE_Token_Proxy_Queue &q);
270 /// Destructor.
271 ~ACE_TPQ_Iterator (void);
273 /// Pass back the <next_item>.
274 int next (ACE_TPQ_Entry *&next_item);
276 /// Returns 1 when all items have been seen, else 0.
277 int done (void) const;
279 /// Move forward by one element in the queue.
280 void advance (void);
282 /// Dump the state of an object.
283 void dump (void) const;
285 private:
286 ACE_TPQ_Entry *current_;
289 // 4..
291 * @class ACE_Token_Proxy_Queue
293 * @brief Token waiter list.
295 * Not a public interface.
296 * This queue holds all the token proxies waiting for ownership
297 * of a token. Along with the proxy reference, it also stores
298 * the nesting level, client id, and a magic cookie from the
299 * proxy. This queue stores the ACE_TPQ_Entries by pointer
300 * values. It DOES NOT make copies. Thus, the user is
301 * responsible to ensure that the TPQ's stick around. This is
302 * motivated by the need to reduce dynamic memory allocation.
304 class ACE_Export ACE_Token_Proxy_Queue
306 public:
307 friend class ACE_TPQ_Iterator;
309 /// Constructor.
310 ACE_Token_Proxy_Queue (void);
312 /// Destructor.
313 ~ACE_Token_Proxy_Queue (void);
316 * Enqueue a proxy, nesting level, client_id, and a magic cookie at
317 * the given position in the list. If the position is -1, we
318 * enqueue at the end of the list (I think).
320 void enqueue (ACE_TPQ_Entry* new_entry,
321 int position);
323 /// Top of the queue.
324 const ACE_TPQ_Entry* head (void);
326 // int member (const ACE_TCHAR *id);
327 // Is this id in the waiter list?
329 /// Remove the top waiter.
330 void dequeue (void);
332 /// Remove the waiter whose proxy ref matches @a remove_me.
333 void remove (const ACE_TPQ_Entry *remove_me);
335 /// The number of waiters.
336 int size (void);
338 /// Dump the state of the class.
339 void dump (void) const;
341 protected:
342 /// Head.
343 ACE_TPQ_Entry *head_;
345 /// Tail.
346 ACE_TPQ_Entry *tail_;
348 /// Size.
349 int size_;
352 // 5..
354 * @class ACE_Tokens
356 * @brief Abstract representation of ACE tokens.
358 * Not a public interface.
359 * Currently, I don't see a reason for providing an abstract
360 * interface at this level of the library. As of yet, no one
361 * uses ACE_Tokens derivatives through this abstract interface
362 * except for ACE_Token_Manager. It only uses the statistical
363 * methods which are shared by all Tokens. For that reason, it
364 * still makes since to have a common base class. However,
365 * acquire, renew, and release do not need to have matching
366 * interfaces throughout all Tokens.
367 * To add a new type of token (e.g. semaphore), this class must
368 * be subtyped to define the new semantics. See
369 * ACE_Token_Manager for details.
371 class ACE_Export ACE_Tokens
373 public:
375 /// Null constructor.
376 ACE_Tokens (void);
378 /// Destructor
379 virtual ~ACE_Tokens (void);
381 /// No implementation.
382 virtual int acquire (ACE_TPQ_Entry *caller,
383 int ignore_deadlock,
384 int notify) = 0;
386 /// No implementation.
387 virtual int tryacquire (ACE_TPQ_Entry *caller) = 0;
389 /// No implementation.
390 virtual int renew (ACE_TPQ_Entry *caller,
391 int requeue_position) = 0;
393 /// No implementation.
394 virtual int release (ACE_TPQ_Entry *caller) = 0;
396 /// Move the caller to the front of the waiter list. This is for use
397 /// with remote mutexes and shadow mutexes.
398 void make_owner (ACE_TPQ_Entry *caller);
400 /// Remove the caller from the waiter list.
401 void remove (ACE_TPQ_Entry *caller);
403 // = Accessor methods.
405 /// Stack of owners.
406 typedef ACE_Unbounded_Stack<ACE_TPQ_Entry *> OWNER_STACK;
408 /// Returns a stack of the current owners. Returns -1 on error, 0 on
409 /// success. If <id> is non-zero, returns 1 if id is an owner.
410 virtual int owners (OWNER_STACK &o, const ACE_TCHAR *id) = 0;
412 /// Returns 1 if <id> is waiting for this token. 0 otherwise.
413 virtual int is_waiting_for (const ACE_TCHAR *id) = 0;
415 /// Returns 1 if <id> is an owner of this token. 0 otherwise.
416 virtual int is_owner (const ACE_TCHAR *id) = 0;
418 /// Return the queue of waiters.
419 virtual ACE_Token_Proxy_Queue *waiters (void);
421 /// Return the number of proxies that are currently waiting to get
422 /// the token.
423 virtual int no_of_waiters (void);
425 /// The current owner.
426 const ACE_TCHAR *owner_id (void);
428 /// Token name.
429 const ACE_TCHAR* name (void);
431 // = Reference counting. These are only called by the
432 // Token_Manager.
433 void inc_reference (void);
434 int dec_reference (void);
436 /// Dump the state of the class.
437 void dump (void) const;
440 * These are the Token types supported by the library at ship time.
441 * There is no restriction on the number of Token types added by
442 * "3rd parties." These are only necessary for the Token Server.
444 enum TOKEN_TYPES { MUTEX, RWLOCK };
447 * Provides a manual RTTI mechanism. This method is used only by
448 * ACE_Token_Request so that the type of a token can be sent to a
449 * remote Token Server.
451 virtual int type (void) const = 0;
453 // = The following methods allow the deadlock detection algorithm to
454 // check if this token has been visited.
456 /// Mark or unmark the token as visited.
457 void visit (int v);
459 /// Check if the token has been visited.
460 int visited (void);
462 /// All the data of the current owner.
463 ACE_TPQ_Entry *owner (void);
465 protected:
467 /// For the deadlock detection algorithm.
468 int visited_;
470 /// Reference count.
471 int reference_count_;
473 /// List of client's owning and waiting the token.
474 ACE_Token_Proxy_Queue waiters_;
476 /// Name of token.
477 ACE_TCHAR token_name_[ACE_MAXTOKENNAMELEN];
480 class ACE_Local_Mutex;
482 // 6..
484 * @class ACE_Mutex_Token
486 * @brief Class that acquires, renews, and releases a process-local
487 * synchronization token.
489 * Not a public interface.
490 * This class is a more general-purpose synchronization mechanism
491 * than SunOS 5.x mutexes. For example, it implements "recursive
492 * mutex" semantics, where a thread that owns the token can
493 * reacquire it without deadlocking. In addition, threads that
494 * are blocked awaiting the token are serviced in strict FIFO
495 * order as other threads release the token (SunOS 5.x mutexes
496 * don't strictly enforce an acquisition order).
498 class ACE_Export ACE_Mutex_Token : public ACE_Tokens
500 public:
501 /// Constructor
502 explicit ACE_Mutex_Token (const ACE_TCHAR* name);
504 /// Destructor
505 virtual ~ACE_Mutex_Token (void);
507 // = Synchronization operations.
508 // With acquire, renew, and release, the caller must be specified so
509 // that multiple proxies (e.g. ACE_Local_Mutex) can use the same
510 // token.
513 * Returns 0 on success, -1 on failure with <ACE_Log_Msg::errnum> as
514 * the reason. If errnum == EWOULDBLOCK, and notify == 1,
515 * <ACE_Token_Proxy::sleep_hook> has been called on the current
516 * owner of the token. If ignore_deadlock is passed as 1 and errnum
517 * == EDEADLK, then deadlock was detected via ace_token_manager.
519 virtual int acquire (ACE_TPQ_Entry *caller,
520 int ignore_deadlock,
521 int notify);
523 /// Same as acquire, but fails if would block
524 virtual int tryacquire (ACE_TPQ_Entry *caller);
527 * An optimized method that efficiently reacquires the token if no
528 * other threads are waiting. This is useful for situations where
529 * you don't want to degrade the quality of service if there are
530 * other threads waiting to get the token. If <requeue_position> ==
531 * -1 and there are other threads waiting to obtain the token we are
532 * queued at the end of the list of waiters. If <requeue_position>
533 * > -1 then it indicates how many entries to skip over before
534 * inserting our thread into the list of waiters (e.g.,
535 * <requeue_position> == 0 means "insert at front of the queue").
536 * Renew has the rather odd semantics such that if there are other
537 * waiting threads it will give up the token even if the
538 * nesting_level_ > 1. I'm not sure if this is really the right
539 * thing to do (since it makes it possible for shared data to be
540 * changed unexpectedly) so use with caution... Returns 0 on
541 * success, -1 on failure with <ACE_Log_Msg::errnum> as the reason.
542 * If errnum == EWOULDBLOCK, and notify == 1,
543 * <ACE_Token_Proxy::sleep_hook> has been called on the current
544 * owner of the token.
546 virtual int renew (ACE_TPQ_Entry *caller,
547 int requeue_position);
550 * Relinquish the token. If there are any waiters then the next one
551 * in line gets it. If the caller is not the owner, caller is
552 * removed from the waiter list.
554 virtual int release (ACE_TPQ_Entry *caller);
556 /// Dump the state of the class.
557 void dump (void) const;
559 /// Returns ACE_Tokens::MUTEX.
560 virtual int type (void) const;
562 /// Returns a stack of the current owners. Returns -1 on error, 0 on
563 /// success. If <id> is non-zero, returns 1 if id is an owner.
564 virtual int owners (OWNER_STACK &o, const ACE_TCHAR *id);
566 /// Returns 1 if <id> is waiting for this token. 0 otherwise.
567 virtual int is_waiting_for (const ACE_TCHAR *id);
569 /// Returns 1 if <id> is an owner of this token. 0 otherwise.
570 virtual int is_owner (const ACE_TCHAR *id);
572 private:
573 /// ACE_Mutex_Token used to lock internal data structures.
574 ACE_TOKEN_CONST::MUTEX lock_;
577 // 12..
579 * @class ACE_RW_Token
581 * @brief Class that acquires, renews, and releases a process-local
582 * synchronization token.
584 * Not a public interface.
585 * This class is a more general-purpose synchronization mechanism
586 * than SunOS 5.x mutexes. For example, it implements "recursive
587 * mutex" semantics, where a thread that owns the token can
588 * reacquire it without deadlocking. In addition, threads that are
589 * blocked awaiting the token are serviced in strict FIFO order as
590 * other threads release the token (SunOS 5.x mutexes don't strictly
591 * enforce an acquisition order).
593 class ACE_Export ACE_RW_Token : public ACE_Tokens
595 public:
596 /// Constructor.
597 explicit ACE_RW_Token (const ACE_TCHAR* name);
599 /// Destructor.
600 virtual ~ACE_RW_Token (void);
602 // = Synchronization operations.
603 // With acquire, renew, and release, the caller must be specified so
604 // that multiple proxies (e.g. ACE_Local_Mutex) can use the same
605 // token.
608 * Returns 0 on success, -1 on failure with <ACE_Log_Msg::errnum> as
609 * the reason. If errnum == EWOULDBLOCK, and notify == 1,
610 * <ACE_Token_Proxy::sleep_hook> has been called on the current
611 * owner of the token. If @a ignore_deadlock is passed as 1 and errnum
612 * == EDEADLK, then deadlock was detected via ACE_Token_Manager.
614 virtual int acquire (ACE_TPQ_Entry *caller,
615 int ignore_deadlock,
616 int notify);
618 /// Same as acquire except fails on would block
619 virtual int tryacquire (ACE_TPQ_Entry *caller);
622 * An optimized method that efficiently reacquires the token if no
623 * other threads are waiting. This is useful for situations where
624 * you don't want to degrade the quality of service if there are
625 * other threads waiting to get the token. If <requeue_position> ==
626 * -1 and there are other threads waiting to obtain the token we are
627 * queued at the end of the list of waiters. If <requeue_position>
628 * > -1 then it indicates how many entries to skip over before
629 * inserting our thread into the list of waiters (e.g.,
630 * <requeue_position> == 0 means "insert at front of the queue").
631 * Renew has the rather odd semantics such that if there are other
632 * waiting threads it will give up the token even if the
633 * nesting_level_ > 1. I'm not sure if this is really the right
634 * thing to do (since it makes it possible for shared data to be
635 * changed unexpectedly) so use with caution... Returns 0 on
636 * success, -1 on failure with <ACE_Log_Msg::errnum> as the reason.
637 * If errnum == EWOULDBLOCK, and notify == 1,
638 * <ACE_Token_Proxy::sleep_hook> has been called on the current
639 * owner of the token.
641 virtual int renew (ACE_TPQ_Entry *caller,
642 int requeue_position);
645 * Relinquish the token. If there are any waiters then the next one
646 * in line gets it. If the caller is not the owner, caller is
647 * removed from the waiter list.
649 virtual int release (ACE_TPQ_Entry *caller);
651 /// Dump the state of the class.
652 void dump (void) const;
654 /// These are the types that proxies can be.
655 enum PROXY_TYPE { READER, WRITER };
657 /// Returns READER or WRITER.
658 virtual int type (void) const;
660 /// Returns a stack of the current owners. Returns -1 on error, 0 on
661 /// success. If <id> is non-zero, returns 1 if id is an owner.
662 virtual int owners (OWNER_STACK &o, const ACE_TCHAR *id);
664 /// Returns 1 if <id> is waiting for this token. 0 otherwise.
665 virtual int is_waiting_for (const ACE_TCHAR *id);
667 /// Returns 1 if <id> is an owner of this token. 0 otherwise.
668 virtual int is_owner (const ACE_TCHAR *id);
670 protected:
671 /// The number of waiting writers.
672 int num_writers_;
674 /// ACE_Mutex_Token used to lock internal data structures.
675 ACE_TOKEN_CONST::MUTEX lock_;
677 /// Sets the new owner.
678 void notify_new_owner (ACE_TPQ_Entry *caller);
681 // a..
683 * @class ACE_Token_Name
685 * @brief Allows Token_Manger to identify tokens.
687 * For now, this is just a string. We need a string class
688 * anyway to use in ACE_Map_Manager. Having this class
689 * (instead of <ACE_SString>) allows us to easily change if
690 * needed. For instance, we may choose to identify tokens by
691 * name and *type* in the future.
693 class ACE_Export ACE_Token_Name
695 public:
696 /// Construction.
697 ACE_Token_Name (const ACE_TCHAR *token_name = 0);
699 /// Copy construction.
700 ACE_Token_Name (const ACE_Token_Name &rhs);
702 /// Destructor.
703 virtual ~ACE_Token_Name (void);
705 /// Copy.
706 void operator= (const ACE_Token_Name &rhs);
708 /// Comparison.
709 bool operator== (const ACE_Token_Name &rhs) const;
711 /// Get the token name.
712 const ACE_TCHAR *name (void) const;
714 /// Set the token name.
715 void name (const ACE_TCHAR *new_name);
717 /// Dump the state of the class.
718 void dump (void) const;
720 private:
721 /// Name of the token.
722 ACE_TCHAR token_name_[ACE_MAXTOKENNAMELEN];
725 // 7..
727 * @class ACE_Token_Proxy
729 * @brief Abstract representation of ACE tokens.
731 * Interface for all Tokens in ACE. This class implements the
732 * synchronization needed for tokens (condition variables etc.)
733 * The algorithms for the operations (acquire, release, etc.)
734 * operate on the generic ACE_Tokens interface. Thus, the _type_
735 * of token (mutex, rwlock) can be set at construction of
736 * ACE_Token_Proxy. You can use all Tokens in ACE through the
737 * ACE_Token_Proxy by passing the proper values at construction.
738 * Alternatively, there are class definitions which "know" how to
739 * do this (ACE_Local_Mutex, ACE_Local_RLock, ACE_Local_WLock).
740 * To add a new type of token (e.g. semaphore), this class is not
741 * changed. See ACE_Token_Manager for details.
742 * Tokens (e.g. ACE_Mutex_Token) assume that it can always call
743 * <ACE_Token_Proxy::token_acquired> on a new token owner. This
744 * is not a problem for synchronous use of token proxies (that is,
745 * when acquires block until successful.) However, for
746 * implementations of the Token Server, which may use asynch
747 * operations, the proxy can not go away after an acquire until
748 * the token is acquired. This is not really a problem, but
749 * should be understood.
751 class ACE_Export ACE_Token_Proxy
753 public:
754 friend class ACE_Token_Manager;
755 friend class ACE_Token_Invariant_Manager; // For testing.
757 // Initialization and termination methods.
758 /// Construction.
759 ACE_Token_Proxy (void);
761 /// Destructor.
762 virtual ~ACE_Token_Proxy (void);
765 * Open the <ACE_Token>.
766 * @param name The string uniquely identifying the token.
767 * @param ignore_deadlock Can be 1 to disable deadlock notifications.
768 * @param debug Prints debug messages.
770 virtual int open (const ACE_TCHAR *name,
771 int ignore_deadlock = 0,
772 int debug = 0);
774 // = The following methods have implementations which are
775 // independent of the token semantics (mutex, rwlock, etc.) They
776 // forward operations to the underlying token and perform the
777 // necessary blocking semantics for operations (condition variables
778 // etc.) This allows reuse of the blocking code as well as having
779 // multiple proxies to the same token.
781 /// Calls acquire on the token. Blocks the calling thread if would
782 /// block.
783 virtual int acquire (int notify = 0,
784 void (*sleep_hook)(void *) = 0,
785 ACE_Synch_Options &options =
786 ACE_Synch_Options::defaults);
788 /// Calls renew on the token. Blocks the calling thread if would block.
789 virtual int renew (int requeue_position = -1,
790 ACE_Synch_Options &options =
791 ACE_Synch_Options::defaults);
793 /// Calls renew on the token.
794 virtual int tryacquire (void (*sleep_hook)(void *) = 0);
796 /// Calls release on the token.
797 virtual int release (ACE_Synch_Options &options =
798 ACE_Synch_Options::defaults);
800 /// Calls remove on the token.
801 virtual int remove (ACE_Synch_Options &options =
802 ACE_Synch_Options::defaults);
804 /// Since the locking mechanism doesn't support read locks then this
805 /// just calls <acquire>.
806 virtual int acquire_read (int notify = 0,
807 void (*sleep_hook)(void *) = 0,
808 ACE_Synch_Options &options =
809 ACE_Synch_Options::defaults);
811 /// Since the locking mechanism doesn't support write locks then this
812 /// just calls <acquire>.
813 virtual int acquire_write (int notify = 0,
814 void (*sleep_hook)(void *) = 0,
815 ACE_Synch_Options &options =
816 ACE_Synch_Options::defaults);
818 /// Since the locking mechanism doesn't support read locks then this
819 /// just calls <tryacquire>.
820 virtual int tryacquire_read (void (*sleep_hook)(void *) = 0);
822 /// Since the locking mechanism doesn't support write locks then this
823 /// just calls <tryacquire>.
824 virtual int tryacquire_write (void (*sleep_hook)(void *) = 0);
826 // = Utility methods.
828 /// Get the client id of the proxy. This is implemented as
829 /// thread-specific data.
830 virtual const ACE_TCHAR *client_id (void) const;
833 * Set the client_id for the calling thread. I strongly recommend
834 * that this not be used unless you really know what you're doing.
835 * I use this in the Token Server, and it caused many headaches.
837 virtual void client_id (const ACE_TCHAR *client_id);
840 * Return the name of the token. This is important for use within
841 * the token servers (local and remote) as well as with token
842 * collections. So, all derivations of ACE_Token_Proxy must be able to
843 * stringify some name. The name must uniquely identify a token.
844 * So, for instance, the token within the reactor should probably be
845 * called "Reactor Token."
847 virtual const ACE_TCHAR *name (void) const;
850 * This should really be called <someone_waiting>. This is called
851 * by ACE_Token_xx's when another proxy enters the waiting list and
852 * requests that the current token holder be notified.
854 virtual void sleep_hook (void);
856 /// This is called when a queued (waiting) proxy is removed from the
857 /// waiters list and given the token.
858 virtual void token_acquired (ACE_TPQ_Entry *);
860 /// The client id of the current token holder
861 virtual const ACE_TCHAR *owner_id (void);
863 /// Return a dynamically allocated clone of the derived class.
864 virtual ACE_Token_Proxy *clone (void) const = 0;
866 /// Dump the state of the class.
867 void dump (void) const;
870 * This method can be used be Tokens (e.g. Readers/Writer Tokens) to
871 * distinguish between Proxy types. For instance a Reader proxy
872 * should return a different type value than a Writer proxy. The
873 * default implementation returns 0.
875 virtual int type (void) const;
877 protected:
878 /// Duplication.
879 ACE_Token_Proxy (const ACE_Token_Proxy &);
881 /// If this is set, we ignore deadlock.
882 int ignore_deadlock_;
884 /// Print a bunch of debug messages.
885 int debug_;
887 /// Reference to the actual logical token. Many ACE_Local_Mutex
888 /// proxies can reference the same ACE_Mutex_Token.
889 ACE_Tokens *token_;
891 /// Handles cond_var waits.
892 int handle_options (ACE_Synch_Options &options,
893 ACE_TOKEN_CONST::COND_VAR &cv);
895 /// Waiter info used for asynchronous transactions.
896 ACE_TSS_TPQ_Entry waiter_;
898 /// Make the correct type of ACE_Tokens. This is called by the Token
899 /// Manager.
900 virtual ACE_Tokens *create_token (const ACE_TCHAR *name) = 0;
903 // 8..
905 * @class ACE_Null_Token
907 * @brief No op class for nonthreaded platform protocols.
909 class ACE_Export ACE_Null_Token : public ACE_Token_Proxy
911 public:
912 #if defined (ACE_LACKS_INLINE_FUNCTIONS)
913 // @@ Hopefully, we can remove this ridicules ifdef when CE's compiler becomes more normal.
914 /// Construction.
915 ACE_Null_Token (void);
917 /// Destructor.
918 ~ACE_Null_Token (void);
919 #endif /* ACE_LACKS_INLINE_FUNCTION */
921 /// Acquire.
922 virtual int acquire (int /* notify */ = 0,
923 void (* /* sleep_hook */ )(void *) = 0,
924 ACE_Synch_Options & /* options */ =
925 ACE_Synch_Options::defaults) { return 0; }
927 /// Renew.
928 virtual int renew (int /* requeue_position */ = -1,
929 ACE_Synch_Options & /* options */ =
930 ACE_Synch_Options::defaults) { return 0; }
932 /// Try acquire.
933 virtual int tryacquire (void (* /* sleep_hook */)(void *) = 0) { return 0; }
935 /// Release.
936 virtual int release (ACE_Synch_Options & /* options */ =
937 ACE_Synch_Options::defaults) { return 0; }
939 /// Remove.
940 virtual int remove (ACE_Synch_Options & /* options */ =
941 ACE_Synch_Options::defaults) { return 0; }
943 /// Return a dynamically allocated clone of the derived class.
944 virtual ACE_Token_Proxy *clone (void) const { return new ACE_Null_Token; }
946 /// Dump the state of the class.
947 void dump (void) const;
949 /// Do not allow the Token Manager to create us.
950 virtual ACE_Tokens *create_token (const ACE_TCHAR *) { return 0; }
953 // 9..
955 * @class ACE_Local_Mutex
957 * @brief Class that acquires, renews, and releases a synchronization
958 * token local to the process.
960 * This class is a more general-purpose synchronization mechanism
961 * than SunOS 5.x mutexes. For example, it implements "recursive
962 * mutex" semantics, where a thread that owns the token can
963 * reacquire it without deadlocking. In addition, threads that
964 * are blocked awaiting the token are serviced in strict FIFO
965 * order as other threads release the token (SunOS 5.x mutexes
966 * don't strictly enforce an acquisition order). Lastly,
967 * ACE_Local_Mutex performs deadlock detection on acquire calls.
968 * The interfaces for acquire, tryacquire, renew, release,
969 * etc. are defined in ACE_Token_Proxy. The semantics for
970 * ACE_Local_Mutex are that of a mutex.
972 class ACE_Export ACE_Local_Mutex : public ACE_Token_Proxy
974 public:
976 * Constructor.
977 * @param token_name Uniquely id's the token.
978 * @param ignore_deadlock Will allow deadlock to occur (useful for testing).
979 * @param debug Prints a bunch of messages.
981 ACE_Local_Mutex (const ACE_TCHAR *token_name = 0,
982 int ignore_deadlock = 0,
983 int debug = 0);
985 /// Destructor
986 ~ACE_Local_Mutex (void);
988 /// Dump the state of the class.
989 void dump (void) const;
991 /// Return deep copy.
992 virtual ACE_Token_Proxy *clone (void) const;
994 protected:
995 /// Return a new ACE_Local_Mutex.
996 virtual ACE_Tokens *create_token (const ACE_TCHAR *name);
999 // *.
1001 * @class ACE_Local_RLock
1003 * @brief Class that acquires, renews, and releases a readers lock that
1004 * is local to the process.
1006 * This class implements the reader interface to canonical
1007 * readers/writer locks. Multiple readers can hold the lock
1008 * simultaneously when no writers have the lock. Alternatively,
1009 * when a writer holds the lock, no other participants (readers
1010 * or writers) may hold the lock. This class is a more
1011 * general-purpose synchronization mechanism than SunOS 5.x
1012 * RLocks. For example, it implements "recursive RLock"
1013 * semantics, where a thread that owns the token can reacquire it
1014 * without deadlocking. In addition, threads that are blocked
1015 * awaiting the token are serviced in strict FIFO order as other
1016 * threads release the token (SunOS 5.x RLockes don't strictly
1017 * enforce an acquisition order).
1018 * The interfaces for acquire, tryacquire, renew, release,
1019 * etc. are defined in ACE_Token_Proxy. The semantics for
1020 * ACE_Local_RLock are that of a readers/writers lock. Acquire
1021 * for this class implies a reader acquisition. That is,
1022 * multiple clients may acquire a lock for read only.
1024 class ACE_Export ACE_Local_RLock : public ACE_Token_Proxy
1026 public:
1027 // = Initialization and termination.
1030 * Constructor.
1031 * @param token_name Uniquely id's the token.
1032 * @param ignore_deadlock Will allow deadlock to occur (useful for testing).
1033 * @param debug Prints a bunch of messages.
1035 ACE_Local_RLock (const ACE_TCHAR *token_name = 0,
1036 int ignore_deadlock = 0,
1037 int debug = 0);
1039 /// Destructor
1040 ~ACE_Local_RLock (void);
1042 /// Dump the state of the class.
1043 void dump (void) const;
1045 /// Returns ACE_RW_Token::RLOCK.
1046 virtual int type (void) const;
1048 /// Return deep copy.
1049 virtual ACE_Token_Proxy *clone (void) const;
1051 protected:
1052 /// Return a new ACE_Local_Mutex.
1053 virtual ACE_Tokens *create_token (const ACE_TCHAR *name);
1056 // *.
1058 * @class ACE_Local_WLock
1060 * @brief Class that acquires, renews, and releases a writer lock that
1061 * is local to the process.
1063 * This class implements the writer interface to canonical
1064 * readers/writer locks. Multiple readers can hold the lock
1065 * simultaneously when no writers have the lock. Alternatively,
1066 * when a writer holds the lock, no other participants (readers
1067 * or writers) may hold the lock. This class is a more
1068 * general-purpose synchronization mechanism than SunOS 5.x
1069 * WLock. For example, it implements "recursive WLock"
1070 * semantics, where a thread that owns the token can reacquire it
1071 * without deadlocking. In addition, threads that are blocked
1072 * awaiting the token are serviced in strict FIFO order as other
1073 * threads release the token (SunOS 5.x WLocks don't strictly
1074 * enforce an acquisition order).
1075 * The interfaces for acquire, tryacquire, renew, release,
1076 * etc. are defined in ACE_Token_Proxy. The semantics for
1077 * ACE_Local_WLock are that of a readers/writers lock. Acquire
1078 * for this class implies a writer acquisition. That is, only
1079 * one client may hold the lock for writing.
1081 class ACE_Export ACE_Local_WLock : public ACE_Token_Proxy
1083 public:
1084 // = Initialization and termination.
1087 * Constructor.
1088 * @param token_name Uniquely id's the token.
1089 * @param ignore_deadlock Will allow deadlock to occur (useful for testing).
1090 * @param debug Prints a bunch of messages.
1092 ACE_Local_WLock (const ACE_TCHAR *token_name = 0,
1093 int ignore_deadlock = 0,
1094 int debug = 0);
1096 /// Destructor
1097 ~ACE_Local_WLock (void);
1099 /// Dump the state of the class.
1100 void dump (void) const;
1102 /// Returns ACE_RW_Token::WLOCK.
1103 virtual int type (void) const;
1105 /// Return deep copy.
1106 virtual ACE_Token_Proxy *clone (void) const;
1108 protected:
1109 /// Return a new ACE_Local_Mutex.
1110 ACE_Tokens *create_token (const ACE_TCHAR *name);
1113 ACE_END_VERSIONED_NAMESPACE_DECL
1115 #endif /* ACE_HAS_TOKENS_LIBRARY */
1117 #if defined (__ACE_INLINE__)
1118 #include "ace/Local_Tokens.inl"
1119 #endif /* __ACE_INLINE__ */
1120 #include /**/ "ace/post.h"
1121 #endif /* ACE_LOCAL_MUTEX_H */