Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Local_Tokens.cpp

Go to the documentation of this file.
00001 #include "ace_pch.h"
00002 // $Id: Local_Tokens.cpp,v 1.1.1.4.2.1 2003/03/13 19:44:21 chad Exp $
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 /* __ACE_INLINE__ */
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 /* ACE_LACKS_INLINE_FUNCTIONS */
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     // This const typecast is safe.
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       // Just make sure we have enough space.
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       // The cast is an attempt to get this to compile (and run,
00101       // hopefully) regardless of the type of ACE_thread_t.
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 /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
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 /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
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   // Not sure this is the right thing to do, but it seems to work.
00204   // The base class ALSO has a proxy_ and client_id_ members (weird?)
00205   // which don't get initialised.  The following two lines make this
00206   // the same as the subclass, so that the slicing works .
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 /* !ACE_NO_TSS_TOKENS */
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       // make tpq the entire list
00294       this->head_ = this->tail_ = tpq;
00295       return;
00296     }
00297 
00298   if (position == 0)
00299     {
00300       // make head of list
00301       tpq->next_ = this->head_;
00302       this->head_ = tpq;
00303       return;
00304     }
00305 
00306   if (position == -1)
00307     {
00308       // stick at back of list
00309       this->tail_->next_ = tpq;
00310       this->tail_ = tpq;
00311       return;
00312     }
00313 
00314   // walk through list to insertion point
00315   ACE_TPQ_Entry *temp = head_;
00316 
00317   for (int x = position;
00318        x > 1;
00319        --x)
00320     {
00321       // end of queue?
00322       if (temp->next_ == 0)
00323         break;
00324       // advance pointer
00325       else
00326         temp = temp->next_;
00327     }
00328 
00329   // insert new tpq after temp
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 int
00358 ACE_Token_Proxy_Queue::member (const ACE_TCHAR *id)
00359 {
00360   ACE_TRACE ("ACE_Token_Proxy_Queue::member");
00361 
00362   for (ACE_TPQ_Entry *temp = this->head_;
00363        temp != 0;
00364        temp = temp->next_)
00365     if (ACE_OS::strcmp (temp->client_id (), id) == 0)
00366       // We found it!
00367       return 1;
00368 
00369   // We didn't find it :-(
00370   return 0;
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   // sanity
00379   if ((remove_me == 0) || (this->head_ == 0))
00380     return;
00381 
00382   // is it the head?
00383   if (this->head_ == remove_me) // pointer comparison.
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   // is it in the middle or tail?
00397   while (temp != 0)
00398     {
00399       if (temp == remove_me)
00400         {
00401           // previous should never be null since the first if
00402           // conditional should always be false
00403           previous->next_ = temp->next_;
00404           // is it the tail?
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   // it wasn't in the list.
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   // We need to acquire two locks. This one to ensure that only one
00455   // thread uses this token at a time.
00456   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
00457   // This one to ensure an atomic transaction across all tokens.  Note
00458   // that this order is crucial too.  It's resource coloring for other
00459   // threads which may be calling this same token.
00460   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1);
00461 
00462   // Does _anyone_ own the token?
00463   if (this->owner () == 0)
00464     {
00465       // there are no waiters, so queue as the first waiter (the owner.)
00466       this->waiters_.enqueue (caller, -1);
00467       return 0;  // success
00468     }
00469 
00470   // Does the caller already own it?
00471   if (this->is_owner (caller->client_id ()))
00472     {
00473       // Recursive acquisition.
00474       caller->nesting_level (1);
00475       return 0; // success
00476     }
00477 
00478   // Check for deadlock.
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   // Someone owns it. Sorry, you're getting queued up at the end of
00487   // the waiter queue.
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   // We need to acquire two locks. This one to ensure that only one
00504   // thread uses this token at a time.
00505   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
00506   // This one to ensure an atomic transaction across all tokens.  Note
00507   // that this order is crucial too.  It's resource coloring for other
00508   // threads which may be calling this same token.
00509   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1);
00510 
00511   // Does _anyone_ own the token?
00512   if (this->owner () == 0)
00513     {
00514       this->waiters_.enqueue (caller, -1);
00515       return 0;  // success
00516     }
00517   // Does the caller already own it?
00518   if (this->is_owner (caller->client_id ()))
00519     {
00520       // recursive acquisition
00521       caller->nesting_level (1);
00522       return 0;  // success
00523     }
00524   else
00525     // Someone owns it.  Fail.
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   // Verify that the caller is the owner.
00542   if (this->is_owner (caller->client_id ()) == 0)
00543     {
00544       errno = EACCES;
00545       ACE_RETURN (-1);
00546     }
00547 
00548   // The caller is the owner, so check to see if there are any
00549   // waiters.  If not, we just keep the token.  == 1 means that there
00550   // is only the owner.
00551   if (this->waiters_.size () == 1 || requeue_position == 0)
00552     return 0;
00553 
00554   // Requeue the caller.
00555   this->waiters_.dequeue ();
00556 
00557   this->waiters_.enqueue (caller, requeue_position);
00558 
00559   // Notify new owner.
00560   if (this->owner () != 0)
00561     this->owner ()->proxy ()->token_acquired (this->owner ());
00562 
00563   // Tell the caller that the operation would block.
00564   errno = EWOULDBLOCK;
00565   ACE_RETURN (-1);
00566 
00567   ACE_NOTREACHED (return -1);
00568 }
00569 
00570 // Release the current holder of the token (which had
00571 // better be the caller's thread!).
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   // Does anyone own the token?
00580   if (this->owner () == 0)
00581     {
00582       errno = EACCES;
00583       ACE_RETURN (-1);
00584     }
00585 
00586   // Is the caller the owner.
00587   if (this->is_owner (caller->client_id ()))
00588     {
00589       // Check the nesting level.
00590       if (caller->nesting_level () > 0)
00591         caller->nesting_level (-1);
00592       else
00593         {
00594           this->waiters_.dequeue ();
00595           // Notify new owner.
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       // If an <id> is specified, return whether it is the owner being
00615       // returned.
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   // If there is no owner, or <id> is the owner, return false.
00628   if ((this->owner () == 0) || this->is_owner (id))
00629     return 0;
00630 
00631   // Step through each waiter looking for <id>.
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   // If there is an owner, return whether it is <id>.
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   // We need to acquire two locks. This one to ensure that only one
00694   // thread uses this token at a time.
00695   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
00696   // This one to ensure an atomic transaction across all tokens.  Note
00697   // that this order is crucial too.  It's resource coloring for other
00698   // threads which may be calling this same token.
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   // Does _anyone_ own the token?
00705   if (this->owner () == 0)
00706     {
00707       // There are no waiters, so queue as the first waiter (the owner).
00708       this->waiters_.enqueue (caller, -1);
00709       return 0;
00710     }
00711 
00712   // Check for recursive acquisition.
00713   if (this->is_owner (caller->client_id ()))
00714     {
00715       caller->nesting_level (1);
00716       return 0;  // Success.
00717     }
00718 
00719   // Reader.
00720   if (caller->proxy ()->type () == ACE_RW_Token::READER)
00721     {
00722       // Are there any writers?
00723       if (this->num_writers_ == 0)
00724         {
00725           // Queue the caller at the end of the queue.
00726           this->waiters_.enqueue (caller, -1);
00727           return 0;
00728         }
00729       // Else failure.
00730     }
00731 
00732   // Failure code.
00733 
00734   // Check for deadlock.
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   // Queue the caller at the end of the queue.
00745   this->waiters_.enqueue (caller, -1);
00746 
00747   if (notify)
00748     {
00749       // If it's a writer, just notify it.
00750       if (this->owner ()->proxy ()->type () == ACE_RW_Token::WRITER)
00751         this->owner ()->call_sleep_hook ();
00752       else
00753         {
00754           // Call back all reader owners.
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   // We need to acquire two locks. This one to ensure that only one
00777   // thread uses this token at a time.
00778   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
00779   // This one to ensure an atomic transaction across all tokens.  Note
00780   // that this order is crucial too.  It's resource coloring for other
00781   // threads which may be calling this same token.
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   // Does _anyone_ own the token?
00790   if (this->owner () == 0)
00791     {
00792       // There are no waiters, so queue as the first waiter (the owner).
00793       this->waiters_.enqueue (caller, -1);
00794       return 0;
00795     }
00796 
00797   // Check for recursive acquisition.
00798   if (this->is_owner (caller->client_id ()))
00799     {
00800       caller->nesting_level (1);
00801       return 0;  // Success.
00802     }
00803 
00804   // Reader.
00805   if (caller->proxy ()->type () == ACE_RW_Token::READER)
00806     {
00807       // Are there any writers?
00808       if (this->num_writers_ == 0)
00809         {
00810           // queue the caller at the end of the queue.
00811           this->waiters_.enqueue (caller, -1);
00812           return 0;
00813         }
00814       // Else, fail.
00815     }
00816   else // Writer.
00817     // We're going to fail, so decrement the num_writers.
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   // Werify that the caller is the owner
00837   if (this->is_owner (caller->client_id ()) == 0)
00838     {
00839       errno = EACCES;
00840       ACE_RETURN (-1);
00841     }
00842 
00843   // The caller is the owner, so check to see if there are any
00844   // waiters.  If not, we just keep the token.
00845   if (this->waiters_.size () == 1 || requeue_position == 0)
00846     return 0;
00847 
00848   // There are waiters, so remove the caller.
00849   this->remove (caller);
00850 
00851   // Requeue the caller.
00852   this->waiters_.enqueue (caller, requeue_position);
00853 
00854   if (caller->proxy ()->type () == ACE_RW_Token::READER)
00855     {
00856       // If the caller got queued before any writers, the caller is
00857       // still the owner.
00858       if (this->is_owner (caller->client_id ()))
00859         return 0; // success
00860       // else fallthrough and return would block.
00861     }
00862   // Writers will always have to block since waiters_.size () == 1 or
00863   // requeue_position == 0.
00864 
00865   // Get a new owner.
00866   this->notify_new_owner (caller);
00867 
00868   // Tell the caller that the operation would block.
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   // Check for errors.
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   // Recursive release.
00893   if (caller->nesting_level () > 0)
00894     {
00895       caller->nesting_level (-1);
00896       return 0;
00897     }
00898 
00899   // Remove the caller and notify the new owner(s).
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         // the owners already know that they're owners
00918         return;
00919 
00920       // The current owner is a reader and the previous owner was a
00921       // writer, so notify all waiting readers up to the first writer.
00922       // call back all reader owners.
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             // We've gone through all the readers.
00930             break;
00931 
00932           temp->proxy ()->token_acquired (temp);
00933         }
00934     }
00935   else // writer
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   // The first waiter is a writer, so there is only one owner.
00952   if (this->owner ()->proxy ()->type () == WRITER)
00953     {
00954       stack.push (this->owner ());
00955       // If an <id> is specified, return whether it is the owner being
00956       // returned.
00957       if ((id != 0) &&
00958           (ACE_OS::strcmp (id, this->owner ()->client_id ()) == 0))
00959         id_is_owner = 1;
00960     }
00961   // The first waiter is a reader, so there can be multiple owning
00962   // readers.
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             // We've gone through all the readers.
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   // If there is no owner, or <id> is the owner, return false.
00990   if ((this->owner () == 0) ||
00991       this->is_owner (id))
00992     return 0;
00993 
00994   // Step through each waiter looking for <id>.
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   // If there is no owner, return false.
01013   if (this->owner () == 0)
01014     return 0;
01015 
01016   // A writer owns us.
01017   if (this->owner ()->proxy ()->type () == ACE_RW_Token::WRITER)
01018     return this->owner ()->equal_client_id (id);
01019 
01020   // Readers own us.
01021   // Step through each owning reader looking for <id>.
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   // Thread-specific.
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 // Notice the token_ (0).  Do *not* copy the token pointer.  This must
01103 // be obtained through the token manager.  Also, we don't copy any
01104 // waiter info.  A copied Proxy does *not* inherit client_id.
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 // @@ should I do a mutex_->release ()?
01114 ACE_Token_Proxy::~ACE_Token_Proxy (void)
01115 {
01116   ACE_TRACE ("ACE_Token_Proxy::~ACE_Token_Proxy");
01117 
01118   if (token_ != 0)
01119     // notify token manager that we are done with it so it can
01120     // free it if necessary
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   // Store some parameters.
01132   this->ignore_deadlock_ = ignore_deadlock;
01133   this->debug_ = debug;
01134 
01135   // Used in case a name was not specified.
01136   ACE_TCHAR name[BUFSIZ];
01137 
01138   // We must have a name.
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   // Get or create the underlying token.  The Token Manager will call
01147   // us back to set token_.
01148   ACE_Token_Manager::instance ()->get_token (this, token_name);
01149 
01150   // Check for failed get or failed new.
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   // Make sure no one calls our token_acquired until we have a chance
01173   // to sleep first!  If after we call an EWOULDBLOCK
01174   // mutex_->acquire() below, but before we enter handle_options to
01175   // wait on the cond_var, a thread tries to give take us off the
01176   // waiter queue and signal us, IT WILL FIRST HAVE TO ACQUIRE THIS
01177   // cond_var.mutex ().  _This_ is why we acquire it.
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     // acquire failed
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           // Else, fallthrough and block!
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           // no error, but would block, if error, return error (-1),
01206           // otherwise, return whether we called the holder or not.
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     // we have the token
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   // Make sure no one calls our token_acquired until we have a chance
01269   // to sleep first!
01270   this->waiter_->cond_var_.mutex ().acquire ();
01271 
01272   if (this->token_->renew (this->waiter_, requeue_position) == -1)
01273     {
01274       // check for error
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       // no error, but would block, so block or return
01285       return this->handle_options (options, waiter_->cond_var_);
01286     }
01287   else
01288     // we have the token
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   // Some operation failed with EWOULDBLOCK.
01303   ACE_TRACE ("ACE_Token_Proxy::handle_options");
01304 
01305   if (options[ACE_Synch_Options::USE_REACTOR] == 1)
01306     // Asynchronous.
01307     {
01308       // Save/restore errno.
01309       ACE_Errno_Guard error (errno);
01310       cv.mutex ().release ();
01311       ACE_RETURN (-1);
01312     }
01313   else
01314     // Synchronous.
01315     {
01316       // Block on condition variable.
01317       while (cv.wait ((ACE_Time_Value *) options.time_value ()) == -1)
01318         {
01319           // Note, this should obey whatever thread-specific
01320           // interrupt policy is currently in place...
01321           if (errno == EINTR)
01322             continue;
01323           // We come here if a timeout occurs or some serious
01324           // ACE_Condition object error.
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;       // operation succeeded
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       // Release failed.
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   // Somebody wants our token!  (Let'em wait...)
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   // We've been taken off the waiters list and given the token!
01391   // This implementation signals the internal condition
01392   // variable. Thus, if asynchronous acquires are used, this must be
01393   // overriden to do something more useful!
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 /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
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 /* ! defined (ACE_HAS_BROKEN_CONDITIONAL_STRING_CASTS) */
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 /* ACE_NO_TSS_TOKENS */
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 /* ACE_NO_TSS_TOKENS */
01445 #pragma instantiate ACE_Unbounded_Stack <ACE_TPQ_Entry *>
01446 #pragma instantiate ACE_Node <ACE_TPQ_Entry *>
01447 #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
01448 
01449 #endif /* ACE_HAS_TOKENS_LIBRARY */

Generated on Mon Jun 16 11:19:57 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002