Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / Local_Tokens.h
blobfcfe7766c3eef00414616f797059f1732f62a670
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file Local_Tokens.h
7 * @author Karl-Heinz Dorn <kdorn@erlh.siemens.de>
8 * @author Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
9 * @author Tim Harrison <harrison@cs.wustl.edu>
11 * This file contains definitions for the following classes:
13 * public:
14 * 7. ACE_Token_Proxy
15 * 8. ACE_Null_Token : public ACE_Token_Proxy
16 * 9. ACE_Local_Mutex : public ACE_Token_Proxy
17 * *. ACE_Local_RLock : public ACE_Local_Mutex
18 * &. ACE_Local_WLock : public ACE_Local_Mutex
19 * private:
20 * 1. ACE_TOKEN_CONST
21 * 3. ACE_TPQ_Entry
22 * b. ACE_TSS_TPQ_Entry
23 * c. ACE_TPQ_Iterator
24 * 4. ACE_Token_Proxy_Queue
25 * 5. ACE_Tokens
26 * 6. ACE_Mutex_Token : public ACE_Tokens
27 * 12. ACE_RW_Token : public ACE_Tokens
28 * a. ACE_Token_Name
30 * Note that the locking classes defined in this file are *not*
31 * intended to be used as general-purpose synchronization
32 * mechanisms, such as mutexes or semaphores. Instead, you should
33 * use the ACE_Recursive_Thread_Mutex, ACE_Thread_Mutex,
34 * ACE_Thread_Semaphore, etc., that are defined in
35 * $ACE_ROOT/ace/Synch.h or the
36 * ACE_Token that's defined in $ACE_ROOT/ace/Token.h.
38 //=============================================================================
40 #ifndef ACE_LOCAL_MUTEX_H
41 #define ACE_LOCAL_MUTEX_H
42 #include /**/ "ace/pre.h"
44 #include /**/ "ace/config-all.h"
46 #if !defined (ACE_LACKS_PRAGMA_ONCE)
47 # pragma once
48 #endif /* ACE_LACKS_PRAGMA_ONCE */
50 #if defined (ACE_HAS_TOKENS_LIBRARY)
52 #include "ace/Synch_Traits.h"
53 #include "ace/Condition_Thread_Mutex.h"
54 #include "ace/TSS_T.h"
55 #include "ace/Containers.h"
56 #include "ace/Synch_Options.h"
57 #include "ace/Map_Manager.h"
58 #include "ace/Log_Category.h"
59 #include "ace/OS_NS_string.h"
60 #include "ace/os_include/os_netdb.h"
62 #if !(defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE))
63 # define ACE_NO_TSS_TOKENS 1
64 #endif /* !(defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)) */
66 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
68 // 1.
69 /**
70 * @class ACE_TOKEN_CONST
72 * @brief Not a public interface.
74 * Constant definitions and typedefs for Token library. Mostly,
75 * this class is necessary to fight the compiler with order of
76 * declaration errors.
78 // FUZZ: disable check_for_ACE_Guard
79 namespace ACE_TOKEN_CONST
81 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
82 // ACE platform supports some form of threading.
83 typedef ACE_Condition_Thread_Mutex COND_VAR;
84 typedef ACE_Thread_Mutex MUTEX;
85 typedef ACE_Guard<ACE_Thread_Mutex> GUARD;
86 #else
87 typedef ACE_Null_Condition COND_VAR;
88 typedef ACE_Null_Mutex MUTEX;
89 typedef ACE_Guard<ACE_Null_Mutex> GUARD;
90 #endif /* ACE_HAS_THREADS */
92 // FUZZ: enable check_for_ACE_Guard
94 // Forward decl.
95 class ACE_Token_Proxy;
97 // 3..
98 /**
99 * @class ACE_TPQ_Entry
101 * @brief Token Proxy Queue entry. Used in the ACE_Token_Proxy_Queue
103 * Not a public interface.
105 class ACE_Export ACE_TPQ_Entry
107 friend class ACE_Token_Manager;
108 public:
109 typedef void (*PTVF) (void *);
111 /// Null constructor.
112 ACE_TPQ_Entry ();
114 /// Constructor.
115 ACE_TPQ_Entry (const ACE_Token_Proxy *proxy,
116 const ACE_TCHAR *client_id);
118 /// Copy constructor.
119 ACE_TPQ_Entry (const ACE_TPQ_Entry &rhs);
121 /// Destructor.
122 ~ACE_TPQ_Entry ();
124 /// Copy operator use by the queue.
125 void operator= (const ACE_TPQ_Entry &rhs);
127 /// Get top of the queue.
128 ACE_Token_Proxy *proxy () const;
130 /// Set top of the queue.
131 void proxy (ACE_Token_Proxy *);
133 /// Get nesting level of the entry.
134 int nesting_level () const;
136 /// Delta nesting level of the entry.
137 void nesting_level (int delta);
139 /// Get client_id of the entry.
140 const ACE_TCHAR *client_id () const;
142 /// Set client_id of the entry.
143 void client_id (const ACE_TCHAR *);
145 /// Returns 1 if @a id == client id. Does not check for @a id == 0.
146 int equal_client_id (const ACE_TCHAR *id);
148 /// One method for arg and sleep_hook.
149 void set (void (*sleep_hook)(void *));
151 /// Set sleep hook of the entry.
152 void sleep_hook (void (*sh)(void *));
154 /// Get sleep hook of the entry.
155 PTVF sleep_hook () const;
157 /// Call the sleep hook function or method passing arg.
158 void call_sleep_hook ();
160 /// Dump the state of the class.
161 void dump () const;
163 // = Used to block the thread if an acquire fails with EWOULDBLOCK.
164 ACE_TOKEN_CONST::COND_VAR cond_var_;
165 ACE_TOKEN_CONST::MUTEX lock_;
167 /// Pointer to next in list.
168 ACE_TPQ_Entry *next_;
170 /// Get whether this client is blocked waiting for a token.
171 int waiting () const;
173 /// Set whether this client is blocked waiting for a token.
174 void waiting (int w);
176 private:
177 /// This client is waiting for a token.
178 int waiting_;
180 /// Proxy.
181 ACE_Token_Proxy *proxy_;
183 /// Nesting level.
184 int nesting_level_;
186 /// Arg.
187 void *arg_;
189 /// Client id.
190 ACE_TCHAR client_id_[ACE_MAXCLIENTIDLEN];
192 /// Sleep hook.
193 void (*sleep_hook_)(void *);
196 // b..
197 #if defined (ACE_NO_TSS_TOKENS)
198 typedef ACE_TPQ_Entry ACE_TPQ_ENTRY;
199 #else
200 typedef ACE_TSS<ACE_TPQ_Entry> ACE_TPQ_ENTRY;
201 #endif /* ACE_NO_TSS_TOKENS */
204 * @class ACE_TSS_TPQ_Entry
206 * @brief ACE_TSS_TPQ_Entry
208 * Not a public interface.
210 class ACE_Export ACE_TSS_TPQ_Entry : public ACE_TPQ_ENTRY
212 public:
213 /// These are passed to the constructor of ACE_TPQ_Entry in
214 /// make_TSS_TYPE
215 ACE_TSS_TPQ_Entry (const ACE_Token_Proxy *proxy,
216 const ACE_TCHAR *client_id);
218 /// Destructor.
219 virtual ~ACE_TSS_TPQ_Entry () = default;
221 /// Allows us to pass args to the construction of the TSS object.
222 virtual ACE_TPQ_Entry *make_TSS_TYPE () const;
224 /// Operator overloading and inheritance don't mix.
225 operator ACE_TPQ_Entry *();
227 /// Dump the state of the class.
228 void dump () const;
230 #if defined (ACE_NO_TSS_TOKENS)
231 ACE_TPQ_Entry *operator-> ()
233 return (ACE_TPQ_Entry *) this;
235 #endif /* ACE_NO_TSS_TOKENS */
237 private:
238 ACE_TSS_TPQ_Entry (const ACE_TSS_TPQ_Entry &) = delete;
239 void operator= (const ACE_TSS_TPQ_Entry &) = delete;
241 // = These are passed to the constructor of ACE_TPQ_Entry in
242 // make_TSS_TYPE
244 /// Proxy.
245 const ACE_Token_Proxy *proxy_;
247 /// Client_id.
248 const ACE_TCHAR *client_id_;
251 class ACE_Token_Proxy_Queue;
253 // c..
255 * @class ACE_TPQ_Iterator
257 * @brief Iterates through ACE_Token_Proxy_Queues.
259 * Not a public interface.
261 class ACE_Export ACE_TPQ_Iterator
263 public:
264 /// Constructor.
265 ACE_TPQ_Iterator (ACE_Token_Proxy_Queue &q);
267 /// Destructor.
268 ~ACE_TPQ_Iterator () = default;
270 /// Pass back the @a next_item.
271 int next (ACE_TPQ_Entry *&next_item);
273 /// Returns 1 when all items have been seen, else 0.
274 int done () const;
276 /// Move forward by one element in the queue.
277 void advance ();
279 /// Dump the state of an object.
280 void dump () const;
282 private:
283 ACE_TPQ_Entry *current_;
286 // 4..
288 * @class ACE_Token_Proxy_Queue
290 * @brief Token waiter list.
292 * Not a public interface.
293 * This queue holds all the token proxies waiting for ownership
294 * of a token. Along with the proxy reference, it also stores
295 * the nesting level, client id, and a magic cookie from the
296 * proxy. This queue stores the ACE_TPQ_Entries by pointer
297 * values. It DOES NOT make copies. Thus, the user is
298 * responsible to ensure that the TPQ's stick around. This is
299 * motivated by the need to reduce dynamic memory allocation.
301 class ACE_Export ACE_Token_Proxy_Queue
303 public:
304 friend class ACE_TPQ_Iterator;
306 /// Constructor.
307 ACE_Token_Proxy_Queue ();
309 /// Destructor.
310 ~ACE_Token_Proxy_Queue () = default;
313 * Enqueue a proxy, nesting level, client_id, and a magic cookie at
314 * the given position in the list. If the position is -1, we
315 * enqueue at the end of the list (I think).
317 void enqueue (ACE_TPQ_Entry* new_entry,
318 int position);
320 /// Top of the queue.
321 const ACE_TPQ_Entry* head ();
323 // int member (const ACE_TCHAR *id);
324 // Is this id in the waiter list?
326 /// Remove the top waiter.
327 void dequeue ();
329 /// Remove the waiter whose proxy ref matches @a remove_me.
330 void remove (const ACE_TPQ_Entry *remove_me);
332 /// The number of waiters.
333 int size ();
335 /// Dump the state of the class.
336 void dump () const;
338 protected:
339 /// Head.
340 ACE_TPQ_Entry *head_;
342 /// Tail.
343 ACE_TPQ_Entry *tail_;
345 /// Size.
346 int size_;
349 // 5..
351 * @class ACE_Tokens
353 * @brief Abstract representation of ACE tokens.
355 * Not a public interface.
356 * Currently, I don't see a reason for providing an abstract
357 * interface at this level of the library. As of yet, no one
358 * uses ACE_Tokens derivatives through this abstract interface
359 * except for ACE_Token_Manager. It only uses the statistical
360 * methods which are shared by all Tokens. For that reason, it
361 * still makes since to have a common base class. However,
362 * acquire, renew, and release do not need to have matching
363 * interfaces throughout all Tokens.
364 * To add a new type of token (e.g. semaphore), this class must
365 * be subtyped to define the new semantics. See
366 * ACE_Token_Manager for details.
368 class ACE_Export ACE_Tokens
370 public:
371 /// Null constructor.
372 ACE_Tokens ();
374 /// Destructor
375 virtual ~ACE_Tokens () = default;
377 /// No implementation.
378 virtual int acquire (ACE_TPQ_Entry *caller,
379 int ignore_deadlock,
380 int notify) = 0;
382 /// No implementation.
383 virtual int tryacquire (ACE_TPQ_Entry *caller) = 0;
385 /// No implementation.
386 virtual int renew (ACE_TPQ_Entry *caller,
387 int requeue_position) = 0;
389 /// No implementation.
390 virtual int release (ACE_TPQ_Entry *caller) = 0;
392 /// Move the caller to the front of the waiter list. This is for use
393 /// with remote mutexes and shadow mutexes.
394 void make_owner (ACE_TPQ_Entry *caller);
396 /// Remove the caller from the waiter list.
397 void remove (ACE_TPQ_Entry *caller);
399 // = Accessor methods.
401 /// Stack of owners.
402 typedef ACE_Unbounded_Stack<ACE_TPQ_Entry *> OWNER_STACK;
404 /// Returns a stack of the current owners. Returns -1 on error, 0 on
405 /// success. If @a id is non-zero, returns 1 if id is an owner.
406 virtual int owners (OWNER_STACK &o, const ACE_TCHAR *id) = 0;
408 /// Returns 1 if @a id is waiting for this token. 0 otherwise.
409 virtual int is_waiting_for (const ACE_TCHAR *id) = 0;
411 /// Returns 1 if @a id is an owner of this token. 0 otherwise.
412 virtual int is_owner (const ACE_TCHAR *id) = 0;
414 /// Return the queue of waiters.
415 virtual ACE_Token_Proxy_Queue *waiters ();
417 /// Return the number of proxies that are currently waiting to get
418 /// the token.
419 virtual int no_of_waiters ();
421 /// The current owner.
422 const ACE_TCHAR *owner_id ();
424 /// Token name.
425 const ACE_TCHAR* name ();
427 // = Reference counting. These are only called by the
428 // Token_Manager.
429 void inc_reference ();
430 int dec_reference ();
432 /// Dump the state of the class.
433 void dump () const;
436 * These are the Token types supported by the library at ship time.
437 * There is no restriction on the number of Token types added by
438 * "3rd parties." These are only necessary for the Token Server.
440 enum TOKEN_TYPES { MUTEX, RWLOCK };
443 * Provides a manual RTTI mechanism. This method is used only by
444 * ACE_Token_Request so that the type of a token can be sent to a
445 * remote Token Server.
447 virtual int type () const = 0;
449 // = The following methods allow the deadlock detection algorithm to
450 // check if this token has been visited.
452 /// Mark or unmark the token as visited.
453 void visit (int v);
455 /// Check if the token has been visited.
456 int visited ();
458 /// All the data of the current owner.
459 ACE_TPQ_Entry *owner ();
461 protected:
462 /// For the deadlock detection algorithm.
463 int visited_;
465 /// Reference count.
466 int reference_count_;
468 /// List of client's owning and waiting the token.
469 ACE_Token_Proxy_Queue waiters_;
471 /// Name of token.
472 ACE_TCHAR token_name_[ACE_MAXTOKENNAMELEN];
475 class ACE_Local_Mutex;
477 // 6..
479 * @class ACE_Mutex_Token
481 * @brief Class that acquires, renews, and releases a process-local
482 * synchronization token.
484 * Not a public interface.
485 * This class is a more general-purpose synchronization mechanism
486 * than SunOS 5.x mutexes. For example, it implements "recursive
487 * mutex" semantics, where a thread that owns the token can
488 * reacquire it without deadlocking. In addition, threads that
489 * are blocked awaiting the token are serviced in strict FIFO
490 * order as other threads release the token (SunOS 5.x mutexes
491 * don't strictly enforce an acquisition order).
493 class ACE_Export ACE_Mutex_Token : public ACE_Tokens
495 public:
496 /// Constructor
497 explicit ACE_Mutex_Token (const ACE_TCHAR* name);
499 /// Destructor
500 virtual ~ACE_Mutex_Token ();
502 // = Synchronization operations.
503 // With acquire, renew, and release, the caller must be specified so
504 // that multiple proxies (e.g. ACE_Local_Mutex) can use the same
505 // token.
508 * Returns 0 on success, -1 on failure with <ACE_Log_Msg::errnum> as
509 * the reason. If errnum == EWOULDBLOCK, and notify == 1,
510 * <ACE_Token_Proxy::sleep_hook> has been called on the current
511 * owner of the token. If ignore_deadlock is passed as 1 and errnum
512 * == EDEADLK, then deadlock was detected via ace_token_manager.
514 virtual int acquire (ACE_TPQ_Entry *caller,
515 int ignore_deadlock,
516 int notify);
518 /// Same as acquire, but fails if would block
519 virtual int tryacquire (ACE_TPQ_Entry *caller);
522 * An optimized method that efficiently reacquires the token if no
523 * other threads are waiting. This is useful for situations where
524 * you don't want to degrade the quality of service if there are
525 * other threads waiting to get the token. If <requeue_position> ==
526 * -1 and there are other threads waiting to obtain the token we are
527 * queued at the end of the list of waiters. If <requeue_position>
528 * > -1 then it indicates how many entries to skip over before
529 * inserting our thread into the list of waiters (e.g.,
530 * <requeue_position> == 0 means "insert at front of the queue").
531 * Renew has the rather odd semantics such that if there are other
532 * waiting threads it will give up the token even if the
533 * nesting_level_ > 1. I'm not sure if this is really the right
534 * thing to do (since it makes it possible for shared data to be
535 * changed unexpectedly) so use with caution... Returns 0 on
536 * success, -1 on failure with <ACE_Log_Msg::errnum> as the reason.
537 * If errnum == EWOULDBLOCK, and notify == 1,
538 * <ACE_Token_Proxy::sleep_hook> has been called on the current
539 * owner of the token.
541 virtual int renew (ACE_TPQ_Entry *caller,
542 int requeue_position);
545 * Relinquish the token. If there are any waiters then the next one
546 * in line gets it. If the caller is not the owner, caller is
547 * removed from the waiter list.
549 virtual int release (ACE_TPQ_Entry *caller);
551 /// Dump the state of the class.
552 void dump () const;
554 /// Returns ACE_Tokens::MUTEX.
555 virtual int type () const;
557 /// Returns a stack of the current owners. Returns -1 on error, 0 on
558 /// success. If @a id is non-zero, returns 1 if id is an owner.
559 virtual int owners (OWNER_STACK &o, const ACE_TCHAR *id);
561 /// Returns 1 if @a id is waiting for this token. 0 otherwise.
562 virtual int is_waiting_for (const ACE_TCHAR *id);
564 /// Returns 1 if @a id is an owner of this token. 0 otherwise.
565 virtual int is_owner (const ACE_TCHAR *id);
567 private:
568 /// ACE_Mutex_Token used to lock internal data structures.
569 ACE_TOKEN_CONST::MUTEX lock_;
572 // 12..
574 * @class ACE_RW_Token
576 * @brief Class that acquires, renews, and releases a process-local
577 * synchronization token.
579 * Not a public interface.
580 * This class is a more general-purpose synchronization mechanism
581 * than SunOS 5.x mutexes. For example, it implements "recursive
582 * mutex" semantics, where a thread that owns the token can
583 * reacquire it without deadlocking. In addition, threads that are
584 * blocked awaiting the token are serviced in strict FIFO order as
585 * other threads release the token (SunOS 5.x mutexes don't strictly
586 * enforce an acquisition order).
588 class ACE_Export ACE_RW_Token : public ACE_Tokens
590 public:
591 /// Constructor.
592 explicit ACE_RW_Token (const ACE_TCHAR* name);
594 /// Destructor.
595 virtual ~ACE_RW_Token ();
597 // = Synchronization operations.
598 // With acquire, renew, and release, the caller must be specified so
599 // that multiple proxies (e.g. ACE_Local_Mutex) can use the same
600 // token.
603 * Returns 0 on success, -1 on failure with <ACE_Log_Msg::errnum> as
604 * the reason. If errnum == EWOULDBLOCK, and notify == 1,
605 * <ACE_Token_Proxy::sleep_hook> has been called on the current
606 * owner of the token. If @a ignore_deadlock is passed as 1 and errnum
607 * == EDEADLK, then deadlock was detected via ACE_Token_Manager.
609 virtual int acquire (ACE_TPQ_Entry *caller,
610 int ignore_deadlock,
611 int notify);
613 /// Same as acquire except fails on would block
614 virtual int tryacquire (ACE_TPQ_Entry *caller);
617 * An optimized method that efficiently reacquires the token if no
618 * other threads are waiting. This is useful for situations where
619 * you don't want to degrade the quality of service if there are
620 * other threads waiting to get the token. If <requeue_position> ==
621 * -1 and there are other threads waiting to obtain the token we are
622 * queued at the end of the list of waiters. If <requeue_position>
623 * > -1 then it indicates how many entries to skip over before
624 * inserting our thread into the list of waiters (e.g.,
625 * <requeue_position> == 0 means "insert at front of the queue").
626 * Renew has the rather odd semantics such that if there are other
627 * waiting threads it will give up the token even if the
628 * nesting_level_ > 1. I'm not sure if this is really the right
629 * thing to do (since it makes it possible for shared data to be
630 * changed unexpectedly) so use with caution... Returns 0 on
631 * success, -1 on failure with <ACE_Log_Msg::errnum> as the reason.
632 * If errnum == EWOULDBLOCK, and notify == 1,
633 * <ACE_Token_Proxy::sleep_hook> has been called on the current
634 * owner of the token.
636 virtual int renew (ACE_TPQ_Entry *caller,
637 int requeue_position);
640 * Relinquish the token. If there are any waiters then the next one
641 * in line gets it. If the caller is not the owner, caller is
642 * removed from the waiter list.
644 virtual int release (ACE_TPQ_Entry *caller);
646 /// Dump the state of the class.
647 void dump () const;
649 /// These are the types that proxies can be.
650 enum PROXY_TYPE { READER, WRITER };
652 /// Returns READER or WRITER.
653 virtual int type () const;
655 /// Returns a stack of the current owners. Returns -1 on error, 0 on
656 /// success. If @a id is non-zero, returns 1 if id is an owner.
657 virtual int owners (OWNER_STACK &o, const ACE_TCHAR *id);
659 /// Returns 1 if @a id is waiting for this token. 0 otherwise.
660 virtual int is_waiting_for (const ACE_TCHAR *id);
662 /// Returns 1 if @a id is an owner of this token. 0 otherwise.
663 virtual int is_owner (const ACE_TCHAR *id);
665 protected:
666 /// The number of waiting writers.
667 int num_writers_;
669 /// ACE_Mutex_Token used to lock internal data structures.
670 ACE_TOKEN_CONST::MUTEX lock_;
672 /// Sets the new owner.
673 void notify_new_owner (ACE_TPQ_Entry *caller);
676 // a..
678 * @class ACE_Token_Name
680 * @brief Allows Token_Manger to identify tokens.
682 * For now, this is just a string. We need a string class
683 * anyway to use in ACE_Map_Manager. Having this class
684 * (instead of <ACE_SString>) allows us to easily change if
685 * needed. For instance, we may choose to identify tokens by
686 * name and *type* in the future.
688 class ACE_Export ACE_Token_Name
690 public:
691 /// Construction.
692 ACE_Token_Name (const ACE_TCHAR *token_name = 0);
694 /// Copy construction.
695 ACE_Token_Name (const ACE_Token_Name &rhs);
697 /// Destructor.
698 virtual ~ACE_Token_Name ();
700 /// Copy.
701 void operator= (const ACE_Token_Name &rhs);
703 /// Comparison.
704 bool operator== (const ACE_Token_Name &rhs) const;
706 /// Get the token name.
707 const ACE_TCHAR *name () const;
709 /// Set the token name.
710 void name (const ACE_TCHAR *new_name);
712 /// Dump the state of the class.
713 void dump () const;
715 private:
716 /// Name of the token.
717 ACE_TCHAR token_name_[ACE_MAXTOKENNAMELEN];
720 // 7..
722 * @class ACE_Token_Proxy
724 * @brief Abstract representation of ACE tokens.
726 * Interface for all Tokens in ACE. This class implements the
727 * synchronization needed for tokens (condition variables etc.)
728 * The algorithms for the operations (acquire, release, etc.)
729 * operate on the generic ACE_Tokens interface. Thus, the _type_
730 * of token (mutex, rwlock) can be set at construction of
731 * ACE_Token_Proxy. You can use all Tokens in ACE through the
732 * ACE_Token_Proxy by passing the proper values at construction.
733 * Alternatively, there are class definitions which "know" how to
734 * do this (ACE_Local_Mutex, ACE_Local_RLock, ACE_Local_WLock).
735 * To add a new type of token (e.g. semaphore), this class is not
736 * changed. See ACE_Token_Manager for details.
737 * Tokens (e.g. ACE_Mutex_Token) assume that it can always call
738 * <ACE_Token_Proxy::token_acquired> on a new token owner. This
739 * is not a problem for synchronous use of token proxies (that is,
740 * when acquires block until successful.) However, for
741 * implementations of the Token Server, which may use asynch
742 * operations, the proxy can not go away after an acquire until
743 * the token is acquired. This is not really a problem, but
744 * should be understood.
746 class ACE_Export ACE_Token_Proxy
748 public:
749 friend class ACE_Token_Manager;
750 friend class ACE_Token_Invariant_Manager; // For testing.
752 // Initialization and termination methods.
753 /// Construction.
754 ACE_Token_Proxy ();
756 /// Destructor.
757 virtual ~ACE_Token_Proxy ();
760 * Open the <ACE_Token>.
761 * @param name The string uniquely identifying the token.
762 * @param ignore_deadlock Can be 1 to disable deadlock notifications.
763 * @param debug Prints debug messages.
765 virtual int open (const ACE_TCHAR *name,
766 int ignore_deadlock = 0,
767 int debug = 0);
769 // = The following methods have implementations which are
770 // independent of the token semantics (mutex, rwlock, etc.) They
771 // forward operations to the underlying token and perform the
772 // necessary blocking semantics for operations (condition variables
773 // etc.) This allows reuse of the blocking code as well as having
774 // multiple proxies to the same token.
776 /// Calls acquire on the token. Blocks the calling thread if would
777 /// block.
778 virtual int acquire (int notify = 0,
779 void (*sleep_hook)(void *) = 0,
780 ACE_Synch_Options &options =
781 ACE_Synch_Options::defaults);
783 /// Calls renew on the token. Blocks the calling thread if would block.
784 virtual int renew (int requeue_position = -1,
785 ACE_Synch_Options &options =
786 ACE_Synch_Options::defaults);
788 /// Calls renew on the token.
789 virtual int tryacquire (void (*sleep_hook)(void *) = 0);
791 /// Calls release on the token.
792 virtual int release (ACE_Synch_Options &options =
793 ACE_Synch_Options::defaults);
795 /// Calls remove on the token.
796 virtual int remove (ACE_Synch_Options &options =
797 ACE_Synch_Options::defaults);
799 /// Since the locking mechanism doesn't support read locks then this
800 /// just calls <acquire>.
801 virtual int acquire_read (int notify = 0,
802 void (*sleep_hook)(void *) = 0,
803 ACE_Synch_Options &options =
804 ACE_Synch_Options::defaults);
806 /// Since the locking mechanism doesn't support write locks then this
807 /// just calls <acquire>.
808 virtual int acquire_write (int notify = 0,
809 void (*sleep_hook)(void *) = 0,
810 ACE_Synch_Options &options =
811 ACE_Synch_Options::defaults);
813 /// Since the locking mechanism doesn't support read locks then this
814 /// just calls <tryacquire>.
815 virtual int tryacquire_read (void (*sleep_hook)(void *) = 0);
817 /// Since the locking mechanism doesn't support write locks then this
818 /// just calls <tryacquire>.
819 virtual int tryacquire_write (void (*sleep_hook)(void *) = 0);
821 // = Utility methods.
823 /// Get the client id of the proxy. This is implemented as
824 /// thread-specific data.
825 virtual const ACE_TCHAR *client_id () const;
828 * Set the client_id for the calling thread. I strongly recommend
829 * that this not be used unless you really know what you're doing.
830 * I use this in the Token Server, and it caused many headaches.
832 virtual void client_id (const ACE_TCHAR *client_id);
835 * Return the name of the token. This is important for use within
836 * the token servers (local and remote) as well as with token
837 * collections. So, all derivations of ACE_Token_Proxy must be able to
838 * stringify some name. The name must uniquely identify a token.
839 * So, for instance, the token within the reactor should probably be
840 * called "Reactor Token."
842 virtual const ACE_TCHAR *name () const;
845 * This should really be called <someone_waiting>. This is called
846 * by ACE_Token_xx's when another proxy enters the waiting list and
847 * requests that the current token holder be notified.
849 virtual void sleep_hook ();
851 /// This is called when a queued (waiting) proxy is removed from the
852 /// waiters list and given the token.
853 virtual void token_acquired (ACE_TPQ_Entry *);
855 /// The client id of the current token holder
856 virtual const ACE_TCHAR *owner_id ();
858 /// Return a dynamically allocated clone of the derived class.
859 virtual ACE_Token_Proxy *clone () const = 0;
861 /// Dump the state of the class.
862 void dump () const;
865 * This method can be used be Tokens (e.g. Readers/Writer Tokens) to
866 * distinguish between Proxy types. For instance a Reader proxy
867 * should return a different type value than a Writer proxy. The
868 * default implementation returns 0.
870 virtual int type () const;
872 protected:
873 /// Duplication.
874 ACE_Token_Proxy (const ACE_Token_Proxy &);
876 /// If this is set, we ignore deadlock.
877 int ignore_deadlock_;
879 /// Print a bunch of debug messages.
880 int debug_;
882 /// Reference to the actual logical token. Many ACE_Local_Mutex
883 /// proxies can reference the same ACE_Mutex_Token.
884 ACE_Tokens *token_;
886 /// Handles cond_var waits.
887 int handle_options (ACE_Synch_Options &options,
888 ACE_TOKEN_CONST::COND_VAR &cv);
890 /// Waiter info used for asynchronous transactions.
891 ACE_TSS_TPQ_Entry waiter_;
893 /// Make the correct type of ACE_Tokens. This is called by the Token
894 /// Manager.
895 virtual ACE_Tokens *create_token (const ACE_TCHAR *name) = 0;
898 // 8..
900 * @class ACE_Null_Token
902 * @brief No op class for nonthreaded platform protocols.
904 class ACE_Export ACE_Null_Token : public ACE_Token_Proxy
906 public:
907 /// Construction.
908 ACE_Null_Token () = default;
910 /// Destructor.
911 ~ACE_Null_Token () = default;
913 /// Acquire.
914 virtual int acquire (int /* notify */ = 0,
915 void (* /* sleep_hook */ )(void *) = 0,
916 ACE_Synch_Options & /* options */ =
917 ACE_Synch_Options::defaults) { return 0; }
919 /// Renew.
920 virtual int renew (int /* requeue_position */ = -1,
921 ACE_Synch_Options & /* options */ =
922 ACE_Synch_Options::defaults) { return 0; }
924 /// Try acquire.
925 virtual int tryacquire (void (* /* sleep_hook */)(void *) = 0) { return 0; }
927 /// Release.
928 virtual int release (ACE_Synch_Options & /* options */ =
929 ACE_Synch_Options::defaults) { return 0; }
931 /// Remove.
932 virtual int remove (ACE_Synch_Options & /* options */ =
933 ACE_Synch_Options::defaults) { return 0; }
935 /// Return a dynamically allocated clone of the derived class.
936 virtual ACE_Token_Proxy *clone () const { return new ACE_Null_Token; }
938 /// Dump the state of the class.
939 void dump () const;
941 /// Do not allow the Token Manager to create us.
942 virtual ACE_Tokens *create_token (const ACE_TCHAR *) { return 0; }
945 // 9..
947 * @class ACE_Local_Mutex
949 * @brief Class that acquires, renews, and releases a synchronization
950 * token local to the process.
952 * This class is a more general-purpose synchronization mechanism
953 * than SunOS 5.x mutexes. For example, it implements "recursive
954 * mutex" semantics, where a thread that owns the token can
955 * reacquire it without deadlocking. In addition, threads that
956 * are blocked awaiting the token are serviced in strict FIFO
957 * order as other threads release the token (SunOS 5.x mutexes
958 * don't strictly enforce an acquisition order). Lastly,
959 * ACE_Local_Mutex performs deadlock detection on acquire calls.
960 * The interfaces for acquire, tryacquire, renew, release,
961 * etc. are defined in ACE_Token_Proxy. The semantics for
962 * ACE_Local_Mutex are that of a mutex.
964 class ACE_Export ACE_Local_Mutex : public ACE_Token_Proxy
966 public:
968 * Constructor.
969 * @param token_name Uniquely id's the token.
970 * @param ignore_deadlock Will allow deadlock to occur (useful for testing).
971 * @param debug Prints a bunch of messages.
973 ACE_Local_Mutex (const ACE_TCHAR *token_name = 0,
974 int ignore_deadlock = 0,
975 int debug = 0);
977 /// Destructor
978 ~ACE_Local_Mutex ();
980 /// Dump the state of the class.
981 void dump () const;
983 /// Return deep copy.
984 virtual ACE_Token_Proxy *clone () const;
986 protected:
987 /// Return a new ACE_Local_Mutex.
988 virtual ACE_Tokens *create_token (const ACE_TCHAR *name);
991 // *.
993 * @class ACE_Local_RLock
995 * @brief Class that acquires, renews, and releases a readers lock that
996 * is local to the process.
998 * This class implements the reader interface to canonical
999 * readers/writer locks. Multiple readers can hold the lock
1000 * simultaneously when no writers have the lock. Alternatively,
1001 * when a writer holds the lock, no other participants (readers
1002 * or writers) may hold the lock. This class is a more
1003 * general-purpose synchronization mechanism than SunOS 5.x
1004 * RLocks. For example, it implements "recursive RLock"
1005 * semantics, where a thread that owns the token can reacquire it
1006 * without deadlocking. In addition, threads that are blocked
1007 * awaiting the token are serviced in strict FIFO order as other
1008 * threads release the token (SunOS 5.x RLockes don't strictly
1009 * enforce an acquisition order).
1010 * The interfaces for acquire, tryacquire, renew, release,
1011 * etc. are defined in ACE_Token_Proxy. The semantics for
1012 * ACE_Local_RLock are that of a readers/writers lock. Acquire
1013 * for this class implies a reader acquisition. That is,
1014 * multiple clients may acquire a lock for read only.
1016 class ACE_Export ACE_Local_RLock : public ACE_Token_Proxy
1018 public:
1020 * Constructor.
1021 * @param token_name Uniquely id's the token.
1022 * @param ignore_deadlock Will allow deadlock to occur (useful for testing).
1023 * @param debug Prints a bunch of messages.
1025 ACE_Local_RLock (const ACE_TCHAR *token_name = 0,
1026 int ignore_deadlock = 0,
1027 int debug = 0);
1029 /// Destructor
1030 ~ACE_Local_RLock ();
1032 /// Dump the state of the class.
1033 void dump () const;
1035 /// Returns ACE_RW_Token::RLOCK.
1036 virtual int type () const;
1038 /// Return deep copy.
1039 virtual ACE_Token_Proxy *clone () const;
1041 protected:
1042 /// Return a new ACE_Local_Mutex.
1043 virtual ACE_Tokens *create_token (const ACE_TCHAR *name);
1046 // *.
1048 * @class ACE_Local_WLock
1050 * @brief Class that acquires, renews, and releases a writer lock that
1051 * is local to the process.
1053 * This class implements the writer interface to canonical
1054 * readers/writer locks. Multiple readers can hold the lock
1055 * simultaneously when no writers have the lock. Alternatively,
1056 * when a writer holds the lock, no other participants (readers
1057 * or writers) may hold the lock. This class is a more
1058 * general-purpose synchronization mechanism than SunOS 5.x
1059 * WLock. For example, it implements "recursive WLock"
1060 * semantics, where a thread that owns the token can reacquire it
1061 * without deadlocking. In addition, threads that are blocked
1062 * awaiting the token are serviced in strict FIFO order as other
1063 * threads release the token (SunOS 5.x WLocks don't strictly
1064 * enforce an acquisition order).
1065 * The interfaces for acquire, tryacquire, renew, release,
1066 * etc. are defined in ACE_Token_Proxy. The semantics for
1067 * ACE_Local_WLock are that of a readers/writers lock. Acquire
1068 * for this class implies a writer acquisition. That is, only
1069 * one client may hold the lock for writing.
1071 class ACE_Export ACE_Local_WLock : public ACE_Token_Proxy
1073 public:
1075 * Constructor.
1076 * @param token_name Uniquely id's the token.
1077 * @param ignore_deadlock Will allow deadlock to occur (useful for testing).
1078 * @param debug Prints a bunch of messages.
1080 ACE_Local_WLock (const ACE_TCHAR *token_name = 0,
1081 int ignore_deadlock = 0,
1082 int debug = 0);
1084 /// Destructor
1085 ~ACE_Local_WLock ();
1087 /// Dump the state of the class.
1088 void dump () const;
1090 /// Returns ACE_RW_Token::WLOCK.
1091 virtual int type () const;
1093 /// Return deep copy.
1094 virtual ACE_Token_Proxy *clone () const;
1096 protected:
1097 /// Return a new ACE_Local_Mutex.
1098 ACE_Tokens *create_token (const ACE_TCHAR *name);
1101 ACE_END_VERSIONED_NAMESPACE_DECL
1103 #endif /* ACE_HAS_TOKENS_LIBRARY */
1105 #if defined (__ACE_INLINE__)
1106 #include "ace/Local_Tokens.inl"
1107 #endif /* __ACE_INLINE__ */
1108 #include /**/ "ace/post.h"
1109 #endif /* ACE_LOCAL_MUTEX_H */