Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / Local_Tokens.cpp
blob215517c315700ab7c261613588642ebed2107083
1 #include "ace/Local_Tokens.h"
3 #if defined (ACE_HAS_TOKENS_LIBRARY)
5 #include "ace/Thread.h"
6 #include "ace/Token_Manager.h"
7 #include "ace/OS_NS_unistd.h"
9 #if !defined (__ACE_INLINE__)
10 #include "ace/Local_Tokens.inl"
11 #endif /* __ACE_INLINE__ */
13 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
15 void
16 ACE_Tokens::dump () const
18 #if defined (ACE_HAS_DUMP)
19 ACE_TRACE ("ACE_Tokens::dump");
20 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
21 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Tokens::dump:\n")
22 ACE_TEXT (" reference_cont_ = %d\n")
23 ACE_TEXT (" token_name_ = %s\n"),
24 reference_count_, token_name_));
25 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("waiters_\n")));
26 this->waiters_.dump ();
27 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
28 #endif /* ACE_HAS_DUMP */
31 ACE_Tokens::ACE_Tokens ()
32 : visited_ (0),
33 reference_count_ (0)
35 ACE_TRACE ("ACE_Tokens::ACE_Tokens");
38 void
39 ACE_Tokens::make_owner (ACE_TPQ_Entry *caller)
41 this->waiters_.remove (caller);
42 this->waiters_.enqueue (caller, 0);
45 ACE_Token_Proxy_Queue *
46 ACE_Tokens::waiters ()
48 ACE_TRACE ("ACE_Tokens::waiters");
49 return &this->waiters_;
52 int
53 ACE_Tokens::no_of_waiters ()
55 ACE_TRACE ("ACE_Tokens::no_of_waiters");
56 return this->waiters_.size ();
59 void
60 ACE_TPQ_Entry::dump () const
62 #if defined (ACE_HAS_DUMP)
63 ACE_TRACE ("ACE_TPQ_Entry::dump");
64 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
65 ACELIB_DEBUG ((LM_DEBUG,
66 ACE_TEXT ("ACE_TPQ_Entry::dump:\n")
67 ACE_TEXT (" nesting_level_ = %d\n")
68 ACE_TEXT (" client_id_ = %s\n"),
69 nesting_level_,
70 client_id_));
72 if (next_ != 0)
74 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("next:.\n")));
75 next_->dump ();
78 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_TPQ_Entry::dump end.\n")));
79 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
80 #endif /* ACE_HAS_DUMP */
83 ACE_TPQ_Entry::ACE_TPQ_Entry (const ACE_Token_Proxy *new_proxy,
84 const ACE_TCHAR *client_id)
85 : cond_var_ (lock_),
86 next_ (0),
87 // This const typecast is safe.
88 proxy_ ((ACE_Token_Proxy *) new_proxy),
89 nesting_level_ (0),
90 sleep_hook_ (0)
92 ACE_TRACE ("ACE_TPQ_Entry::ACE_TPQ_Entry");
94 if (client_id != 0)
95 this->client_id (client_id);
96 else
98 // Just make sure we have enough space.
99 ACE_TCHAR host_name[MAXHOSTNAMELEN];
100 ACE_TCHAR name[(sizeof host_name / sizeof (ACE_TCHAR)) + 256];
101 ACE_OS::hostname (host_name, sizeof host_name);
103 ACE_thread_t thread_id = ACE_Thread::self ();
105 // The cast is an attempt to get this to compile (and run,
106 // hopefully) regardless of the type of ACE_thread_t.
107 ACE_OS::snprintf (name, sizeof name / sizeof name[0],
108 ACE_TEXT ("/%s/%u/%lu"),
109 host_name,
110 static_cast<u_int> (ACE_OS::getpid ()),
111 *reinterpret_cast<u_long *> (&thread_id));
113 this->client_id (name);
117 ACE_TPQ_Entry::ACE_TPQ_Entry ()
118 : cond_var_ (lock_),
119 proxy_ (0),
120 nesting_level_ (0),
121 sleep_hook_ (0)
123 ACE_TRACE ("ACE_TPQ_Entry::ACE_TPQ_Entry null const.");
126 ACE_TPQ_Entry::ACE_TPQ_Entry (const ACE_TPQ_Entry &rhs)
127 : cond_var_ (lock_)
129 ACE_TRACE ("ACE_TPQ_Entry::ACE_TPQ_Entry copy const.");
130 *this = rhs;
133 ACE_TPQ_Entry::~ACE_TPQ_Entry ()
135 ACE_TRACE ("ACE_TPQ_Entry::~ACE_TPQ_Entry");
138 void
139 ACE_TPQ_Entry::operator= (const ACE_TPQ_Entry& rhs)
141 ACE_TRACE ("ACE_TPQ_Entry::operator=");
142 if (&rhs == this)
143 return;
144 this->proxy_ = rhs.proxy ();
145 this->nesting_level_ = rhs.nesting_level ();
146 this->client_id (rhs.client_id ());
147 this->sleep_hook_ = rhs.sleep_hook ();
150 void
151 ACE_TPQ_Entry::client_id (const ACE_TCHAR *id)
153 ACE_TRACE ("ACE_TPQ_Entry::client_id");
155 if (id == 0)
156 return;
158 ACE_OS::strsncpy (this->client_id_,
159 (ACE_TCHAR *) id,
160 ACE_MAXCLIENTIDLEN);
163 void
164 ACE_TSS_TPQ_Entry::dump () const
166 #if defined (ACE_HAS_DUMP)
167 ACE_TRACE ("ACE_TSS_TPQ_Entry::dump");
168 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
169 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_TSS_TPQ_Entry::dump:\n")
170 ACE_TEXT (" client_id_ = %s\n"),
171 client_id_ == 0 ? ACE_TEXT ("0") : client_id_));
172 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("base:\n")));
173 ACE_TPQ_ENTRY::dump ();
174 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
175 #endif /* ACE_HAS_DUMP */
178 ACE_TSS_TPQ_Entry::ACE_TSS_TPQ_Entry (const ACE_Token_Proxy *proxy,
179 const ACE_TCHAR *client_id)
180 : proxy_ (proxy),
181 client_id_ (client_id)
183 ACE_TRACE ("ACE_TSS_TPQ_Entry::ACE_TSS_TPQ_Entry");
186 ACE_TPQ_Entry *
187 ACE_TSS_TPQ_Entry::make_TSS_TYPE () const
189 ACE_TRACE ("ACE_TSS_TPQ_Entry::make_TSS_TYPE");
190 ACE_TPQ_Entry *temp;
192 ACE_NEW_RETURN (temp,
193 ACE_TPQ_Entry (this->proxy_,
194 this->client_id_),
196 return temp;
199 ACE_TSS_TPQ_Entry::operator ACE_TPQ_Entry * ()
201 #if !defined (ACE_NO_TSS_TOKENS)
202 return (ACE_TPQ_Entry *) (*((ACE_TSS<ACE_TPQ_Entry> *) this));
203 #else
204 // Not sure this is the right thing to do, but it seems to work.
205 // The base class ALSO has a proxy_ and client_id_ members (weird?)
206 // which don't get initialised. The following two lines make this
207 // the same as the subclass, so that the slicing works .
208 ACE_TPQ_ENTRY::proxy ((ACE_Token_Proxy *)(this->proxy_));
209 ACE_TPQ_ENTRY::client_id (this->client_id_);
210 return (ACE_TPQ_Entry *) this;
211 #endif /* !ACE_NO_TSS_TOKENS */
214 ACE_TPQ_Iterator::ACE_TPQ_Iterator (ACE_Token_Proxy_Queue &q)
215 : current_ (q.head_)
217 ACE_TRACE ("ACE_TPQ_Iterator::ACE_TPQ_Iterator");
221 ACE_TPQ_Iterator::next (ACE_TPQ_Entry *&next_item)
223 ACE_TRACE ("ACE_TPQ_Iterator::next");
225 next_item = this->current_;
227 return current_ != 0;
231 ACE_TPQ_Iterator::done () const
233 ACE_TRACE ("ACE_TPQ_Iterator::done");
235 return this->current_ == 0;
238 void
239 ACE_TPQ_Iterator::advance ()
241 ACE_TRACE ("ACE_TPQ_Iterator::advance");
243 if (current_ != 0)
244 this->current_ = this->current_->next_;
247 void
248 ACE_TPQ_Iterator::dump () const
250 #if defined (ACE_HAS_DUMP)
251 ACE_TRACE ("ACE_TPQ_Iterator::dump");
252 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
253 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_TPQ_Iterator::dump:\n")
254 ACE_TEXT (" current_ = %d\n"),
255 (long) this->current_));
256 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("head_ and tail_\n")));
257 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
258 #endif /* ACE_HAS_DUMP */
261 void
262 ACE_Token_Proxy_Queue::dump () const
264 #if defined (ACE_HAS_DUMP)
265 ACE_TRACE ("ACE_Token_Proxy_Queue::dump");
266 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
267 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Token_Proxy_Queue::dump:\n")
268 ACE_TEXT (" size_ = %d\n"),
269 size_));
270 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("head_ and tail_\n")));
271 if (this->head_ != 0)
272 this->head_->dump ();
274 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Token_Proxy_Queue::dump end.\n")));
275 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
276 #endif /* ACE_HAS_DUMP */
279 ACE_Token_Proxy_Queue::ACE_Token_Proxy_Queue ()
280 : head_ (0),
281 tail_ (0),
282 size_ (0)
284 ACE_TRACE ("ACE_Token_Proxy_Queue::ACE_Token_Proxy_Queue");
287 void
288 ACE_Token_Proxy_Queue::enqueue (ACE_TPQ_Entry *tpq,
289 int position)
291 ACE_TRACE ("ACE_Token_Proxy_Queue::enqueue");
292 tpq->next_ = 0;
294 ++this->size_;
296 if (this->head_ == 0)
298 // make tpq the entire list
299 this->head_ = this->tail_ = tpq;
300 return;
303 if (position == 0)
305 // make head of list
306 tpq->next_ = this->head_;
307 this->head_ = tpq;
308 return;
311 if (position == -1)
313 // stick at back of list
314 this->tail_->next_ = tpq;
315 this->tail_ = tpq;
316 return;
319 // walk through list to insertion point
320 ACE_TPQ_Entry *temp = head_;
322 for (int x = position;
323 x > 1;
324 --x)
326 // end of queue?
327 if (temp->next_ == 0)
328 break;
329 // advance pointer
330 else
331 temp = temp->next_;
334 // insert new tpq after temp
335 tpq->next_ = temp->next_;
336 temp->next_ = tpq;
339 void
340 ACE_Token_Proxy_Queue::dequeue ()
342 ACE_TRACE ("ACE_Token_Proxy_Queue::dequeue");
344 if (head_ == 0)
345 return;
347 ACE_TPQ_Entry *temp = this->head_;
349 this->head_ = this->head_->next_;
351 temp->next_ = 0;
353 --this->size_;
355 if (this->head_ == 0 && this->size_ != 0)
356 ACELIB_ERROR ((LM_ERROR,
357 ACE_TEXT ("incorrect size = %d\n"),
358 this->size_));
363 ACE_Token_Proxy_Queue::member (const ACE_TCHAR *id)
365 ACE_TRACE ("ACE_Token_Proxy_Queue::member");
367 for (ACE_TPQ_Entry *temp = this->head_;
368 temp != 0;
369 temp = temp->next_)
370 if (ACE_OS::strcmp (temp->client_id (), id) == 0)
371 // We found it!
372 return 1;
374 // We didn't find it :-(
375 return 0;
379 void
380 ACE_Token_Proxy_Queue::remove (const ACE_TPQ_Entry *remove_me)
382 ACE_TRACE ("ACE_Token_Proxy_Queue::remove");
383 // sanity
384 if ((remove_me == 0) || (this->head_ == 0))
385 return;
387 // is it the head?
388 if (this->head_ == remove_me) // pointer comparison.
390 this->head_ = this->head_->next_;
391 if (this->head_ == 0)
392 this->tail_ = 0;
394 --this->size_;
395 return;
398 ACE_TPQ_Entry *temp = this->head_;
399 ACE_TPQ_Entry *previous = 0;
401 // is it in the middle or tail?
402 while (temp != 0)
404 if (temp == remove_me)
406 // previous should never be null since the first if
407 // conditional should always be false
408 previous->next_ = temp->next_;
409 // is it the tail?
410 if (this->tail_ == temp)
411 this->tail_ = previous;
413 --this->size_;
414 return;
417 previous = temp;
418 temp = temp->next_;
421 // it wasn't in the list.
422 return;
425 void
426 ACE_Mutex_Token::dump () const
428 #if defined (ACE_HAS_DUMP)
429 ACE_TRACE ("ACE_Mutex_Token::dump");
430 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
431 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Mutex_Token::dump:\n")));
432 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("lock_\n")));
433 lock_.dump ();
434 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("base:\n")));
435 ACE_Tokens::dump ();
436 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Mutex_Token::dump end.\n")));
437 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
438 #endif /* ACE_HAS_DUMP */
441 ACE_Mutex_Token::ACE_Mutex_Token (const ACE_TCHAR *name)
443 ACE_TRACE ("ACE_Mutex_Token::ACE_Mutex_Token");
445 ACE_OS::strsncpy (this->token_name_,
446 name,
447 ACE_MAXTOKENNAMELEN);
450 ACE_Mutex_Token::~ACE_Mutex_Token ()
452 ACE_TRACE ("ACE_Mutex_Token::~ACE_Mutex_Token");
456 ACE_Mutex_Token::acquire (ACE_TPQ_Entry *caller,
457 int ignore_deadlock,
458 int notify)
460 ACE_TRACE ("ACE_Mutex_Token::acquire");
461 // We need to acquire two locks. This one to ensure that only one
462 // thread uses this token at a time.
463 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
464 // This one to ensure an atomic transaction across all tokens. Note
465 // that this order is crucial too. It's resource coloring for other
466 // threads which may be calling this same token.
467 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1);
469 // Does _anyone_ own the token?
470 if (this->owner () == 0)
472 // there are no waiters, so queue as the first waiter (the owner.)
473 this->waiters_.enqueue (caller, -1);
474 return 0; // success
477 // Does the caller already own it?
478 if (this->is_owner (caller->client_id ()))
480 // Recursive acquisition.
481 caller->nesting_level (1);
482 return 0; // success
485 // Check for deadlock.
486 if (!ignore_deadlock
487 && ACE_Token_Manager::instance ()->check_deadlock (caller->proxy ()) == 1)
489 errno = EDEADLK;
490 ACE_RETURN (-1);
493 // Someone owns it. Sorry, you're getting queued up at the end of
494 // the waiter queue.
495 this->waiters_.enqueue (caller, -1);
497 if (notify)
498 this->owner ()->call_sleep_hook ();
500 errno = EWOULDBLOCK;
501 ACE_RETURN (-1);
503 ACE_NOTREACHED (return -1);
507 ACE_Mutex_Token::tryacquire (ACE_TPQ_Entry *caller)
509 ACE_TRACE ("ACE_Mutex_Token::tryacquire");
510 // We need to acquire two locks. This one to ensure that only one
511 // thread uses this token at a time.
512 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
513 // This one to ensure an atomic transaction across all tokens. Note
514 // that this order is crucial too. It's resource coloring for other
515 // threads which may be calling this same token.
516 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1);
518 // Does _anyone_ own the token?
519 if (this->owner () == 0)
521 this->waiters_.enqueue (caller, -1);
522 return 0; // success
524 // Does the caller already own it?
525 if (this->is_owner (caller->client_id ()))
527 // recursive acquisition
528 caller->nesting_level (1);
529 return 0; // success
531 else
532 // Someone owns it. Fail.
534 errno = EWOULDBLOCK;
535 ACE_RETURN (-1);
538 ACE_NOTREACHED (return -1);
542 ACE_Mutex_Token::renew (ACE_TPQ_Entry *caller,
543 int requeue_position)
545 ACE_TRACE ("ACE_Mutex_Token::renew");
546 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1);
548 // Verify that the caller is the owner.
549 if (this->is_owner (caller->client_id ()) == 0)
551 errno = EACCES;
552 ACE_RETURN (-1);
555 // The caller is the owner, so check to see if there are any
556 // waiters. If not, we just keep the token. == 1 means that there
557 // is only the owner.
558 if (this->waiters_.size () == 1 || requeue_position == 0)
559 return 0;
561 // Requeue the caller.
562 this->waiters_.dequeue ();
564 this->waiters_.enqueue (caller, requeue_position);
566 // Notify new owner.
567 if (this->owner () != 0)
568 this->owner ()->proxy ()->token_acquired (this->owner ());
570 // Tell the caller that the operation would block.
571 errno = EWOULDBLOCK;
572 ACE_RETURN (-1);
574 ACE_NOTREACHED (return -1);
577 // Release the current holder of the token (which had
578 // better be the caller's thread!).
581 ACE_Mutex_Token::release (ACE_TPQ_Entry *caller)
583 ACE_TRACE ("ACE_Mutex_Token::release");
584 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1);
586 // Does anyone own the token?
587 if (this->owner () == 0)
589 errno = EACCES;
590 ACE_RETURN (-1);
593 // Is the caller the owner.
594 if (this->is_owner (caller->client_id ()))
596 // Check the nesting level.
597 if (caller->nesting_level () > 0)
598 caller->nesting_level (-1);
599 else
601 this->waiters_.dequeue ();
602 // Notify new owner.
603 if (this->owner () != 0)
604 this->owner ()->proxy ()->token_acquired (this->owner ());
607 else
608 this->remove (caller);
610 return 0;
614 ACE_Mutex_Token::owners (OWNER_STACK &stack,
615 const ACE_TCHAR *id)
617 ACE_TRACE ("ACE_Mutex_Token::owners");
618 if (this->owner () != 0)
620 stack.push (this->owner ());
621 // If an <id> is specified, return whether it is the owner being
622 // returned.
623 if (id != 0)
624 return this->owner ()->equal_client_id (id);
627 return 0;
631 ACE_Mutex_Token::is_waiting_for (const ACE_TCHAR *id)
633 ACE_TRACE ("ACE_Mutex_Token::is_waiting_for");
634 // If there is no owner, or <id> is the owner, return false.
635 if ((this->owner () == 0) || this->is_owner (id))
636 return 0;
638 // Step through each waiter looking for <id>.
639 ACE_TPQ_Iterator iterator (waiters_);
640 iterator.advance ();
641 for (ACE_TPQ_Entry *temp = 0;
642 iterator.next (temp) != 0;
643 iterator.advance ())
645 if (temp->equal_client_id (id))
646 return 1;
649 return 0;
653 ACE_Mutex_Token::is_owner (const ACE_TCHAR *id)
655 ACE_TRACE ("ACE_Mutex_Token::is_owner");
656 // If there is an owner, return whether it is <id>.
657 if ((this->owner () != 0) &&
658 this->owner ()->equal_client_id (id))
659 return 1;
660 else
661 return 0;
665 ACE_Mutex_Token::type () const
667 ACE_TRACE ("ACE_Mutex_Token::type");
668 return (int) ACE_Tokens::MUTEX;
671 // ************************************************************
674 ACE_RW_Token::type () const
676 ACE_TRACE ("ACE_RW_Token::type");
677 return (int) ACE_Tokens::RWLOCK;
680 void
681 ACE_RW_Token::dump () const
683 #if defined (ACE_HAS_DUMP)
684 ACE_TRACE ("ACE_RW_Token::dump");
685 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
686 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_RW_Token::dump:\n")
687 ACE_TEXT ("num_writers_ = %d\n"), num_writers_));
688 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("lock_\n")));
689 this->lock_.dump ();
690 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("base:\n")));
691 ACE_Tokens::dump ();
692 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_RW_Token::dump end.\n")));
693 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
694 #endif /* ACE_HAS_DUMP */
697 ACE_RW_Token::ACE_RW_Token (const ACE_TCHAR *name)
698 : num_writers_ (0)
700 ACE_TRACE ("ACE_RW_Token::ACE_RW_Token");
702 ACE_OS::strsncpy (this->token_name_,
703 name,
704 ACE_MAXTOKENNAMELEN);
707 ACE_RW_Token::~ACE_RW_Token ()
709 ACE_TRACE ("ACE_RW_Token::~ACE_RW_Token");
713 ACE_RW_Token::acquire (ACE_TPQ_Entry *caller,
714 int ignore_deadlock,
715 int notify)
717 ACE_TRACE ("ACE_RW_Token::acquire");
718 // We need to acquire two locks. This one to ensure that only one
719 // thread uses this token at a time.
720 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
721 // This one to ensure an atomic transaction across all tokens. Note
722 // that this order is crucial too. It's resource coloring for other
723 // threads which may be calling this same token.
724 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1);
726 if (caller->proxy ()->type () == ACE_RW_Token::WRITER)
727 this->num_writers_++;
729 // Does _anyone_ own the token?
730 if (this->owner () == 0)
732 // There are no waiters, so queue as the first waiter (the owner).
733 this->waiters_.enqueue (caller, -1);
734 return 0;
737 // Check for recursive acquisition.
738 if (this->is_owner (caller->client_id ()))
740 caller->nesting_level (1);
741 return 0; // Success.
744 // Reader.
745 if (caller->proxy ()->type () == ACE_RW_Token::READER)
747 // Are there any writers?
748 if (this->num_writers_ == 0)
750 // Queue the caller at the end of the queue.
751 this->waiters_.enqueue (caller, -1);
752 return 0;
754 // Else failure.
757 // Failure code.
759 // Check for deadlock.
760 if (!ignore_deadlock &&
761 ACE_Token_Manager::instance ()->check_deadlock (caller->proxy ()) == 1)
763 if (caller->proxy ()->type () == ACE_RW_Token::WRITER)
764 this->num_writers_--;
765 errno = EDEADLK;
766 ACE_RETURN (-1);
769 // Queue the caller at the end of the queue.
770 this->waiters_.enqueue (caller, -1);
772 if (notify)
774 // If it's a writer, just notify it.
775 if (this->owner ()->proxy ()->type () == ACE_RW_Token::WRITER)
776 this->owner ()->call_sleep_hook ();
777 else
779 // Call back all reader owners.
780 ACE_TPQ_Entry *temp = this->owner ();
783 temp->call_sleep_hook ();
784 temp = temp->next_;
786 while (temp != 0 &&
787 temp->proxy ()->type () == ACE_RW_Token::READER);
791 errno = EWOULDBLOCK;
792 ACE_RETURN (-1);
794 ACE_NOTREACHED (return -1);
798 ACE_RW_Token::tryacquire (ACE_TPQ_Entry *caller)
800 ACE_TRACE ("ACE_RW_Token::tryacquire");
801 // We need to acquire two locks. This one to ensure that only one
802 // thread uses this token at a time.
803 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
804 // This one to ensure an atomic transaction across all tokens. Note
805 // that this order is crucial too. It's resource coloring for other
806 // threads which may be calling this same token.
807 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1);
809 if (caller->proxy ()->type () == ACE_RW_Token::WRITER)
811 this->num_writers_++;
814 // Does _anyone_ own the token?
815 if (this->owner () == 0)
817 // There are no waiters, so queue as the first waiter (the owner).
818 this->waiters_.enqueue (caller, -1);
819 return 0;
822 // Check for recursive acquisition.
823 if (this->is_owner (caller->client_id ()))
825 caller->nesting_level (1);
826 return 0; // Success.
829 // Reader.
830 if (caller->proxy ()->type () == ACE_RW_Token::READER)
832 // Are there any writers?
833 if (this->num_writers_ == 0)
835 // queue the caller at the end of the queue.
836 this->waiters_.enqueue (caller, -1);
837 return 0;
839 // Else, fail.
841 else // Writer.
842 // We're going to fail, so decrement the num_writers.
844 this->num_writers_--;
848 errno = EWOULDBLOCK;
849 ACE_RETURN (-1);
851 ACE_NOTREACHED (return -1);
855 ACE_RW_Token::renew (ACE_TPQ_Entry *caller,
856 int requeue_position)
858 ACE_TRACE ("ACE_RW_Token::renew");
859 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1);
861 // Werify that the caller is the owner
862 if (this->is_owner (caller->client_id ()) == 0)
864 errno = EACCES;
865 ACE_RETURN (-1);
868 // The caller is the owner, so check to see if there are any
869 // waiters. If not, we just keep the token.
870 if (this->waiters_.size () == 1 || requeue_position == 0)
871 return 0;
873 // There are waiters, so remove the caller.
874 this->remove (caller);
876 // Requeue the caller.
877 this->waiters_.enqueue (caller, requeue_position);
879 if (caller->proxy ()->type () == ACE_RW_Token::READER)
881 // If the caller got queued before any writers, the caller is
882 // still the owner.
883 if (this->is_owner (caller->client_id ()))
884 return 0; // success
885 // else fallthrough and return would block.
887 // Writers will always have to block since waiters_.size () == 1 or
888 // requeue_position == 0.
890 // Get a new owner.
891 this->notify_new_owner (caller);
893 // Tell the caller that the operation would block.
894 errno = EWOULDBLOCK;
895 ACE_RETURN (-1);
897 ACE_NOTREACHED (return -1);
901 ACE_RW_Token::release (ACE_TPQ_Entry *caller)
903 ACE_TRACE ("ACE_RW_Token::release");
904 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1);
906 // Check for errors.
907 if ((this->owner () == 0) ||
908 (this->is_owner (caller->client_id ()) == 0))
910 errno = EACCES;
911 ACE_RETURN (-1);
914 if (caller->proxy ()->type () == ACE_RW_Token::WRITER)
915 num_writers_--;
917 // Recursive release.
918 if (caller->nesting_level () > 0)
920 caller->nesting_level (-1);
921 return 0;
924 // Remove the caller and notify the new owner(s).
925 this->remove (caller);
926 this->notify_new_owner (caller);
928 return 0;
931 void
932 ACE_RW_Token::notify_new_owner (ACE_TPQ_Entry *old_owner)
934 ACE_TRACE ("ACE_RW_Token::notify_new_owner");
936 if (this->owner () == 0)
937 return;
939 if (this->owner ()->proxy ()->type () == ACE_RW_Token::READER)
941 if (old_owner->proxy ()->type () == ACE_RW_Token::READER)
942 // the owners already know that they're owners
943 return;
945 // The current owner is a reader and the previous owner was a
946 // writer, so notify all waiting readers up to the first writer.
947 // call back all reader owners.
948 ACE_TPQ_Iterator iterator (waiters_);
949 for (ACE_TPQ_Entry *temp = 0;
950 iterator.next (temp) != 0;
951 iterator.advance ())
953 if (temp->proxy ()->type () == WRITER)
954 // We've gone through all the readers.
955 break;
957 temp->proxy ()->token_acquired (temp);
960 else // writer
961 this->owner ()->proxy ()->token_acquired (this->owner ());
966 ACE_RW_Token::owners (OWNER_STACK &stack,
967 const ACE_TCHAR *id)
969 ACE_TRACE ("ACE_RW_Token::owners");
971 if (this->owner () == 0)
972 return 0;
974 int id_is_owner = 0;
976 // The first waiter is a writer, so there is only one owner.
977 if (this->owner ()->proxy ()->type () == WRITER)
979 stack.push (this->owner ());
980 // If an <id> is specified, return whether it is the owner being
981 // returned.
982 if ((id != 0) &&
983 (ACE_OS::strcmp (id, this->owner ()->client_id ()) == 0))
984 id_is_owner = 1;
986 // The first waiter is a reader, so there can be multiple owning
987 // readers.
988 else
990 ACE_TPQ_Iterator iterator (waiters_);
991 for (ACE_TPQ_Entry *temp = 0;
992 iterator.next (temp) != 0;
993 iterator.advance ())
995 if (temp->proxy ()->type () == WRITER)
996 // We've gone through all the readers.
997 break;
999 stack.push (temp);
1001 if (!id_is_owner && (id != 0) &&
1002 (ACE_OS::strcmp (id, temp->client_id ()) == 0))
1003 id_is_owner = 1;
1007 return id_is_owner;
1011 ACE_RW_Token::is_waiting_for (const ACE_TCHAR *id)
1013 ACE_TRACE ("ACE_RW_Token::is_waiting_for");
1014 // If there is no owner, or <id> is the owner, return false.
1015 if ((this->owner () == 0) ||
1016 this->is_owner (id))
1017 return 0;
1019 // Step through each waiter looking for <id>.
1020 ACE_TPQ_Iterator iterator (waiters_);
1021 iterator.advance ();
1022 for (ACE_TPQ_Entry *temp = 0;
1023 iterator.next (temp) != 0;
1024 iterator.advance ())
1026 if (temp->equal_client_id (id))
1027 return 1;
1030 return 0;
1034 ACE_RW_Token::is_owner (const ACE_TCHAR *id)
1036 ACE_TRACE ("ACE_RW_Token::is_owner");
1037 // If there is no owner, return false.
1038 if (this->owner () == 0)
1039 return 0;
1041 // A writer owns us.
1042 if (this->owner ()->proxy ()->type () == ACE_RW_Token::WRITER)
1043 return this->owner ()->equal_client_id (id);
1045 // Readers own us.
1046 // Step through each owning reader looking for <id>.
1047 ACE_TPQ_Iterator iterator (waiters_);
1048 for (ACE_TPQ_Entry *temp = 0;
1049 iterator.next (temp) != 0;
1050 iterator.advance ())
1052 if (temp->proxy ()->type () != ACE_RW_Token::READER)
1053 break;
1055 if (temp->equal_client_id (id))
1056 return 1;
1059 return 0;
1062 void
1063 ACE_Token_Proxy::dump () const
1065 #if defined (ACE_HAS_DUMP)
1066 ACE_TRACE ("ACE_Token_Proxy::dump");
1067 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
1068 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Token_Proxy::dump:\n")
1069 ACE_TEXT (" type = %d\n")
1070 ACE_TEXT (" ignore_deadlock_ = %d\n")
1071 ACE_TEXT (" debug_ = %d\n"),
1072 (int) this->type (), ignore_deadlock_, debug_));
1073 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("mutex_, and waiter_\n")));
1075 if (this->token_ != 0)
1076 this->token_->dump ();
1078 this->waiter_.dump ();
1079 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Token_Proxy::dump end.\n")));
1080 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
1081 #endif /* ACE_HAS_DUMP */
1084 const ACE_TCHAR *
1085 ACE_Token_Proxy::client_id () const
1087 ACE_TRACE ("ACE_Token_Proxy::client_id");
1088 // Thread-specific.
1089 const ACE_TPQ_Entry *temp = this->waiter_.operator->();
1090 const ACE_TCHAR *id = temp->client_id ();
1092 if (id == 0)
1093 return ACE_TEXT ("ERROR NO CLIENT ID");
1094 else
1095 return id;
1098 void
1099 ACE_Token_Proxy::client_id (const ACE_TCHAR *client_id)
1101 ACE_TRACE ("ACE_Token_Proxy::client_id");
1102 this->waiter_->client_id (client_id);
1105 const ACE_TCHAR *
1106 ACE_Token_Proxy::owner_id ()
1108 ACE_TRACE ("ACE_Token_Proxy::owner_id");
1109 return this->token_->owner_id ();
1112 const ACE_TCHAR *
1113 ACE_Token_Proxy::name () const
1115 ACE_TRACE ("ACE_Token_Proxy::name");
1116 return this->token_->name ();
1119 #if defined (_MSC_VER)
1120 # pragma warning (push)
1121 # pragma warning (disable:4355) /* Use of 'this' in initializer list */
1122 #endif
1123 ACE_Token_Proxy::ACE_Token_Proxy ()
1124 : token_ (0),
1125 waiter_ (this, 0)
1127 ACE_TRACE ("ACE_Token_Proxy::ACE_Token_Proxy");
1130 // Notice the token_ (0). Do *not* copy the token pointer. This must
1131 // be obtained through the token manager. Also, we don't copy any
1132 // waiter info. A copied Proxy does *not* inherit client_id.
1134 ACE_Token_Proxy::ACE_Token_Proxy (const ACE_Token_Proxy &)
1135 : token_ (0),
1136 waiter_ (this, 0)
1138 ACE_TRACE ("ACE_Token_Proxy::ACE_Token_Proxy");
1140 #if defined (_MSC_VER)
1141 # pragma warning (pop)
1142 #endif
1144 // @@ should I do a mutex_->release ()?
1145 ACE_Token_Proxy::~ACE_Token_Proxy ()
1147 ACE_TRACE ("ACE_Token_Proxy::~ACE_Token_Proxy");
1149 if (token_ != 0)
1150 // notify token manager that we are done with it so it can
1151 // free it if necessary
1152 ACE_Token_Manager::instance ()->release_token (token_);
1156 ACE_Token_Proxy::open (const ACE_TCHAR *token_name,
1157 int ignore_deadlock,
1158 int debug)
1160 ACE_TRACE ("ACE_Token_Proxy::open");
1162 // Store some parameters.
1163 this->ignore_deadlock_ = ignore_deadlock;
1164 this->debug_ = debug;
1166 // Used in case a name was not specified.
1167 ACE_TCHAR name[BUFSIZ];
1169 // We must have a name.
1170 if (token_name == 0)
1172 ACE_OS::snprintf (name, BUFSIZ, ACE_TEXT ("token %lx"),
1173 reinterpret_cast<long> (this));
1174 token_name = name;
1177 // Get or create the underlying token. The Token Manager will call
1178 // us back to set token_.
1179 ACE_Token_Manager::instance ()->get_token (this, token_name);
1181 // Check for failed get or failed new.
1182 if (this->token_ == 0)
1184 errno = ENOMEM;
1185 ACELIB_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("Can't allocate mutex")), -1);
1188 return 0;
1192 ACE_Token_Proxy::acquire (int notify,
1193 void (*sleep_hook)(void *),
1194 ACE_Synch_Options &options)
1196 ACE_TRACE ("ACE_Token_Proxy::acquire");
1197 if (this->token_ == 0)
1199 errno = ENOENT;
1200 ACELIB_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("Not open.\n")), -1);
1203 // Make sure no one calls our token_acquired until we have a chance
1204 // to sleep first! If after we call an EWOULDBLOCK
1205 // mutex_->acquire() below, but before we enter handle_options to
1206 // wait on the cond_var, a thread tries to give take us off the
1207 // waiter queue and signal us, IT WILL FIRST HAVE TO ACQUIRE THIS
1208 // cond_var.mutex (). _This_ is why we acquire it.
1209 this->waiter_->cond_var_.mutex ().acquire ();
1211 this->waiter_->sleep_hook (sleep_hook);
1213 if (this->token_->acquire (this->waiter_, this->ignore_deadlock_, notify) == -1)
1214 // acquire failed
1216 switch (errno)
1218 case EDEADLK :
1219 if (!ignore_deadlock_)
1221 waiter_->cond_var_.mutex ().release ();
1222 errno = EDEADLK;
1223 ACE_RETURN (-1);
1225 // Else, fallthrough and block!
1226 ACE_FALLTHROUGH;
1228 case EWOULDBLOCK :
1229 if (this->debug_)
1230 ACELIB_DEBUG ((LM_DEBUG,
1231 ACE_TEXT ("(%t) waiting for %s, owner is %s, ")
1232 ACE_TEXT ("total waiters == %d\n"),
1233 this->name (),
1234 this->token_->owner_id (),
1235 token_->no_of_waiters ()));
1237 // no error, but would block, if error, return error (-1),
1238 // otherwise, return whether we called the holder or not.
1239 int return_value;
1240 if (this->handle_options (options,
1241 waiter_->cond_var_) == -1)
1242 return_value = -1;
1243 else
1244 return_value = notify == 1;
1246 errno = EWOULDBLOCK;
1247 ACE_RETURN (return_value);
1249 default :
1250 waiter_->cond_var_.mutex ().release ();
1251 ACELIB_ERROR_RETURN ((LM_ERROR,
1252 ACE_TEXT ("%p\n"),
1253 ACE_TEXT ("Token Proxy acquire.")),
1254 -1);
1257 else
1258 // we have the token
1260 if (debug_)
1261 ACELIB_DEBUG ((LM_DEBUG,
1262 ACE_TEXT ("(%t) acquired %s\n"),
1263 this->name ()));
1264 waiter_->cond_var_.mutex ().release ();
1267 return 0;
1271 ACE_Token_Proxy::tryacquire (void (*sleep_hook)(void *))
1273 ACE_TRACE ("ACE_Token_Proxy::tryacquire");
1274 if (this->token_ == 0)
1276 errno = ENOENT;
1277 ACELIB_ERROR_RETURN ((LM_ERROR,
1278 ACE_TEXT ("Not open.\n")),
1279 -1);
1282 this->waiter_->sleep_hook (sleep_hook);
1284 return this->token_->tryacquire (waiter_);
1288 ACE_Token_Proxy::renew (int requeue_position,
1289 ACE_Synch_Options &options)
1291 ACE_TRACE ("ACE_Token_Proxy::renew");
1292 if (this->token_ == 0)
1294 errno = ENOENT;
1295 ACELIB_ERROR_RETURN ((LM_ERROR,
1296 ACE_TEXT ("Not open.\n")),
1297 -1);
1300 // Make sure no one calls our token_acquired until we have a chance
1301 // to sleep first!
1302 this->waiter_->cond_var_.mutex ().acquire ();
1304 if (this->token_->renew (this->waiter_, requeue_position) == -1)
1306 // check for error
1307 if (errno != EWOULDBLOCK)
1308 ACELIB_ERROR_RETURN ((LM_ERROR,
1309 ACE_TEXT ("%p renew failed\n"), ACE_TEXT ("ACE_Token_Proxy")), -1);
1311 if (this->debug_)
1312 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) renew blocking for %s, owner is %s\n"),
1313 this->name (),
1314 token_->owner_id ()));
1316 // no error, but would block, so block or return
1317 return this->handle_options (options, waiter_->cond_var_);
1319 else
1320 // we have the token
1322 if (this->debug_)
1323 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) renewed %s\n"),
1324 this->name ()));
1325 waiter_->cond_var_.mutex ().release ();
1326 return 0;
1331 ACE_Token_Proxy::handle_options (ACE_Synch_Options &options,
1332 ACE_TOKEN_CONST::COND_VAR &cv)
1334 // Some operation failed with EWOULDBLOCK.
1335 ACE_TRACE ("ACE_Token_Proxy::handle_options");
1337 if (options[ACE_Synch_Options::USE_REACTOR] == 1)
1338 // Asynchronous.
1340 // Save/restore errno.
1341 ACE_Errno_Guard error (errno);
1342 cv.mutex ().release ();
1343 ACE_RETURN (-1);
1345 else
1346 // Synchronous.
1348 // Block on condition variable.
1349 while (cv.wait ((ACE_Time_Value *) options.time_value ()) == -1)
1351 // Note, this should obey whatever thread-specific
1352 // interrupt policy is currently in place...
1353 if (errno == EINTR)
1354 continue;
1355 // We come here if a timeout occurs or some serious
1356 // ACE_Condition object error.
1357 cv.mutex ().release ();
1358 ACELIB_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("condition variable wait")
1359 ACE_TEXT (" bombed.")), -1);
1362 if (this->debug_)
1363 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) unblocking %s.\n"),
1364 this->client_id ()));
1365 cv.mutex ().release ();
1366 return 0; // operation succeeded
1371 ACE_Token_Proxy::release (ACE_Synch_Options &)
1373 ACE_TRACE ("ACE_Token_Proxy::release");
1375 if (this->token_ == 0)
1377 errno = ENOENT;
1378 if (debug_)
1379 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("Must open before releasing.\n")));
1380 ACE_RETURN (-1);
1383 if (this->token_->release (waiter_) != 0)
1385 // Release failed.
1386 this->token_->remove (this->waiter_);
1387 if (debug_)
1388 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) %p.\n"), ACE_TEXT ("release failed")));
1389 return -1;
1391 else
1393 if (this->debug_)
1394 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) released %s, owner is %s\n"),
1395 this->name (),
1396 token_->owner_id ()));
1398 return 0;
1403 ACE_Token_Proxy::remove (ACE_Synch_Options &)
1405 ACE_TRACE ("ACE_Token_Proxy::remove");
1406 return 0;
1409 void
1410 ACE_Token_Proxy::sleep_hook ()
1412 ACE_TRACE ("ACE_Token_Proxy::sleep_hook");
1413 // Somebody wants our token! (Let'em wait...)
1414 return;
1417 void
1418 ACE_Token_Proxy::token_acquired (ACE_TPQ_Entry *e)
1420 ACE_TRACE ("ACE_Token_Proxy::token_acquired");
1421 e->cond_var_.mutex ().acquire ();
1422 // We've been taken off the waiters list and given the token!
1423 // This implementation signals the internal condition
1424 // variable. Thus, if asynchronous acquires are used, this must be
1425 // overriden to do something more useful!
1426 e->cond_var_.signal ();
1427 e->cond_var_.mutex ().release ();
1429 return;
1433 ACE_Token_Proxy::type () const
1435 ACE_TRACE ("ACE_Token_Proxy::type");
1436 return 0;
1440 ACE_Token_Proxy::acquire_read (int notify,
1441 void (*sleep_hook)(void *),
1442 ACE_Synch_Options &options)
1444 return this->acquire (notify,
1445 sleep_hook,
1446 options);
1450 ACE_Token_Proxy::acquire_write (int notify,
1451 void (*sleep_hook)(void *),
1452 ACE_Synch_Options &options)
1454 return this->acquire (notify,
1455 sleep_hook,
1456 options);
1460 ACE_Token_Proxy::tryacquire_read (void (*sleep_hook)(void *))
1462 return this->tryacquire (sleep_hook);
1466 ACE_Token_Proxy::tryacquire_write (void (*sleep_hook)(void *))
1468 return this->tryacquire (sleep_hook);
1471 ACE_Token_Name::ACE_Token_Name (const ACE_TCHAR *token_name)
1473 ACE_TRACE ("ACE_Token_Name::ACE_Token_Name");
1474 this->name (token_name);
1477 ACE_Token_Name::ACE_Token_Name (const ACE_Token_Name &rhs)
1479 ACE_TRACE ("ACE_Token_Name::ACE_Token_Name");
1480 this->name (rhs.name ());
1483 ACE_Token_Name::~ACE_Token_Name ()
1485 ACE_TRACE ("ACE_Token_Name::~ACE_Token_Name");
1488 void
1489 ACE_Token_Name::dump () const
1491 #if defined (ACE_HAS_DUMP)
1492 ACE_TRACE ("ACE_Token_Name::dump");
1493 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
1494 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Token_Name::dump:\n")
1495 ACE_TEXT (" token_name_ = %s\n"),
1496 token_name_ == 0 ? ACE_TEXT ("no name") : token_name_));
1497 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
1498 #endif /* ACE_HAS_DUMP */
1501 // ************************************************************
1503 ACE_Token_Proxy *
1504 ACE_Local_Mutex::clone () const
1506 ACE_Token_Proxy *temp = 0;
1507 ACE_NEW_RETURN (temp,
1508 ACE_Local_Mutex (token_->name (),
1509 ignore_deadlock_,
1510 debug_),
1512 return temp;
1515 ACE_Tokens *
1516 ACE_Local_Mutex::create_token (const ACE_TCHAR *name)
1518 ACE_Tokens *temp = 0;
1519 ACE_NEW_RETURN (temp,
1520 ACE_Mutex_Token (name),
1522 return temp;
1525 ACE_Local_Mutex::~ACE_Local_Mutex ()
1529 // ************************************************************
1531 ACE_Local_RLock::~ACE_Local_RLock ()
1535 ACE_Tokens *
1536 ACE_Local_RLock::create_token (const ACE_TCHAR *name)
1538 ACE_Tokens *temp = 0;
1539 ACE_NEW_RETURN (temp,
1540 ACE_RW_Token (name),
1542 return temp;
1546 ACE_Local_RLock::type () const
1548 return ACE_RW_Token::READER;
1551 ACE_Token_Proxy *
1552 ACE_Local_RLock::clone () const
1554 ACE_Token_Proxy *temp = 0;
1555 ACE_NEW_RETURN (temp,
1556 ACE_Local_RLock (token_->name (),
1557 ignore_deadlock_,
1558 debug_),
1560 return temp;
1563 // ************************************************************
1565 ACE_Local_WLock::~ACE_Local_WLock ()
1569 ACE_Tokens *
1570 ACE_Local_WLock::create_token (const ACE_TCHAR *name)
1572 ACE_Tokens *temp = 0;
1573 ACE_NEW_RETURN (temp,
1574 ACE_RW_Token (name),
1576 return temp;
1580 ACE_Local_WLock::type () const
1582 return ACE_RW_Token::WRITER;
1585 ACE_Token_Proxy *
1586 ACE_Local_WLock::clone () const
1588 ACE_Token_Proxy *temp = 0;
1589 ACE_NEW_RETURN (temp,
1590 ACE_Local_WLock (token_->name (),
1591 ignore_deadlock_,
1592 debug_),
1594 return temp;
1597 ACE_END_VERSIONED_NAMESPACE_DECL
1599 #endif /* ACE_HAS_TOKENS_LIBRARY */