00001 #include "ace_pch.h"
00002
00003
00004 #include "ace/Local_Tokens.h"
00005
00006 #if defined (ACE_HAS_TOKENS_LIBRARY)
00007
00008 #include "ace/Thread.h"
00009 #include "ace/Token_Manager.h"
00010
00011 #if !defined (__ACE_INLINE__)
00012 #include "ace/Local_Tokens.i"
00013 #endif
00014
00015
00016 ACE_RCSID(ace, Local_Tokens, "$Id: Local_Tokens.cpp,v 1.1.1.4.2.1 2003/03/13 19:44:21 chad Exp $")
00017
00018 void
00019 ACE_Tokens::dump (void) const
00020 {
00021 ACE_TRACE ("ACE_Tokens::dump");
00022 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00023 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_Tokens::dump:\n")
00024 ACE_LIB_TEXT (" reference_cont_ = %d\n")
00025 ACE_LIB_TEXT (" token_name_ = %s\n"),
00026 reference_count_, token_name_));
00027 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("waiters_\n")));
00028 this->waiters_.dump ();
00029 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00030 }
00031
00032 ACE_Tokens::ACE_Tokens (void)
00033 : visited_ (0),
00034 reference_count_ (0)
00035 {
00036 ACE_TRACE ("ACE_Tokens::ACE_Tokens");
00037 }
00038
00039 void
00040 ACE_Tokens::make_owner (ACE_TPQ_Entry *caller)
00041 {
00042 this->waiters_.remove (caller);
00043 this->waiters_.enqueue (caller, 0);
00044 }
00045
00046 #if defined (ACE_LACKS_INLINE_FUNCTIONS)
00047 ACE_Null_Token::ACE_Null_Token (void)
00048 {
00049 }
00050
00051 ACE_Null_Token::~ACE_Null_Token (void)
00052 {
00053 }
00054 #endif
00055
00056 void
00057 ACE_TPQ_Entry::dump (void) const
00058 {
00059 ACE_TRACE ("ACE_TPQ_Entry::dump");
00060 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00061 ACE_DEBUG ((LM_DEBUG,
00062 ACE_LIB_TEXT ("ACE_TPQ_Entry::dump:\n")
00063 ACE_LIB_TEXT (" nesting_level_ = %d\n")
00064 ACE_LIB_TEXT (" client_id_ = %s\n"),
00065 nesting_level_,
00066 client_id_));
00067
00068 if (next_ != 0)
00069 {
00070 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("next:.\n")));
00071 next_->dump ();
00072 }
00073
00074 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_TPQ_Entry::dump end.\n")));
00075 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00076 }
00077
00078 ACE_TPQ_Entry::ACE_TPQ_Entry (const ACE_Token_Proxy *new_proxy,
00079 const ACE_TCHAR *client_id)
00080 : cond_var_ (lock_),
00081 next_ (0),
00082
00083 proxy_ ((ACE_Token_Proxy *) new_proxy),
00084 nesting_level_ (0),
00085 sleep_hook_ (0)
00086 {
00087 ACE_TRACE ("ACE_TPQ_Entry::ACE_TPQ_Entry");
00088
00089 if (client_id != 0)
00090 this->client_id (client_id);
00091 else
00092 {
00093
00094 ACE_TCHAR host_name[MAXHOSTNAMELEN];
00095 ACE_TCHAR name[(sizeof host_name / sizeof (ACE_TCHAR)) + 256];
00096 ACE_OS::hostname (host_name, sizeof host_name);
00097
00098 ACE_thread_t thread_id = ACE_Thread::self ();
00099
00100
00101
00102 ACE_OS::sprintf (name,
00103 ACE_LIB_TEXT ("/%s/%u/%lu"),
00104 host_name,
00105 ACE_static_cast (u_int, ACE_OS::getpid ()),
00106 *ACE_reinterpret_cast (u_long *, &thread_id));
00107
00108 this->client_id (name);
00109 }
00110 }
00111
00112 ACE_TPQ_Entry::ACE_TPQ_Entry (void)
00113 : cond_var_ (lock_),
00114 proxy_ (0),
00115 nesting_level_ (0),
00116 sleep_hook_ (0)
00117 {
00118 ACE_TRACE ("ACE_TPQ_Entry::ACE_TPQ_Entry null const.");
00119 }
00120
00121 ACE_TPQ_Entry::ACE_TPQ_Entry (const ACE_TPQ_Entry &rhs)
00122 : cond_var_ (lock_)
00123 {
00124 ACE_TRACE ("ACE_TPQ_Entry::ACE_TPQ_Entry copy const.");
00125 *this = rhs;
00126 }
00127
00128 ACE_TPQ_Entry::~ACE_TPQ_Entry (void)
00129 {
00130 ACE_TRACE ("ACE_TPQ_Entry::~ACE_TPQ_Entry");
00131 }
00132
00133 void
00134 ACE_TPQ_Entry::operator= (const ACE_TPQ_Entry& rhs)
00135 {
00136 ACE_TRACE ("ACE_TPQ_Entry::operator=");
00137 if (&rhs == this)
00138 return;
00139 this->proxy_ = rhs.proxy ();
00140 this->nesting_level_ = rhs.nesting_level ();
00141 this->client_id (rhs.client_id ());
00142 this->sleep_hook_ = rhs.sleep_hook ();
00143 }
00144
00145 void
00146 ACE_TPQ_Entry::client_id (const ACE_TCHAR *id)
00147 {
00148 ACE_TRACE ("ACE_TPQ_Entry::client_id");
00149
00150 if (id == 0)
00151 return;
00152
00153 ACE_OS::strsncpy (this->client_id_,
00154 (ACE_TCHAR *) id,
00155 ACE_MAXCLIENTIDLEN);
00156 }
00157
00158 void
00159 ACE_TSS_TPQ_Entry::dump (void) const
00160 {
00161 ACE_TRACE ("ACE_TSS_TPQ_Entry::dump");
00162 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00163 #if defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS)
00164 ACE_DEBUG ((LM_DEBUG, (char *) "ACE_TSS_TPQ_Entry::dump:\n",
00165 (char *) " client_id_ = %s\n",
00166 (char *) client_id_ == 0 ? (char *) "0" : (char *) client_id_));
00167 #else
00168 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_TSS_TPQ_Entry::dump:\n")
00169 ACE_LIB_TEXT (" client_id_ = %s\n"),
00170 client_id_ == 0 ? ACE_LIB_TEXT ("0") : client_id_));
00171 #endif
00172 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("base:\n")));
00173 ACE_TPQ_ENTRY::dump ();
00174 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00175 }
00176
00177 ACE_TSS_TPQ_Entry::ACE_TSS_TPQ_Entry (const ACE_Token_Proxy *proxy,
00178 const ACE_TCHAR *client_id)
00179 : proxy_ (proxy),
00180 client_id_ (client_id)
00181 {
00182 ACE_TRACE ("ACE_TSS_TPQ_Entry::ACE_TSS_TPQ_Entry");
00183 }
00184
00185 ACE_TPQ_Entry *
00186 ACE_TSS_TPQ_Entry::make_TSS_TYPE (void) const
00187 {
00188 ACE_TRACE ("ACE_TSS_TPQ_Entry::make_TSS_TYPE");
00189 ACE_TPQ_Entry *temp;
00190
00191 ACE_NEW_RETURN (temp,
00192 ACE_TPQ_Entry (this->proxy_,
00193 this->client_id_),
00194 0);
00195 return temp;
00196 }
00197
00198 ACE_TSS_TPQ_Entry::operator ACE_TPQ_Entry * (void)
00199 {
00200 #if !defined (ACE_NO_TSS_TOKENS)
00201 return (ACE_TPQ_Entry *) (*((ACE_TSS<ACE_TPQ_Entry> *) this));
00202 #else
00203
00204
00205
00206
00207 ACE_TPQ_ENTRY::proxy ((ACE_Token_Proxy *)(this->proxy_));
00208 ACE_TPQ_ENTRY::client_id (this->client_id_);
00209 return (ACE_TPQ_Entry *) this;;
00210 #endif
00211 }
00212
00213 ACE_TPQ_Iterator::ACE_TPQ_Iterator (ACE_Token_Proxy_Queue &q)
00214 : current_ (q.head_)
00215 {
00216 ACE_TRACE ("ACE_TPQ_Iterator::ACE_TPQ_Iterator");
00217 }
00218
00219 int
00220 ACE_TPQ_Iterator::next (ACE_TPQ_Entry *&next_item)
00221 {
00222 ACE_TRACE ("ACE_TPQ_Iterator::next");
00223
00224 next_item = this->current_;
00225
00226 return current_ != 0;
00227 }
00228
00229 int
00230 ACE_TPQ_Iterator::done (void) const
00231 {
00232 ACE_TRACE ("ACE_TPQ_Iterator::done");
00233
00234 return this->current_ == 0;
00235 }
00236
00237 void
00238 ACE_TPQ_Iterator::advance (void)
00239 {
00240 ACE_TRACE ("ACE_TPQ_Iterator::advance");
00241
00242 if (current_ != 0)
00243 this->current_ = this->current_->next_;
00244 }
00245
00246 void
00247 ACE_TPQ_Iterator::dump (void) const
00248 {
00249 ACE_TRACE ("ACE_TPQ_Iterator::dump");
00250 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00251 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_TPQ_Iterator::dump:\n")
00252 ACE_LIB_TEXT (" current_ = %d\n"),
00253 (long) this->current_));
00254 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("head_ and tail_\n")));
00255 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00256 }
00257
00258 void
00259 ACE_Token_Proxy_Queue::dump (void) const
00260 {
00261 ACE_TRACE ("ACE_Token_Proxy_Queue::dump");
00262 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00263 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_Token_Proxy_Queue::dump:\n")
00264 ACE_LIB_TEXT (" size_ = %d\n"),
00265 size_));
00266 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("head_ and tail_\n")));
00267 if (this->head_ != 0)
00268 this->head_->dump ();
00269
00270 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_Token_Proxy_Queue::dump end.\n")));
00271 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00272 }
00273
00274 ACE_Token_Proxy_Queue::ACE_Token_Proxy_Queue (void)
00275 : head_ (0),
00276 tail_ (0),
00277 size_ (0)
00278 {
00279 ACE_TRACE ("ACE_Token_Proxy_Queue::ACE_Token_Proxy_Queue");
00280 }
00281
00282 void
00283 ACE_Token_Proxy_Queue::enqueue (ACE_TPQ_Entry *tpq,
00284 int position)
00285 {
00286 ACE_TRACE ("ACE_Token_Proxy_Queue::enqueue");
00287 tpq->next_ = 0;
00288
00289 ++this->size_;
00290
00291 if (this->head_ == 0)
00292 {
00293
00294 this->head_ = this->tail_ = tpq;
00295 return;
00296 }
00297
00298 if (position == 0)
00299 {
00300
00301 tpq->next_ = this->head_;
00302 this->head_ = tpq;
00303 return;
00304 }
00305
00306 if (position == -1)
00307 {
00308
00309 this->tail_->next_ = tpq;
00310 this->tail_ = tpq;
00311 return;
00312 }
00313
00314
00315 ACE_TPQ_Entry *temp = head_;
00316
00317 for (int x = position;
00318 x > 1;
00319 --x)
00320 {
00321
00322 if (temp->next_ == 0)
00323 break;
00324
00325 else
00326 temp = temp->next_;
00327 }
00328
00329
00330 tpq->next_ = temp->next_;
00331 temp->next_ = tpq;
00332 }
00333
00334 void
00335 ACE_Token_Proxy_Queue::dequeue (void)
00336 {
00337 ACE_TRACE ("ACE_Token_Proxy_Queue::dequeue");
00338
00339 if (head_ == 0)
00340 return;
00341
00342 ACE_TPQ_Entry *temp = this->head_;
00343
00344 this->head_ = this->head_->next_;
00345
00346 temp->next_ = 0;
00347
00348 --this->size_;
00349
00350 if (this->head_ == 0 && this->size_ != 0)
00351 ACE_ERROR ((LM_ERROR,
00352 ACE_LIB_TEXT ("incorrect size = %d\n"),
00353 this->size_));
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 void
00375 ACE_Token_Proxy_Queue::remove (const ACE_TPQ_Entry *remove_me)
00376 {
00377 ACE_TRACE ("ACE_Token_Proxy_Queue::remove");
00378
00379 if ((remove_me == 0) || (this->head_ == 0))
00380 return;
00381
00382
00383 if (this->head_ == remove_me)
00384 {
00385 this->head_ = this->head_->next_;
00386 if (this->head_ == 0)
00387 this->tail_ = 0;
00388
00389 --this->size_;
00390 return;
00391 }
00392
00393 ACE_TPQ_Entry *temp = this->head_;
00394 ACE_TPQ_Entry *previous = 0;
00395
00396
00397 while (temp != 0)
00398 {
00399 if (temp == remove_me)
00400 {
00401
00402
00403 previous->next_ = temp->next_;
00404
00405 if (this->tail_ == temp)
00406 this->tail_ = previous;
00407
00408 --this->size_;
00409 return;
00410 }
00411
00412 previous = temp;
00413 temp = temp->next_;
00414 }
00415
00416
00417 return;
00418 }
00419
00420 void
00421 ACE_Mutex_Token::dump (void) const
00422 {
00423 ACE_TRACE ("ACE_Mutex_Token::dump");
00424 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00425 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_Mutex_Token::dump:\n")));
00426 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("lock_\n")));
00427 lock_.dump ();
00428 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("base:\n")));
00429 ACE_Tokens::dump ();
00430 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_Mutex_Token::dump end.\n")));
00431 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00432 }
00433
00434 ACE_Mutex_Token::ACE_Mutex_Token (const ACE_TCHAR *name)
00435 {
00436 ACE_TRACE ("ACE_Mutex_Token::ACE_Mutex_Token");
00437
00438 ACE_OS::strsncpy (this->token_name_,
00439 name,
00440 ACE_MAXTOKENNAMELEN);
00441 }
00442
00443 ACE_Mutex_Token::~ACE_Mutex_Token (void)
00444 {
00445 ACE_TRACE ("ACE_Mutex_Token::~ACE_Mutex_Token");
00446 }
00447
00448 int
00449 ACE_Mutex_Token::acquire (ACE_TPQ_Entry *caller,
00450 int ignore_deadlock,
00451 int notify)
00452 {
00453 ACE_TRACE ("ACE_Mutex_Token::acquire");
00454
00455
00456 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
00457
00458
00459
00460 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1);
00461
00462
00463 if (this->owner () == 0)
00464 {
00465
00466 this->waiters_.enqueue (caller, -1);
00467 return 0;
00468 }
00469
00470
00471 if (this->is_owner (caller->client_id ()))
00472 {
00473
00474 caller->nesting_level (1);
00475 return 0;
00476 }
00477
00478
00479 if (!ignore_deadlock
00480 && ACE_Token_Manager::instance ()->check_deadlock (caller->proxy ()) == 1)
00481 {
00482 errno = EDEADLK;
00483 ACE_RETURN (-1);
00484 }
00485
00486
00487
00488 this->waiters_.enqueue (caller, -1);
00489
00490 if (notify)
00491 this->owner ()->call_sleep_hook ();
00492
00493 errno = EWOULDBLOCK;
00494 ACE_RETURN (-1);
00495
00496 ACE_NOTREACHED (return -1);
00497 }
00498
00499 int
00500 ACE_Mutex_Token::tryacquire (ACE_TPQ_Entry *caller)
00501 {
00502 ACE_TRACE ("ACE_Mutex_Token::tryacquire");
00503
00504
00505 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
00506
00507
00508
00509 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1);
00510
00511
00512 if (this->owner () == 0)
00513 {
00514 this->waiters_.enqueue (caller, -1);
00515 return 0;
00516 }
00517
00518 if (this->is_owner (caller->client_id ()))
00519 {
00520
00521 caller->nesting_level (1);
00522 return 0;
00523 }
00524 else
00525
00526 {
00527 errno = EWOULDBLOCK;
00528 ACE_RETURN (-1);
00529 }
00530
00531 ACE_NOTREACHED (return -1);
00532 }
00533
00534 int
00535 ACE_Mutex_Token::renew (ACE_TPQ_Entry *caller,
00536 int requeue_position)
00537 {
00538 ACE_TRACE ("ACE_Mutex_Token::renew");
00539 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1);
00540
00541
00542 if (this->is_owner (caller->client_id ()) == 0)
00543 {
00544 errno = EACCES;
00545 ACE_RETURN (-1);
00546 }
00547
00548
00549
00550
00551 if (this->waiters_.size () == 1 || requeue_position == 0)
00552 return 0;
00553
00554
00555 this->waiters_.dequeue ();
00556
00557 this->waiters_.enqueue (caller, requeue_position);
00558
00559
00560 if (this->owner () != 0)
00561 this->owner ()->proxy ()->token_acquired (this->owner ());
00562
00563
00564 errno = EWOULDBLOCK;
00565 ACE_RETURN (-1);
00566
00567 ACE_NOTREACHED (return -1);
00568 }
00569
00570
00571
00572
00573 int
00574 ACE_Mutex_Token::release (ACE_TPQ_Entry *caller)
00575 {
00576 ACE_TRACE ("ACE_Mutex_Token::release");
00577 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1);
00578
00579
00580 if (this->owner () == 0)
00581 {
00582 errno = EACCES;
00583 ACE_RETURN (-1);
00584 }
00585
00586
00587 if (this->is_owner (caller->client_id ()))
00588 {
00589
00590 if (caller->nesting_level () > 0)
00591 caller->nesting_level (-1);
00592 else
00593 {
00594 this->waiters_.dequeue ();
00595
00596 if (this->owner () != 0)
00597 this->owner ()->proxy ()->token_acquired (this->owner ());
00598 }
00599 }
00600 else
00601 this->remove (caller);
00602
00603 return 0;
00604 }
00605
00606 int
00607 ACE_Mutex_Token::owners (OWNER_STACK &stack,
00608 const ACE_TCHAR *id)
00609 {
00610 ACE_TRACE ("ACE_Mutex_Token::owners");
00611 if (this->owner () != 0)
00612 {
00613 stack.push (this->owner ());
00614
00615
00616 if (id != 0)
00617 return this->owner ()->equal_client_id (id);
00618 }
00619
00620 return 0;
00621 }
00622
00623 int
00624 ACE_Mutex_Token::is_waiting_for (const ACE_TCHAR *id)
00625 {
00626 ACE_TRACE ("ACE_Mutex_Token::is_waiting_for");
00627
00628 if ((this->owner () == 0) || this->is_owner (id))
00629 return 0;
00630
00631
00632 ACE_TPQ_Iterator iterator (waiters_);
00633 iterator.advance ();
00634 for (ACE_TPQ_Entry *temp = 0;
00635 iterator.next (temp) != 0;
00636 iterator.advance ())
00637 {
00638 if (temp->equal_client_id (id))
00639 return 1;
00640 }
00641
00642 return 0;
00643 }
00644
00645 int
00646 ACE_Mutex_Token::is_owner (const ACE_TCHAR *id)
00647 {
00648 ACE_TRACE ("ACE_Mutex_Token::is_owner");
00649
00650 if ((this->owner () != 0) &&
00651 this->owner ()->equal_client_id (id))
00652 return 1;
00653 else
00654 return 0;
00655 }
00656
00657 void
00658 ACE_RW_Token::dump (void) const
00659 {
00660 ACE_TRACE ("ACE_RW_Token::dump");
00661 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00662 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_RW_Token::dump:\n")
00663 ACE_LIB_TEXT ("num_writers_ = %d\n"), num_writers_));
00664 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("lock_\n")));
00665 this->lock_.dump ();
00666 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("base:\n")));
00667 ACE_Tokens::dump ();
00668 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_RW_Token::dump end.\n")));
00669 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00670 }
00671
00672 ACE_RW_Token::ACE_RW_Token (const ACE_TCHAR *name)
00673 : num_writers_ (0)
00674 {
00675 ACE_TRACE ("ACE_RW_Token::ACE_RW_Token");
00676
00677 ACE_OS::strsncpy (this->token_name_,
00678 name,
00679 ACE_MAXTOKENNAMELEN);
00680 }
00681
00682 ACE_RW_Token::~ACE_RW_Token (void)
00683 {
00684 ACE_TRACE ("ACE_RW_Token::~ACE_RW_Token");
00685 }
00686
00687 int
00688 ACE_RW_Token::acquire (ACE_TPQ_Entry *caller,
00689 int ignore_deadlock,
00690 int notify)
00691 {
00692 ACE_TRACE ("ACE_RW_Token::acquire");
00693
00694
00695 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
00696
00697
00698
00699 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1);
00700
00701 if (caller->proxy ()->type () == ACE_RW_Token::WRITER)
00702 this->num_writers_++;
00703
00704
00705 if (this->owner () == 0)
00706 {
00707
00708 this->waiters_.enqueue (caller, -1);
00709 return 0;
00710 }
00711
00712
00713 if (this->is_owner (caller->client_id ()))
00714 {
00715 caller->nesting_level (1);
00716 return 0;
00717 }
00718
00719
00720 if (caller->proxy ()->type () == ACE_RW_Token::READER)
00721 {
00722
00723 if (this->num_writers_ == 0)
00724 {
00725
00726 this->waiters_.enqueue (caller, -1);
00727 return 0;
00728 }
00729
00730 }
00731
00732
00733
00734
00735 if (!ignore_deadlock &&
00736 ACE_Token_Manager::instance ()->check_deadlock (caller->proxy ()) == 1)
00737 {
00738 if (caller->proxy ()->type () == ACE_RW_Token::WRITER)
00739 this->num_writers_--;
00740 errno = EDEADLK;
00741 ACE_RETURN (-1);
00742 }
00743
00744
00745 this->waiters_.enqueue (caller, -1);
00746
00747 if (notify)
00748 {
00749
00750 if (this->owner ()->proxy ()->type () == ACE_RW_Token::WRITER)
00751 this->owner ()->call_sleep_hook ();
00752 else
00753 {
00754
00755 ACE_TPQ_Entry *temp = this->owner ();
00756 do
00757 {
00758 temp->call_sleep_hook ();
00759 temp = temp->next_;
00760 }
00761 while (temp != 0 &&
00762 temp->proxy ()->type () == ACE_RW_Token::READER);
00763 }
00764 }
00765
00766 errno = EWOULDBLOCK;
00767 ACE_RETURN (-1);
00768
00769 ACE_NOTREACHED (return -1);
00770 }
00771
00772 int
00773 ACE_RW_Token::tryacquire (ACE_TPQ_Entry *caller)
00774 {
00775 ACE_TRACE ("ACE_RW_Token::tryacquire");
00776
00777
00778 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
00779
00780
00781
00782 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1);
00783
00784 if (caller->proxy ()->type () == ACE_RW_Token::WRITER)
00785 {
00786 this->num_writers_++;
00787 }
00788
00789
00790 if (this->owner () == 0)
00791 {
00792
00793 this->waiters_.enqueue (caller, -1);
00794 return 0;
00795 }
00796
00797
00798 if (this->is_owner (caller->client_id ()))
00799 {
00800 caller->nesting_level (1);
00801 return 0;
00802 }
00803
00804
00805 if (caller->proxy ()->type () == ACE_RW_Token::READER)
00806 {
00807
00808 if (this->num_writers_ == 0)
00809 {
00810
00811 this->waiters_.enqueue (caller, -1);
00812 return 0;
00813 }
00814
00815 }
00816 else
00817
00818 {
00819 this->num_writers_--;
00820 }
00821
00822
00823 errno = EWOULDBLOCK;
00824 ACE_RETURN (-1);
00825
00826 ACE_NOTREACHED (return -1);
00827 }
00828
00829 int
00830 ACE_RW_Token::renew (ACE_TPQ_Entry *caller,
00831 int requeue_position)
00832 {
00833 ACE_TRACE ("ACE_RW_Token::renew");
00834 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1);
00835
00836
00837 if (this->is_owner (caller->client_id ()) == 0)
00838 {
00839 errno = EACCES;
00840 ACE_RETURN (-1);
00841 }
00842
00843
00844
00845 if (this->waiters_.size () == 1 || requeue_position == 0)
00846 return 0;
00847
00848
00849 this->remove (caller);
00850
00851
00852 this->waiters_.enqueue (caller, requeue_position);
00853
00854 if (caller->proxy ()->type () == ACE_RW_Token::READER)
00855 {
00856
00857
00858 if (this->is_owner (caller->client_id ()))
00859 return 0;
00860
00861 }
00862
00863
00864
00865
00866 this->notify_new_owner (caller);
00867
00868
00869 errno = EWOULDBLOCK;
00870 ACE_RETURN (-1);
00871
00872 ACE_NOTREACHED (return -1);
00873 }
00874
00875 int
00876 ACE_RW_Token::release (ACE_TPQ_Entry *caller)
00877 {
00878 ACE_TRACE ("ACE_RW_Token::release");
00879 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1);
00880
00881
00882 if ((this->owner () == 0) ||
00883 (this->is_owner (caller->client_id ()) == 0))
00884 {
00885 errno = EACCES;
00886 ACE_RETURN (-1);
00887 }
00888
00889 if (caller->proxy ()->type () == ACE_RW_Token::WRITER)
00890 num_writers_--;
00891
00892
00893 if (caller->nesting_level () > 0)
00894 {
00895 caller->nesting_level (-1);
00896 return 0;
00897 }
00898
00899
00900 this->remove (caller);
00901 this->notify_new_owner (caller);
00902
00903 return 0;
00904 }
00905
00906 void
00907 ACE_RW_Token::notify_new_owner (ACE_TPQ_Entry *old_owner)
00908 {
00909 ACE_TRACE ("ACE_RW_Token::notify_new_owner");
00910
00911 if (this->owner () == 0)
00912 return;
00913
00914 if (this->owner ()->proxy ()->type () == ACE_RW_Token::READER)
00915 {
00916 if (old_owner->proxy ()->type () == ACE_RW_Token::READER)
00917
00918 return;
00919
00920
00921
00922
00923 ACE_TPQ_Iterator iterator (waiters_);
00924 for (ACE_TPQ_Entry *temp = 0;
00925 iterator.next (temp) != 0;
00926 iterator.advance ())
00927 {
00928 if (temp->proxy ()->type () == WRITER)
00929
00930 break;
00931
00932 temp->proxy ()->token_acquired (temp);
00933 }
00934 }
00935 else
00936 this->owner ()->proxy ()->token_acquired (this->owner ());
00937 }
00938
00939
00940 int
00941 ACE_RW_Token::owners (OWNER_STACK &stack,
00942 const ACE_TCHAR *id)
00943 {
00944 ACE_TRACE ("ACE_RW_Token::owners");
00945
00946 if (this->owner () == 0)
00947 return 0;
00948
00949 int id_is_owner = 0;
00950
00951
00952 if (this->owner ()->proxy ()->type () == WRITER)
00953 {
00954 stack.push (this->owner ());
00955
00956
00957 if ((id != 0) &&
00958 (ACE_OS::strcmp (id, this->owner ()->client_id ()) == 0))
00959 id_is_owner = 1;
00960 }
00961
00962
00963 else
00964 {
00965 ACE_TPQ_Iterator iterator (waiters_);
00966 for (ACE_TPQ_Entry *temp = 0;
00967 iterator.next (temp) != 0;
00968 iterator.advance ())
00969 {
00970 if (temp->proxy ()->type () == WRITER)
00971
00972 break;
00973
00974 stack.push (temp);
00975
00976 if (!id_is_owner && (id != 0) &&
00977 (ACE_OS::strcmp (id, temp->client_id ()) == 0))
00978 id_is_owner = 1;
00979 }
00980 }
00981
00982 return id_is_owner;
00983 }
00984
00985 int
00986 ACE_RW_Token::is_waiting_for (const ACE_TCHAR *id)
00987 {
00988 ACE_TRACE ("ACE_RW_Token::is_waiting_for");
00989
00990 if ((this->owner () == 0) ||
00991 this->is_owner (id))
00992 return 0;
00993
00994
00995 ACE_TPQ_Iterator iterator (waiters_);
00996 iterator.advance ();
00997 for (ACE_TPQ_Entry *temp = 0;
00998 iterator.next (temp) != 0;
00999 iterator.advance ())
01000 {
01001 if (temp->equal_client_id (id))
01002 return 1;
01003 }
01004
01005 return 0;
01006 }
01007
01008 int
01009 ACE_RW_Token::is_owner (const ACE_TCHAR *id)
01010 {
01011 ACE_TRACE ("ACE_RW_Token::is_owner");
01012
01013 if (this->owner () == 0)
01014 return 0;
01015
01016
01017 if (this->owner ()->proxy ()->type () == ACE_RW_Token::WRITER)
01018 return this->owner ()->equal_client_id (id);
01019
01020
01021
01022 ACE_TPQ_Iterator iterator (waiters_);
01023 for (ACE_TPQ_Entry *temp = 0;
01024 iterator.next (temp) != 0;
01025 iterator.advance ())
01026 {
01027 if (temp->proxy ()->type () != ACE_RW_Token::READER)
01028 break;
01029
01030 if (temp->equal_client_id (id))
01031 return 1;
01032 }
01033
01034 return 0;
01035 }
01036
01037 void
01038 ACE_Token_Proxy::dump (void) const
01039 {
01040 ACE_TRACE ("ACE_Token_Proxy::dump");
01041 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
01042 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_Token_Proxy::dump:\n")
01043 ACE_LIB_TEXT (" type = %d\n")
01044 ACE_LIB_TEXT (" ignore_deadlock_ = %d\n")
01045 ACE_LIB_TEXT (" debug_ = %d\n"),
01046 (int) this->type (), ignore_deadlock_, debug_));
01047 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("mutex_, and waiter_\n")));
01048
01049 if (this->token_ != 0)
01050 this->token_->dump ();
01051
01052 this->waiter_.dump ();
01053 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_Token_Proxy::dump end.\n")));
01054 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
01055 }
01056
01057 const ACE_TCHAR *
01058 ACE_Token_Proxy::client_id (void) const
01059 {
01060 ACE_TRACE ("ACE_Token_Proxy::client_id");
01061
01062 ACE_Token_Proxy *nc_this =
01063 ACE_const_cast (ACE_Token_Proxy *, this);
01064 const ACE_TPQ_Entry *temp =
01065 nc_this->waiter_.operator->();
01066 const ACE_TCHAR *id = temp->client_id ();
01067
01068 if (id == 0)
01069 return ACE_LIB_TEXT ("ERROR NO CLIENT ID");
01070 else
01071 return id;
01072 }
01073
01074 void
01075 ACE_Token_Proxy::client_id (const ACE_TCHAR *client_id)
01076 {
01077 ACE_TRACE ("ACE_Token_Proxy::client_id");
01078 this->waiter_->client_id (client_id);
01079 }
01080
01081 const ACE_TCHAR *
01082 ACE_Token_Proxy::owner_id (void)
01083 {
01084 ACE_TRACE ("ACE_Token_Proxy::owner_id");
01085 return this->token_->owner_id ();
01086 }
01087
01088 const ACE_TCHAR *
01089 ACE_Token_Proxy::name (void) const
01090 {
01091 ACE_TRACE ("ACE_Token_Proxy::name");
01092 return this->token_->name ();
01093 }
01094
01095 ACE_Token_Proxy::ACE_Token_Proxy (void)
01096 : token_ (0),
01097 waiter_ (this, 0)
01098 {
01099 ACE_TRACE ("ACE_Token_Proxy::ACE_Token_Proxy");
01100 }
01101
01102
01103
01104
01105
01106 ACE_Token_Proxy::ACE_Token_Proxy (const ACE_Token_Proxy &)
01107 : token_ (0),
01108 waiter_ (this, 0)
01109 {
01110 ACE_TRACE ("ACE_Token_Proxy::ACE_Token_Proxy");
01111 }
01112
01113
01114 ACE_Token_Proxy::~ACE_Token_Proxy (void)
01115 {
01116 ACE_TRACE ("ACE_Token_Proxy::~ACE_Token_Proxy");
01117
01118 if (token_ != 0)
01119
01120
01121 ACE_Token_Manager::instance ()->release_token (token_);
01122 }
01123
01124 int
01125 ACE_Token_Proxy::open (const ACE_TCHAR *token_name,
01126 int ignore_deadlock,
01127 int debug)
01128 {
01129 ACE_TRACE ("ACE_Token_Proxy::open");
01130
01131
01132 this->ignore_deadlock_ = ignore_deadlock;
01133 this->debug_ = debug;
01134
01135
01136 ACE_TCHAR name[BUFSIZ];
01137
01138
01139 if (token_name == 0)
01140 {
01141 ACE_OS::sprintf (name, ACE_LIB_TEXT ("token %lx"),
01142 ACE_reinterpret_cast (long, this));
01143 token_name = name;
01144 }
01145
01146
01147
01148 ACE_Token_Manager::instance ()->get_token (this, token_name);
01149
01150
01151 if (this->token_ == 0)
01152 {
01153 errno = ENOMEM;
01154 ACE_ERROR_RETURN ((LM_ERROR, ACE_LIB_TEXT ("Can't allocate mutex")), -1);
01155 }
01156
01157 return 0;
01158 }
01159
01160 int
01161 ACE_Token_Proxy::acquire (int notify,
01162 void (*sleep_hook)(void *),
01163 ACE_Synch_Options &options)
01164 {
01165 ACE_TRACE ("ACE_Token_Proxy::acquire");
01166 if (this->token_ == 0)
01167 {
01168 errno = ENOENT;
01169 ACE_ERROR_RETURN ((LM_ERROR, ACE_LIB_TEXT ("Not open.\n")), -1);
01170 }
01171
01172
01173
01174
01175
01176
01177
01178 this->waiter_->cond_var_.mutex ().acquire ();
01179
01180 this->waiter_->sleep_hook (sleep_hook);
01181
01182 if (this->token_->acquire (this->waiter_, this->ignore_deadlock_, notify) == -1)
01183
01184 {
01185 switch (errno)
01186 {
01187 case EDEADLK :
01188 if (!ignore_deadlock_)
01189 {
01190 waiter_->cond_var_.mutex ().release ();
01191 errno = EDEADLK;
01192 ACE_RETURN (-1);
01193 }
01194
01195
01196 case EWOULDBLOCK :
01197 if (this->debug_)
01198 ACE_DEBUG ((LM_DEBUG,
01199 ACE_LIB_TEXT ("(%t) waiting for %s, owner is %s, ")
01200 ACE_LIB_TEXT ("total waiters == %d\n"),
01201 this->name (),
01202 this->token_->owner_id (),
01203 token_->no_of_waiters ()));
01204
01205
01206
01207 int return_value;
01208 if (this->handle_options (options,
01209 waiter_->cond_var_) == -1)
01210 return_value = -1;
01211 else
01212 return_value = notify == 1;
01213
01214 errno = EWOULDBLOCK;
01215 ACE_RETURN (return_value);
01216
01217 default :
01218 waiter_->cond_var_.mutex ().release ();
01219 ACE_ERROR_RETURN ((LM_ERROR,
01220 ACE_LIB_TEXT ("%p\n"),
01221 ACE_LIB_TEXT ("Token Proxy acquire.")),
01222 -1);
01223 }
01224 }
01225 else
01226
01227 {
01228 if (debug_)
01229 ACE_DEBUG ((LM_DEBUG,
01230 ACE_LIB_TEXT ("(%t) acquired %s\n"),
01231 this->name ()));
01232 waiter_->cond_var_.mutex ().release ();
01233 }
01234
01235 return 0;
01236 }
01237
01238 int
01239 ACE_Token_Proxy::tryacquire (void (*sleep_hook)(void *))
01240 {
01241 ACE_TRACE ("ACE_Token_Proxy::tryacquire");
01242 if (this->token_ == 0)
01243 {
01244 errno = ENOENT;
01245 ACE_ERROR_RETURN ((LM_ERROR,
01246 ACE_LIB_TEXT ("Not open.\n")),
01247 -1);
01248 }
01249
01250 this->waiter_->sleep_hook (sleep_hook);
01251
01252 return this->token_->tryacquire (waiter_);
01253 }
01254
01255 int
01256 ACE_Token_Proxy::renew (int requeue_position,
01257 ACE_Synch_Options &options)
01258 {
01259 ACE_TRACE ("ACE_Token_Proxy::renew");
01260 if (this->token_ == 0)
01261 {
01262 errno = ENOENT;
01263 ACE_ERROR_RETURN ((LM_ERROR,
01264 ACE_LIB_TEXT ("Not open.\n")),
01265 -1);
01266 }
01267
01268
01269
01270 this->waiter_->cond_var_.mutex ().acquire ();
01271
01272 if (this->token_->renew (this->waiter_, requeue_position) == -1)
01273 {
01274
01275 if (errno != EWOULDBLOCK)
01276 ACE_ERROR_RETURN ((LM_ERROR,
01277 ACE_LIB_TEXT ("%p renew failed\n"), ACE_LIB_TEXT ("ACE_Token_Proxy")), -1);
01278
01279 if (this->debug_)
01280 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%t) renew blocking for %s, owner is %s\n"),
01281 this->name (),
01282 token_->owner_id ()));
01283
01284
01285 return this->handle_options (options, waiter_->cond_var_);
01286 }
01287 else
01288
01289 {
01290 if (this->debug_)
01291 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%t) renewed %s\n"),
01292 this->name ()));
01293 waiter_->cond_var_.mutex ().release ();
01294 return 0;
01295 }
01296 }
01297
01298 int
01299 ACE_Token_Proxy::handle_options (ACE_Synch_Options &options,
01300 ACE_TOKEN_CONST::COND_VAR &cv)
01301 {
01302
01303 ACE_TRACE ("ACE_Token_Proxy::handle_options");
01304
01305 if (options[ACE_Synch_Options::USE_REACTOR] == 1)
01306
01307 {
01308
01309 ACE_Errno_Guard error (errno);
01310 cv.mutex ().release ();
01311 ACE_RETURN (-1);
01312 }
01313 else
01314
01315 {
01316
01317 while (cv.wait ((ACE_Time_Value *) options.time_value ()) == -1)
01318 {
01319
01320
01321 if (errno == EINTR)
01322 continue;
01323
01324
01325 cv.mutex ().release ();
01326 ACE_ERROR_RETURN ((LM_ERROR, ACE_LIB_TEXT ("condition variable wait")
01327 ACE_LIB_TEXT (" bombed.")), -1);
01328 }
01329
01330 if (this->debug_)
01331 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%t) unblocking.\n"),
01332 this->client_id ()));
01333 cv.mutex ().release ();
01334 return 0;
01335 }
01336 }
01337
01338 int
01339 ACE_Token_Proxy::release (ACE_Synch_Options &)
01340 {
01341 ACE_TRACE ("ACE_Token_Proxy::release");
01342
01343 if (this->token_ == 0)
01344 {
01345 errno = ENOENT;
01346 if (debug_)
01347 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("Must open before releasing.\n")));
01348 ACE_RETURN (-1);
01349 }
01350
01351 if (this->token_->release (waiter_) != 0)
01352 {
01353
01354 this->token_->remove (this->waiter_);
01355 if (debug_)
01356 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%t) %p.\n"), ACE_LIB_TEXT ("release failed")));
01357 return -1;
01358 }
01359 else
01360 {
01361 if (this->debug_)
01362 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%t) released %s, owner is %s\n"),
01363 this->name (),
01364 token_->owner_id ()));
01365
01366 return 0;
01367 }
01368 }
01369
01370 int
01371 ACE_Token_Proxy::remove (ACE_Synch_Options &)
01372 {
01373 ACE_TRACE ("ACE_Token_Proxy::remove");
01374 return 0;
01375 }
01376
01377 void
01378 ACE_Token_Proxy::sleep_hook (void)
01379 {
01380 ACE_TRACE ("ACE_Token_Proxy::sleep_hook");
01381
01382 return;
01383 }
01384
01385 void
01386 ACE_Token_Proxy::token_acquired (ACE_TPQ_Entry *e)
01387 {
01388 ACE_TRACE ("ACE_Token_Proxy::token_acquired");
01389 e->cond_var_.mutex ().acquire ();
01390
01391
01392
01393
01394 e->cond_var_.signal ();
01395 e->cond_var_.mutex ().release ();
01396
01397 return;
01398 }
01399
01400 ACE_Token_Name::ACE_Token_Name (const ACE_TCHAR *token_name)
01401 {
01402 ACE_TRACE ("ACE_Token_Name::ACE_Token_Name");
01403 this->name (token_name);
01404 }
01405
01406 ACE_Token_Name::ACE_Token_Name (const ACE_Token_Name &rhs)
01407 {
01408 ACE_TRACE ("ACE_Token_Name::ACE_Token_Name");
01409 this->name (rhs.name ());
01410 }
01411
01412 ACE_Token_Name::~ACE_Token_Name ()
01413 {
01414 ACE_TRACE ("ACE_Token_Name::~ACE_Token_Name");
01415 }
01416
01417 void
01418 ACE_Token_Name::dump (void) const
01419 {
01420 ACE_TRACE ("ACE_Token_Name::dump");
01421 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
01422 #if defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS)
01423 ACE_DEBUG ((LM_DEBUG, (char *) "ACE_Token_Name::dump:\n",
01424 (char *) " token_name_ = %s\n",
01425 (char *) token_name_ == 0 ? (char *) "no name" : (char *) token_name_));
01426 #else
01427 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_Token_Name::dump:\n")
01428 ACE_LIB_TEXT (" token_name_ = %s\n"),
01429 token_name_ == 0 ? ACE_LIB_TEXT ("no name") : token_name_));
01430 #endif
01431 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
01432 }
01433
01434
01435 #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
01436 #if !defined (ACE_NO_TSS_TOKENS)
01437 template class ACE_TSS <ACE_TPQ_Entry>;
01438 #endif
01439 template class ACE_Unbounded_Stack <ACE_TPQ_Entry *>;
01440 template class ACE_Node <ACE_TPQ_Entry *>;
01441 #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
01442 #if !defined (ACE_NO_TSS_TOKENS)
01443 #pragma instantiate ACE_TSS <ACE_TPQ_Entry>
01444 #endif
01445 #pragma instantiate ACE_Unbounded_Stack <ACE_TPQ_Entry *>
01446 #pragma instantiate ACE_Node <ACE_TPQ_Entry *>
01447 #endif
01448
01449 #endif