Local_Tokens.cpp

Go to the documentation of this file.
00001 // $Id: Local_Tokens.cpp 80826 2008-03-04 14:51:23Z wotte $
00002 
00003 #include "ace/Local_Tokens.h"
00004 
00005 #if defined (ACE_HAS_TOKENS_LIBRARY)
00006 
00007 #include "ace/Thread.h"
00008 #include "ace/Token_Manager.h"
00009 #include "ace/OS_NS_unistd.h"
00010 
00011 #if !defined (__ACE_INLINE__)
00012 #include "ace/Local_Tokens.inl"
00013 #endif /* __ACE_INLINE__ */
00014 
00015 
00016 ACE_RCSID (ace,
00017            Local_Tokens,
00018            "$Id: Local_Tokens.cpp 80826 2008-03-04 14:51:23Z wotte $")
00019 
00020 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00021 
00022 void
00023 ACE_Tokens::dump (void) const
00024 {
00025 #if defined (ACE_HAS_DUMP)
00026   ACE_TRACE ("ACE_Tokens::dump");
00027   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00028   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("ACE_Tokens::dump:\n")
00029                         ACE_TEXT (" reference_cont_ = %d\n")
00030                         ACE_TEXT (" token_name_ = %s\n"),
00031                         reference_count_, token_name_));
00032   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("waiters_\n")));
00033   this->waiters_.dump ();
00034   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00035 #endif /* ACE_HAS_DUMP */
00036 }
00037 
00038 ACE_Tokens::ACE_Tokens (void)
00039   : visited_ (0),
00040     reference_count_ (0)
00041 {
00042   ACE_TRACE ("ACE_Tokens::ACE_Tokens");
00043 }
00044 
00045 ACE_Tokens::~ACE_Tokens (void)
00046 {
00047 }
00048 
00049 void
00050 ACE_Tokens::make_owner (ACE_TPQ_Entry *caller)
00051 {
00052   this->waiters_.remove (caller);
00053   this->waiters_.enqueue (caller, 0);
00054 }
00055 
00056 ACE_Token_Proxy_Queue *
00057 ACE_Tokens::waiters ()
00058 {
00059   ACE_TRACE ("ACE_Tokens::waiters");
00060   return &this->waiters_;
00061 }
00062 
00063 int
00064 ACE_Tokens::no_of_waiters ()
00065 {
00066   ACE_TRACE ("ACE_Tokens::no_of_waiters");
00067   return this->waiters_.size ();
00068 }
00069 
00070 #if defined (ACE_LACKS_INLINE_FUNCTIONS)
00071 ACE_Null_Token::ACE_Null_Token (void)
00072 {
00073 }
00074 
00075 ACE_Null_Token::~ACE_Null_Token (void)
00076 {
00077 }
00078 #endif /* ACE_LACKS_INLINE_FUNCTIONS */
00079 
00080 void
00081 ACE_TPQ_Entry::dump (void) const
00082 {
00083 #if defined (ACE_HAS_DUMP)
00084   ACE_TRACE ("ACE_TPQ_Entry::dump");
00085   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00086   ACE_DEBUG ((LM_DEBUG,
00087               ACE_TEXT ("ACE_TPQ_Entry::dump:\n")
00088               ACE_TEXT (" nesting_level_ = %d\n")
00089               ACE_TEXT (" client_id_ = %s\n"),
00090               nesting_level_,
00091               client_id_));
00092 
00093   if (next_ != 0)
00094     {
00095       ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("next:.\n")));
00096       next_->dump ();
00097     }
00098 
00099   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_TPQ_Entry::dump end.\n")));
00100   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00101 #endif /* ACE_HAS_DUMP */
00102 }
00103 
00104 ACE_TPQ_Entry::ACE_TPQ_Entry (const ACE_Token_Proxy *new_proxy,
00105                               const ACE_TCHAR *client_id)
00106   : cond_var_ (lock_),
00107     next_ (0),
00108     // This const typecast is safe.
00109     proxy_ ((ACE_Token_Proxy *) new_proxy),
00110     nesting_level_ (0),
00111     sleep_hook_ (0)
00112 {
00113   ACE_TRACE ("ACE_TPQ_Entry::ACE_TPQ_Entry");
00114 
00115   if (client_id != 0)
00116     this->client_id (client_id);
00117   else
00118     {
00119       // Just make sure we have enough space.
00120       ACE_TCHAR host_name[MAXHOSTNAMELEN];
00121       ACE_TCHAR name[(sizeof host_name / sizeof (ACE_TCHAR)) + 256];
00122       ACE_OS::hostname (host_name, sizeof host_name);
00123 
00124       ACE_thread_t thread_id = ACE_Thread::self ();
00125 
00126       // The cast is an attempt to get this to compile (and run,
00127       // hopefully) regardless of the type of ACE_thread_t.
00128       ACE_OS::sprintf (name,
00129                        ACE_TEXT ("/%s/%u/%lu"),
00130                        host_name,
00131                        static_cast<u_int> (ACE_OS::getpid ()),
00132                        *reinterpret_cast<u_long *> (&thread_id));
00133 
00134       this->client_id (name);
00135     }
00136 }
00137 
00138 ACE_TPQ_Entry::ACE_TPQ_Entry (void)
00139   : cond_var_ (lock_),
00140     proxy_ (0),
00141     nesting_level_ (0),
00142     sleep_hook_ (0)
00143 {
00144   ACE_TRACE ("ACE_TPQ_Entry::ACE_TPQ_Entry null const.");
00145 }
00146 
00147 ACE_TPQ_Entry::ACE_TPQ_Entry (const ACE_TPQ_Entry &rhs)
00148 : cond_var_ (lock_)
00149 {
00150   ACE_TRACE ("ACE_TPQ_Entry::ACE_TPQ_Entry copy const.");
00151   *this = rhs;
00152 }
00153 
00154 ACE_TPQ_Entry::~ACE_TPQ_Entry (void)
00155 {
00156   ACE_TRACE ("ACE_TPQ_Entry::~ACE_TPQ_Entry");
00157 }
00158 
00159 void
00160 ACE_TPQ_Entry::operator= (const ACE_TPQ_Entry& rhs)
00161 {
00162   ACE_TRACE ("ACE_TPQ_Entry::operator=");
00163   if (&rhs == this)
00164     return;
00165   this->proxy_ = rhs.proxy ();
00166   this->nesting_level_ = rhs.nesting_level ();
00167   this->client_id (rhs.client_id ());
00168   this->sleep_hook_ = rhs.sleep_hook ();
00169 }
00170 
00171 void
00172 ACE_TPQ_Entry::client_id (const ACE_TCHAR *id)
00173 {
00174   ACE_TRACE ("ACE_TPQ_Entry::client_id");
00175 
00176   if (id == 0)
00177     return;
00178 
00179   ACE_OS::strsncpy (this->client_id_,
00180                     (ACE_TCHAR *) id,
00181                     ACE_MAXCLIENTIDLEN);
00182 }
00183 
00184 ACE_TSS_TPQ_Entry::~ACE_TSS_TPQ_Entry (void)
00185 {
00186 }
00187 
00188 void
00189 ACE_TSS_TPQ_Entry::dump (void) const
00190 {
00191 #if defined (ACE_HAS_DUMP)
00192   ACE_TRACE ("ACE_TSS_TPQ_Entry::dump");
00193   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00194   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("ACE_TSS_TPQ_Entry::dump:\n")
00195                         ACE_TEXT (" client_id_ = %s\n"),
00196                         client_id_ == 0 ? ACE_TEXT ("0") : client_id_));
00197   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("base:\n")));
00198   ACE_TPQ_ENTRY::dump ();
00199   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00200 #endif /* ACE_HAS_DUMP */
00201 }
00202 
00203 ACE_TSS_TPQ_Entry::ACE_TSS_TPQ_Entry (const ACE_Token_Proxy *proxy,
00204                                       const ACE_TCHAR *client_id)
00205 : proxy_ (proxy),
00206   client_id_ (client_id)
00207 {
00208   ACE_TRACE ("ACE_TSS_TPQ_Entry::ACE_TSS_TPQ_Entry");
00209 }
00210 
00211 ACE_TPQ_Entry *
00212 ACE_TSS_TPQ_Entry::make_TSS_TYPE (void) const
00213 {
00214   ACE_TRACE ("ACE_TSS_TPQ_Entry::make_TSS_TYPE");
00215   ACE_TPQ_Entry *temp;
00216 
00217   ACE_NEW_RETURN (temp,
00218                   ACE_TPQ_Entry (this->proxy_,
00219                                  this->client_id_),
00220                   0);
00221   return temp;
00222 }
00223 
00224 ACE_TSS_TPQ_Entry::operator ACE_TPQ_Entry * (void)
00225 {
00226 #if !defined (ACE_NO_TSS_TOKENS)
00227   return  (ACE_TPQ_Entry *) (*((ACE_TSS<ACE_TPQ_Entry> *) this));
00228 #else
00229   // Not sure this is the right thing to do, but it seems to work.
00230   // The base class ALSO has a proxy_ and client_id_ members (weird?)
00231   // which don't get initialised.  The following two lines make this
00232   // the same as the subclass, so that the slicing works .
00233   ACE_TPQ_ENTRY::proxy ((ACE_Token_Proxy *)(this->proxy_));
00234   ACE_TPQ_ENTRY::client_id (this->client_id_);
00235   return  (ACE_TPQ_Entry *) this;;
00236 #endif /* !ACE_NO_TSS_TOKENS */
00237 }
00238 
00239 ACE_TPQ_Iterator::ACE_TPQ_Iterator (ACE_Token_Proxy_Queue &q)
00240   : current_ (q.head_)
00241 {
00242   ACE_TRACE ("ACE_TPQ_Iterator::ACE_TPQ_Iterator");
00243 }
00244 
00245 int
00246 ACE_TPQ_Iterator::next (ACE_TPQ_Entry *&next_item)
00247 {
00248   ACE_TRACE ("ACE_TPQ_Iterator::next");
00249 
00250   next_item = this->current_;
00251 
00252   return current_ != 0;
00253 }
00254 
00255 int
00256 ACE_TPQ_Iterator::done (void) const
00257 {
00258   ACE_TRACE ("ACE_TPQ_Iterator::done");
00259 
00260   return this->current_ == 0;
00261 }
00262 
00263 void
00264 ACE_TPQ_Iterator::advance (void)
00265 {
00266   ACE_TRACE ("ACE_TPQ_Iterator::advance");
00267 
00268   if (current_ != 0)
00269     this->current_ = this->current_->next_;
00270 }
00271 
00272 void
00273 ACE_TPQ_Iterator::dump (void) const
00274 {
00275 #if defined (ACE_HAS_DUMP)
00276   ACE_TRACE ("ACE_TPQ_Iterator::dump");
00277   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00278   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("ACE_TPQ_Iterator::dump:\n")
00279               ACE_TEXT (" current_ = %d\n"),
00280               (long) this->current_));
00281   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("head_ and tail_\n")));
00282   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00283 #endif /* ACE_HAS_DUMP */
00284 }
00285 
00286 void
00287 ACE_Token_Proxy_Queue::dump (void) const
00288 {
00289 #if defined (ACE_HAS_DUMP)
00290   ACE_TRACE ("ACE_Token_Proxy_Queue::dump");
00291   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00292   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Token_Proxy_Queue::dump:\n")
00293                         ACE_TEXT (" size_ = %d\n"),
00294                         size_));
00295   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("head_ and tail_\n")));
00296   if (this->head_ != 0)
00297     this->head_->dump ();
00298 
00299   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Token_Proxy_Queue::dump end.\n")));
00300   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00301 #endif /* ACE_HAS_DUMP */
00302 }
00303 
00304 ACE_Token_Proxy_Queue::ACE_Token_Proxy_Queue (void)
00305   : head_ (0),
00306     tail_ (0),
00307     size_ (0)
00308 {
00309   ACE_TRACE ("ACE_Token_Proxy_Queue::ACE_Token_Proxy_Queue");
00310 }
00311 
00312 void
00313 ACE_Token_Proxy_Queue::enqueue (ACE_TPQ_Entry *tpq,
00314                                 int position)
00315 {
00316   ACE_TRACE ("ACE_Token_Proxy_Queue::enqueue");
00317   tpq->next_ = 0;
00318 
00319   ++this->size_;
00320 
00321   if (this->head_ == 0)
00322     {
00323       // make tpq the entire list
00324       this->head_ = this->tail_ = tpq;
00325       return;
00326     }
00327 
00328   if (position == 0)
00329     {
00330       // make head of list
00331       tpq->next_ = this->head_;
00332       this->head_ = tpq;
00333       return;
00334     }
00335 
00336   if (position == -1)
00337     {
00338       // stick at back of list
00339       this->tail_->next_ = tpq;
00340       this->tail_ = tpq;
00341       return;
00342     }
00343 
00344   // walk through list to insertion point
00345   ACE_TPQ_Entry *temp = head_;
00346 
00347   for (int x = position;
00348        x > 1;
00349        --x)
00350     {
00351       // end of queue?
00352       if (temp->next_ == 0)
00353         break;
00354       // advance pointer
00355       else
00356         temp = temp->next_;
00357     }
00358 
00359   // insert new tpq after temp
00360   tpq->next_ = temp->next_;
00361   temp->next_ = tpq;
00362 }
00363 
00364 void
00365 ACE_Token_Proxy_Queue::dequeue (void)
00366 {
00367   ACE_TRACE ("ACE_Token_Proxy_Queue::dequeue");
00368 
00369   if (head_ == 0)
00370     return;
00371 
00372   ACE_TPQ_Entry *temp = this->head_;
00373 
00374   this->head_ = this->head_->next_;
00375 
00376   temp->next_ = 0;
00377 
00378   --this->size_;
00379 
00380   if (this->head_ == 0 && this->size_ != 0)
00381     ACE_ERROR ((LM_ERROR,
00382                 ACE_TEXT ("incorrect size = %d\n"),
00383                 this->size_));
00384 }
00385 
00386 /*
00387 int
00388 ACE_Token_Proxy_Queue::member (const ACE_TCHAR *id)
00389 {
00390   ACE_TRACE ("ACE_Token_Proxy_Queue::member");
00391 
00392   for (ACE_TPQ_Entry *temp = this->head_;
00393        temp != 0;
00394        temp = temp->next_)
00395     if (ACE_OS::strcmp (temp->client_id (), id) == 0)
00396       // We found it!
00397       return 1;
00398 
00399   // We didn't find it :-(
00400   return 0;
00401 }
00402 */
00403 
00404 void
00405 ACE_Token_Proxy_Queue::remove (const ACE_TPQ_Entry *remove_me)
00406 {
00407   ACE_TRACE ("ACE_Token_Proxy_Queue::remove");
00408   // sanity
00409   if ((remove_me == 0) || (this->head_ == 0))
00410     return;
00411 
00412   // is it the head?
00413   if (this->head_ == remove_me) // pointer comparison.
00414     {
00415       this->head_ = this->head_->next_;
00416       if (this->head_ == 0)
00417         this->tail_ = 0;
00418 
00419       --this->size_;
00420       return;
00421     }
00422 
00423   ACE_TPQ_Entry *temp = this->head_;
00424   ACE_TPQ_Entry *previous = 0;
00425 
00426   // is it in the middle or tail?
00427   while (temp != 0)
00428     {
00429       if (temp == remove_me)
00430         {
00431           // previous should never be null since the first if
00432           // conditional should always be false
00433           previous->next_ = temp->next_;
00434           // is it the tail?
00435           if (this->tail_ == temp)
00436             this->tail_ = previous;
00437 
00438           --this->size_;
00439           return;
00440         }
00441 
00442       previous = temp;
00443       temp = temp->next_;
00444     }
00445 
00446   // it wasn't in the list.
00447   return;
00448 }
00449 
00450 void
00451 ACE_Mutex_Token::dump (void) const
00452 {
00453 #if defined (ACE_HAS_DUMP)
00454   ACE_TRACE ("ACE_Mutex_Token::dump");
00455   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00456   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("ACE_Mutex_Token::dump:\n")));
00457   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("lock_\n")));
00458   lock_.dump ();
00459   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("base:\n")));
00460   ACE_Tokens::dump ();
00461   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("ACE_Mutex_Token::dump end.\n")));
00462   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00463 #endif /* ACE_HAS_DUMP */
00464 }
00465 
00466 ACE_Mutex_Token::ACE_Mutex_Token (const ACE_TCHAR *name)
00467 {
00468   ACE_TRACE ("ACE_Mutex_Token::ACE_Mutex_Token");
00469 
00470   ACE_OS::strsncpy (this->token_name_,
00471                     name,
00472                     ACE_MAXTOKENNAMELEN);
00473 }
00474 
00475 ACE_Mutex_Token::~ACE_Mutex_Token (void)
00476 {
00477   ACE_TRACE ("ACE_Mutex_Token::~ACE_Mutex_Token");
00478 }
00479 
00480 int
00481 ACE_Mutex_Token::acquire (ACE_TPQ_Entry *caller,
00482                           int ignore_deadlock,
00483                           int notify)
00484 {
00485   ACE_TRACE ("ACE_Mutex_Token::acquire");
00486   // We need to acquire two locks. This one to ensure that only one
00487   // thread uses this token at a time.
00488   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
00489   // This one to ensure an atomic transaction across all tokens.  Note
00490   // that this order is crucial too.  It's resource coloring for other
00491   // threads which may be calling this same token.
00492   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1);
00493 
00494   // Does _anyone_ own the token?
00495   if (this->owner () == 0)
00496     {
00497       // there are no waiters, so queue as the first waiter (the owner.)
00498       this->waiters_.enqueue (caller, -1);
00499       return 0;  // success
00500     }
00501 
00502   // Does the caller already own it?
00503   if (this->is_owner (caller->client_id ()))
00504     {
00505       // Recursive acquisition.
00506       caller->nesting_level (1);
00507       return 0; // success
00508     }
00509 
00510   // Check for deadlock.
00511   if (!ignore_deadlock
00512       && ACE_Token_Manager::instance ()->check_deadlock (caller->proxy ()) == 1)
00513     {
00514       errno = EDEADLK;
00515       ACE_RETURN (-1);
00516     }
00517 
00518   // Someone owns it. Sorry, you're getting queued up at the end of
00519   // the waiter queue.
00520   this->waiters_.enqueue (caller, -1);
00521 
00522   if (notify)
00523     this->owner ()->call_sleep_hook ();
00524 
00525   errno = EWOULDBLOCK;
00526   ACE_RETURN (-1);
00527 
00528   ACE_NOTREACHED (return -1);
00529 }
00530 
00531 int
00532 ACE_Mutex_Token::tryacquire (ACE_TPQ_Entry *caller)
00533 {
00534   ACE_TRACE ("ACE_Mutex_Token::tryacquire");
00535   // We need to acquire two locks. This one to ensure that only one
00536   // thread uses this token at a time.
00537   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
00538   // This one to ensure an atomic transaction across all tokens.  Note
00539   // that this order is crucial too.  It's resource coloring for other
00540   // threads which may be calling this same token.
00541   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1);
00542 
00543   // Does _anyone_ own the token?
00544   if (this->owner () == 0)
00545     {
00546       this->waiters_.enqueue (caller, -1);
00547       return 0;  // success
00548     }
00549   // Does the caller already own it?
00550   if (this->is_owner (caller->client_id ()))
00551     {
00552       // recursive acquisition
00553       caller->nesting_level (1);
00554       return 0;  // success
00555     }
00556   else
00557     // Someone owns it.  Fail.
00558     {
00559       errno = EWOULDBLOCK;
00560       ACE_RETURN (-1);
00561     }
00562 
00563   ACE_NOTREACHED (return -1);
00564 }
00565 
00566 int
00567 ACE_Mutex_Token::renew (ACE_TPQ_Entry *caller,
00568                         int requeue_position)
00569 {
00570   ACE_TRACE ("ACE_Mutex_Token::renew");
00571   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1);
00572 
00573   // Verify that the caller is the owner.
00574   if (this->is_owner (caller->client_id ()) == 0)
00575     {
00576       errno = EACCES;
00577       ACE_RETURN (-1);
00578     }
00579 
00580   // The caller is the owner, so check to see if there are any
00581   // waiters.  If not, we just keep the token.  == 1 means that there
00582   // is only the owner.
00583   if (this->waiters_.size () == 1 || requeue_position == 0)
00584     return 0;
00585 
00586   // Requeue the caller.
00587   this->waiters_.dequeue ();
00588 
00589   this->waiters_.enqueue (caller, requeue_position);
00590 
00591   // Notify new owner.
00592   if (this->owner () != 0)
00593     this->owner ()->proxy ()->token_acquired (this->owner ());
00594 
00595   // Tell the caller that the operation would block.
00596   errno = EWOULDBLOCK;
00597   ACE_RETURN (-1);
00598 
00599   ACE_NOTREACHED (return -1);
00600 }
00601 
00602 // Release the current holder of the token (which had
00603 // better be the caller's thread!).
00604 
00605 int
00606 ACE_Mutex_Token::release (ACE_TPQ_Entry *caller)
00607 {
00608   ACE_TRACE ("ACE_Mutex_Token::release");
00609   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1);
00610 
00611   // Does anyone own the token?
00612   if (this->owner () == 0)
00613     {
00614       errno = EACCES;
00615       ACE_RETURN (-1);
00616     }
00617 
00618   // Is the caller the owner.
00619   if (this->is_owner (caller->client_id ()))
00620     {
00621       // Check the nesting level.
00622       if (caller->nesting_level () > 0)
00623         caller->nesting_level (-1);
00624       else
00625         {
00626           this->waiters_.dequeue ();
00627           // Notify new owner.
00628           if (this->owner () != 0)
00629             this->owner ()->proxy ()->token_acquired (this->owner ());
00630         }
00631     }
00632   else
00633     this->remove (caller);
00634 
00635   return 0;
00636 }
00637 
00638 int
00639 ACE_Mutex_Token::owners (OWNER_STACK &stack,
00640                          const ACE_TCHAR *id)
00641 {
00642   ACE_TRACE ("ACE_Mutex_Token::owners");
00643   if (this->owner () != 0)
00644     {
00645       stack.push (this->owner ());
00646       // If an <id> is specified, return whether it is the owner being
00647       // returned.
00648       if (id != 0)
00649         return this->owner ()->equal_client_id (id);
00650     }
00651 
00652   return 0;
00653 }
00654 
00655 int
00656 ACE_Mutex_Token::is_waiting_for (const ACE_TCHAR *id)
00657 {
00658   ACE_TRACE ("ACE_Mutex_Token::is_waiting_for");
00659   // If there is no owner, or <id> is the owner, return false.
00660   if ((this->owner () == 0) || this->is_owner (id))
00661     return 0;
00662 
00663   // Step through each waiter looking for <id>.
00664   ACE_TPQ_Iterator iterator (waiters_);
00665   iterator.advance ();
00666   for (ACE_TPQ_Entry *temp = 0;
00667        iterator.next (temp) != 0;
00668        iterator.advance ())
00669     {
00670       if (temp->equal_client_id (id))
00671         return 1;
00672     }
00673 
00674   return 0;
00675 }
00676 
00677 int
00678 ACE_Mutex_Token::is_owner (const ACE_TCHAR *id)
00679 {
00680   ACE_TRACE ("ACE_Mutex_Token::is_owner");
00681   // If there is an owner, return whether it is <id>.
00682   if ((this->owner () != 0) &&
00683       this->owner ()->equal_client_id (id))
00684     return 1;
00685   else
00686     return 0;
00687 }
00688 
00689 int
00690 ACE_Mutex_Token::type (void) const
00691 {
00692   ACE_TRACE ("ACE_Mutex_Token::type");
00693   return (int) ACE_Tokens::MUTEX;
00694 }
00695 
00696 // ************************************************************
00697 
00698 int
00699 ACE_RW_Token::type (void) const
00700 {
00701   ACE_TRACE ("ACE_RW_Token::type");
00702   return (int) ACE_Tokens::RWLOCK;
00703 }
00704 
00705 void
00706 ACE_RW_Token::dump (void) const
00707 {
00708 #if defined (ACE_HAS_DUMP)
00709   ACE_TRACE ("ACE_RW_Token::dump");
00710   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00711   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("ACE_RW_Token::dump:\n")
00712                         ACE_TEXT ("num_writers_ = %d\n"), num_writers_));
00713   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("lock_\n")));
00714   this->lock_.dump ();
00715   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("base:\n")));
00716   ACE_Tokens::dump ();
00717   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("ACE_RW_Token::dump end.\n")));
00718   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00719 #endif /* ACE_HAS_DUMP */
00720 }
00721 
00722 ACE_RW_Token::ACE_RW_Token (const ACE_TCHAR *name)
00723 : num_writers_ (0)
00724 {
00725   ACE_TRACE ("ACE_RW_Token::ACE_RW_Token");
00726 
00727   ACE_OS::strsncpy (this->token_name_,
00728                     name,
00729                     ACE_MAXTOKENNAMELEN);
00730 }
00731 
00732 ACE_RW_Token::~ACE_RW_Token (void)
00733 {
00734   ACE_TRACE ("ACE_RW_Token::~ACE_RW_Token");
00735 }
00736 
00737 int
00738 ACE_RW_Token::acquire (ACE_TPQ_Entry *caller,
00739                        int ignore_deadlock,
00740                        int notify)
00741 {
00742   ACE_TRACE ("ACE_RW_Token::acquire");
00743   // We need to acquire two locks. This one to ensure that only one
00744   // thread uses this token at a time.
00745   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
00746   // This one to ensure an atomic transaction across all tokens.  Note
00747   // that this order is crucial too.  It's resource coloring for other
00748   // threads which may be calling this same token.
00749   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1);
00750 
00751   if (caller->proxy ()->type () == ACE_RW_Token::WRITER)
00752     this->num_writers_++;
00753 
00754   // Does _anyone_ own the token?
00755   if (this->owner () == 0)
00756     {
00757       // There are no waiters, so queue as the first waiter (the owner).
00758       this->waiters_.enqueue (caller, -1);
00759       return 0;
00760     }
00761 
00762   // Check for recursive acquisition.
00763   if (this->is_owner (caller->client_id ()))
00764     {
00765       caller->nesting_level (1);
00766       return 0;  // Success.
00767     }
00768 
00769   // Reader.
00770   if (caller->proxy ()->type () == ACE_RW_Token::READER)
00771     {
00772       // Are there any writers?
00773       if (this->num_writers_ == 0)
00774         {
00775           // Queue the caller at the end of the queue.
00776           this->waiters_.enqueue (caller, -1);
00777           return 0;
00778         }
00779       // Else failure.
00780     }
00781 
00782   // Failure code.
00783 
00784   // Check for deadlock.
00785   if (!ignore_deadlock &&
00786       ACE_Token_Manager::instance ()->check_deadlock (caller->proxy ()) == 1)
00787     {
00788       if (caller->proxy ()->type () == ACE_RW_Token::WRITER)
00789         this->num_writers_--;
00790       errno = EDEADLK;
00791       ACE_RETURN (-1);
00792     }
00793 
00794   // Queue the caller at the end of the queue.
00795   this->waiters_.enqueue (caller, -1);
00796 
00797   if (notify)
00798     {
00799       // If it's a writer, just notify it.
00800       if (this->owner ()->proxy ()->type () == ACE_RW_Token::WRITER)
00801         this->owner ()->call_sleep_hook ();
00802       else
00803         {
00804           // Call back all reader owners.
00805           ACE_TPQ_Entry *temp = this->owner ();
00806           do
00807             {
00808               temp->call_sleep_hook ();
00809               temp = temp->next_;
00810             }
00811           while (temp != 0 &&
00812                  temp->proxy ()->type () == ACE_RW_Token::READER);
00813         }
00814     }
00815 
00816   errno = EWOULDBLOCK;
00817   ACE_RETURN (-1);
00818 
00819   ACE_NOTREACHED (return -1);
00820 }
00821 
00822 int
00823 ACE_RW_Token::tryacquire (ACE_TPQ_Entry *caller)
00824 {
00825   ACE_TRACE ("ACE_RW_Token::tryacquire");
00826   // We need to acquire two locks. This one to ensure that only one
00827   // thread uses this token at a time.
00828   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
00829   // This one to ensure an atomic transaction across all tokens.  Note
00830   // that this order is crucial too.  It's resource coloring for other
00831   // threads which may be calling this same token.
00832   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1);
00833 
00834   if (caller->proxy ()->type () == ACE_RW_Token::WRITER)
00835     {
00836       this->num_writers_++;
00837     }
00838 
00839   // Does _anyone_ own the token?
00840   if (this->owner () == 0)
00841     {
00842       // There are no waiters, so queue as the first waiter (the owner).
00843       this->waiters_.enqueue (caller, -1);
00844       return 0;
00845     }
00846 
00847   // Check for recursive acquisition.
00848   if (this->is_owner (caller->client_id ()))
00849     {
00850       caller->nesting_level (1);
00851       return 0;  // Success.
00852     }
00853 
00854   // Reader.
00855   if (caller->proxy ()->type () == ACE_RW_Token::READER)
00856     {
00857       // Are there any writers?
00858       if (this->num_writers_ == 0)
00859         {
00860           // queue the caller at the end of the queue.
00861           this->waiters_.enqueue (caller, -1);
00862           return 0;
00863         }
00864       // Else, fail.
00865     }
00866   else // Writer.
00867     // We're going to fail, so decrement the num_writers.
00868     {
00869       this->num_writers_--;
00870     }
00871 
00872 
00873   errno = EWOULDBLOCK;
00874   ACE_RETURN (-1);
00875 
00876   ACE_NOTREACHED (return -1);
00877 }
00878 
00879 int
00880 ACE_RW_Token::renew (ACE_TPQ_Entry *caller,
00881                      int requeue_position)
00882 {
00883   ACE_TRACE ("ACE_RW_Token::renew");
00884   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1);
00885 
00886   // Werify that the caller is the owner
00887   if (this->is_owner (caller->client_id ()) == 0)
00888     {
00889       errno = EACCES;
00890       ACE_RETURN (-1);
00891     }
00892 
00893   // The caller is the owner, so check to see if there are any
00894   // waiters.  If not, we just keep the token.
00895   if (this->waiters_.size () == 1 || requeue_position == 0)
00896     return 0;
00897 
00898   // There are waiters, so remove the caller.
00899   this->remove (caller);
00900 
00901   // Requeue the caller.
00902   this->waiters_.enqueue (caller, requeue_position);
00903 
00904   if (caller->proxy ()->type () == ACE_RW_Token::READER)
00905     {
00906       // If the caller got queued before any writers, the caller is
00907       // still the owner.
00908       if (this->is_owner (caller->client_id ()))
00909         return 0; // success
00910       // else fallthrough and return would block.
00911     }
00912   // Writers will always have to block since waiters_.size () == 1 or
00913   // requeue_position == 0.
00914 
00915   // Get a new owner.
00916   this->notify_new_owner (caller);
00917 
00918   // Tell the caller that the operation would block.
00919   errno = EWOULDBLOCK;
00920   ACE_RETURN (-1);
00921 
00922   ACE_NOTREACHED (return -1);
00923 }
00924 
00925 int
00926 ACE_RW_Token::release (ACE_TPQ_Entry *caller)
00927 {
00928   ACE_TRACE ("ACE_RW_Token::release");
00929   ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1);
00930 
00931   // Check for errors.
00932   if ((this->owner () == 0) ||
00933       (this->is_owner (caller->client_id ()) == 0))
00934     {
00935       errno = EACCES;
00936       ACE_RETURN (-1);
00937     }
00938 
00939   if (caller->proxy ()->type () == ACE_RW_Token::WRITER)
00940     num_writers_--;
00941 
00942   // Recursive release.
00943   if (caller->nesting_level () > 0)
00944     {
00945       caller->nesting_level (-1);
00946       return 0;
00947     }
00948 
00949   // Remove the caller and notify the new owner(s).
00950   this->remove (caller);
00951   this->notify_new_owner (caller);
00952 
00953   return 0;
00954 }
00955 
00956 void
00957 ACE_RW_Token::notify_new_owner (ACE_TPQ_Entry *old_owner)
00958 {
00959   ACE_TRACE ("ACE_RW_Token::notify_new_owner");
00960 
00961   if (this->owner () == 0)
00962     return;
00963 
00964   if (this->owner ()->proxy ()->type () == ACE_RW_Token::READER)
00965     {
00966       if (old_owner->proxy ()->type () == ACE_RW_Token::READER)
00967         // the owners already know that they're owners
00968         return;
00969 
00970       // The current owner is a reader and the previous owner was a
00971       // writer, so notify all waiting readers up to the first writer.
00972       // call back all reader owners.
00973       ACE_TPQ_Iterator iterator (waiters_);
00974       for (ACE_TPQ_Entry *temp = 0;
00975            iterator.next (temp) != 0;
00976            iterator.advance ())
00977         {
00978           if (temp->proxy ()->type () == WRITER)
00979             // We've gone through all the readers.
00980             break;
00981 
00982           temp->proxy ()->token_acquired (temp);
00983         }
00984     }
00985   else // writer
00986     this->owner ()->proxy ()->token_acquired (this->owner ());
00987 }
00988 
00989 
00990 int
00991 ACE_RW_Token::owners (OWNER_STACK &stack,
00992                       const ACE_TCHAR *id)
00993 {
00994   ACE_TRACE ("ACE_RW_Token::owners");
00995 
00996   if (this->owner () == 0)
00997     return 0;
00998 
00999   int id_is_owner = 0;
01000 
01001   // The first waiter is a writer, so there is only one owner.
01002   if (this->owner ()->proxy ()->type () == WRITER)
01003     {
01004       stack.push (this->owner ());
01005       // If an <id> is specified, return whether it is the owner being
01006       // returned.
01007       if ((id != 0) &&
01008           (ACE_OS::strcmp (id, this->owner ()->client_id ()) == 0))
01009         id_is_owner = 1;
01010     }
01011   // The first waiter is a reader, so there can be multiple owning
01012   // readers.
01013   else
01014     {
01015       ACE_TPQ_Iterator iterator (waiters_);
01016       for (ACE_TPQ_Entry *temp = 0;
01017            iterator.next (temp) != 0;
01018            iterator.advance ())
01019         {
01020           if (temp->proxy ()->type () == WRITER)
01021             // We've gone through all the readers.
01022             break;
01023 
01024           stack.push (temp);
01025 
01026           if (!id_is_owner && (id != 0) &&
01027               (ACE_OS::strcmp (id, temp->client_id ()) == 0))
01028             id_is_owner = 1;
01029         }
01030     }
01031 
01032   return id_is_owner;
01033 }
01034 
01035 int
01036 ACE_RW_Token::is_waiting_for (const ACE_TCHAR *id)
01037 {
01038   ACE_TRACE ("ACE_RW_Token::is_waiting_for");
01039   // If there is no owner, or <id> is the owner, return false.
01040   if ((this->owner () == 0) ||
01041       this->is_owner (id))
01042     return 0;
01043 
01044   // Step through each waiter looking for <id>.
01045   ACE_TPQ_Iterator iterator (waiters_);
01046   iterator.advance ();
01047   for (ACE_TPQ_Entry *temp = 0;
01048        iterator.next (temp) != 0;
01049        iterator.advance ())
01050     {
01051       if (temp->equal_client_id (id))
01052         return 1;
01053     }
01054 
01055   return 0;
01056 }
01057 
01058 int
01059 ACE_RW_Token::is_owner (const ACE_TCHAR *id)
01060 {
01061   ACE_TRACE ("ACE_RW_Token::is_owner");
01062   // If there is no owner, return false.
01063   if (this->owner () == 0)
01064     return 0;
01065 
01066   // A writer owns us.
01067   if (this->owner ()->proxy ()->type () == ACE_RW_Token::WRITER)
01068     return this->owner ()->equal_client_id (id);
01069 
01070   // Readers own us.
01071   // Step through each owning reader looking for <id>.
01072   ACE_TPQ_Iterator iterator (waiters_);
01073   for (ACE_TPQ_Entry *temp = 0;
01074        iterator.next (temp) != 0;
01075        iterator.advance ())
01076     {
01077       if (temp->proxy ()->type () != ACE_RW_Token::READER)
01078         break;
01079 
01080       if (temp->equal_client_id (id))
01081         return 1;
01082     }
01083 
01084   return 0;
01085 }
01086 
01087 void
01088 ACE_Token_Proxy::dump (void) const
01089 {
01090 #if defined (ACE_HAS_DUMP)
01091   ACE_TRACE ("ACE_Token_Proxy::dump");
01092   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
01093   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("ACE_Token_Proxy::dump:\n")
01094                         ACE_TEXT (" type = %d\n")
01095                         ACE_TEXT (" ignore_deadlock_ = %d\n")
01096                         ACE_TEXT (" debug_ = %d\n"),
01097                         (int) this->type (), ignore_deadlock_, debug_));
01098   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("mutex_, and waiter_\n")));
01099 
01100   if (this->token_ != 0)
01101     this->token_->dump ();
01102 
01103   this->waiter_.dump ();
01104   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Token_Proxy::dump end.\n")));
01105   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
01106 #endif /* ACE_HAS_DUMP */
01107 }
01108 
01109 const ACE_TCHAR *
01110 ACE_Token_Proxy::client_id (void) const
01111 {
01112   ACE_TRACE ("ACE_Token_Proxy::client_id");
01113   // Thread-specific.
01114   const ACE_TPQ_Entry *temp = this->waiter_.operator->();
01115   const ACE_TCHAR *id = temp->client_id ();
01116 
01117   if (id == 0)
01118     return ACE_TEXT ("ERROR NO CLIENT ID");
01119   else
01120     return id;
01121 }
01122 
01123 void
01124 ACE_Token_Proxy::client_id (const ACE_TCHAR *client_id)
01125 {
01126   ACE_TRACE ("ACE_Token_Proxy::client_id");
01127   this->waiter_->client_id (client_id);
01128 }
01129 
01130 const ACE_TCHAR *
01131 ACE_Token_Proxy::owner_id (void)
01132 {
01133   ACE_TRACE ("ACE_Token_Proxy::owner_id");
01134   return this->token_->owner_id ();
01135 }
01136 
01137 const ACE_TCHAR *
01138 ACE_Token_Proxy::name (void) const
01139 {
01140   ACE_TRACE ("ACE_Token_Proxy::name");
01141   return this->token_->name ();
01142 }
01143 
01144 #if defined (ACE_WIN32_VC8)
01145 #  pragma warning (push)
01146 #  pragma warning (disable:4355)  /* Use of 'this' in initializer list */
01147 #endif
01148 ACE_Token_Proxy::ACE_Token_Proxy (void)
01149 : token_ (0),
01150   waiter_ (this, 0)
01151 {
01152   ACE_TRACE ("ACE_Token_Proxy::ACE_Token_Proxy");
01153 }
01154 
01155 // Notice the token_ (0).  Do *not* copy the token pointer.  This must
01156 // be obtained through the token manager.  Also, we don't copy any
01157 // waiter info.  A copied Proxy does *not* inherit client_id.
01158 
01159 ACE_Token_Proxy::ACE_Token_Proxy (const ACE_Token_Proxy &)
01160   : token_ (0),
01161     waiter_ (this, 0)
01162 {
01163   ACE_TRACE ("ACE_Token_Proxy::ACE_Token_Proxy");
01164 }
01165 #if defined (ACE_WIN32_VC8)
01166 #  pragma warning (pop)
01167 #endif
01168 
01169 // @@ should I do a mutex_->release ()?
01170 ACE_Token_Proxy::~ACE_Token_Proxy (void)
01171 {
01172   ACE_TRACE ("ACE_Token_Proxy::~ACE_Token_Proxy");
01173 
01174   if (token_ != 0)
01175     // notify token manager that we are done with it so it can
01176     // free it if necessary
01177     ACE_Token_Manager::instance ()->release_token (token_);
01178 }
01179 
01180 int
01181 ACE_Token_Proxy::open (const ACE_TCHAR *token_name,
01182                        int ignore_deadlock,
01183                        int debug)
01184 {
01185   ACE_TRACE ("ACE_Token_Proxy::open");
01186 
01187   // Store some parameters.
01188   this->ignore_deadlock_ = ignore_deadlock;
01189   this->debug_ = debug;
01190 
01191   // Used in case a name was not specified.
01192   ACE_TCHAR name[BUFSIZ];
01193 
01194   // We must have a name.
01195   if (token_name == 0)
01196     {
01197       ACE_OS::sprintf (name, ACE_TEXT ("token %lx"),
01198                        reinterpret_cast<long> (this));
01199       token_name = name;
01200     }
01201 
01202   // Get or create the underlying token.  The Token Manager will call
01203   // us back to set token_.
01204   ACE_Token_Manager::instance ()->get_token (this, token_name);
01205 
01206   // Check for failed get or failed new.
01207   if (this->token_ == 0)
01208     {
01209       errno = ENOMEM;
01210       ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("Can't allocate mutex")), -1);
01211     }
01212 
01213   return 0;
01214 }
01215 
01216 int
01217 ACE_Token_Proxy::acquire (int notify,
01218                           void (*sleep_hook)(void *),
01219                           ACE_Synch_Options &options)
01220 {
01221   ACE_TRACE ("ACE_Token_Proxy::acquire");
01222   if (this->token_ == 0)
01223     {
01224       errno = ENOENT;
01225       ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("Not open.\n")), -1);
01226     }
01227 
01228   // Make sure no one calls our token_acquired until we have a chance
01229   // to sleep first!  If after we call an EWOULDBLOCK
01230   // mutex_->acquire() below, but before we enter handle_options to
01231   // wait on the cond_var, a thread tries to give take us off the
01232   // waiter queue and signal us, IT WILL FIRST HAVE TO ACQUIRE THIS
01233   // cond_var.mutex ().  _This_ is why we acquire it.
01234   this->waiter_->cond_var_.mutex ().acquire ();
01235 
01236   this->waiter_->sleep_hook (sleep_hook);
01237 
01238   if (this->token_->acquire (this->waiter_, this->ignore_deadlock_, notify) == -1)
01239     // acquire failed
01240     {
01241       switch (errno)
01242         {
01243         case EDEADLK :
01244           if (!ignore_deadlock_)
01245             {
01246               waiter_->cond_var_.mutex ().release ();
01247               errno = EDEADLK;
01248               ACE_RETURN (-1);
01249             }
01250           // Else, fallthrough and block!
01251 
01252         case EWOULDBLOCK :
01253           if (this->debug_)
01254             ACE_DEBUG ((LM_DEBUG,
01255                         ACE_TEXT ("(%t) waiting for %s, owner is %s, ")
01256                         ACE_TEXT ("total waiters == %d\n"),
01257                         this->name (),
01258                         this->token_->owner_id (),
01259                         token_->no_of_waiters ()));
01260 
01261           // no error, but would block, if error, return error (-1),
01262           // otherwise, return whether we called the holder or not.
01263           int return_value;
01264           if (this->handle_options (options,
01265                                     waiter_->cond_var_) == -1)
01266             return_value = -1;
01267           else
01268             return_value = notify == 1;
01269 
01270           errno = EWOULDBLOCK;
01271           ACE_RETURN (return_value);
01272 
01273         default :
01274           waiter_->cond_var_.mutex ().release ();
01275           ACE_ERROR_RETURN ((LM_ERROR,
01276                              ACE_TEXT ("%p\n"),
01277                              ACE_TEXT ("Token Proxy acquire.")),
01278                             -1);
01279         }
01280     }
01281   else
01282     // we have the token
01283     {
01284       if (debug_)
01285         ACE_DEBUG ((LM_DEBUG,
01286                     ACE_TEXT ("(%t) acquired %s\n"),
01287                     this->name ()));
01288       waiter_->cond_var_.mutex ().release ();
01289     }
01290 
01291   return 0;
01292 }
01293 
01294 int
01295 ACE_Token_Proxy::tryacquire (void (*sleep_hook)(void *))
01296 {
01297   ACE_TRACE ("ACE_Token_Proxy::tryacquire");
01298   if (this->token_ == 0)
01299     {
01300       errno = ENOENT;
01301       ACE_ERROR_RETURN ((LM_ERROR,
01302                          ACE_TEXT ("Not open.\n")),
01303                         -1);
01304     }
01305 
01306   this->waiter_->sleep_hook (sleep_hook);
01307 
01308   return this->token_->tryacquire (waiter_);
01309 }
01310 
01311 int
01312 ACE_Token_Proxy::renew (int requeue_position,
01313                         ACE_Synch_Options &options)
01314 {
01315   ACE_TRACE ("ACE_Token_Proxy::renew");
01316   if (this->token_ == 0)
01317     {
01318       errno = ENOENT;
01319       ACE_ERROR_RETURN ((LM_ERROR,
01320                          ACE_TEXT ("Not open.\n")),
01321                         -1);
01322     }
01323 
01324   // Make sure no one calls our token_acquired until we have a chance
01325   // to sleep first!
01326   this->waiter_->cond_var_.mutex ().acquire ();
01327 
01328   if (this->token_->renew (this->waiter_, requeue_position) == -1)
01329     {
01330       // check for error
01331       if (errno != EWOULDBLOCK)
01332         ACE_ERROR_RETURN ((LM_ERROR,
01333                            ACE_TEXT ("%p renew failed\n"), ACE_TEXT ("ACE_Token_Proxy")), -1);
01334 
01335       if (this->debug_)
01336         ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("(%t) renew blocking for %s, owner is %s\n"),
01337                     this->name (),
01338                     token_->owner_id ()));
01339 
01340       // no error, but would block, so block or return
01341       return this->handle_options (options, waiter_->cond_var_);
01342     }
01343   else
01344     // we have the token
01345     {
01346       if (this->debug_)
01347         ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("(%t) renewed %s\n"),
01348                     this->name ()));
01349       waiter_->cond_var_.mutex ().release ();
01350       return 0;
01351     }
01352 }
01353 
01354 int
01355 ACE_Token_Proxy::handle_options (ACE_Synch_Options &options,
01356                                  ACE_TOKEN_CONST::COND_VAR &cv)
01357 {
01358   // Some operation failed with EWOULDBLOCK.
01359   ACE_TRACE ("ACE_Token_Proxy::handle_options");
01360 
01361   if (options[ACE_Synch_Options::USE_REACTOR] == 1)
01362     // Asynchronous.
01363     {
01364       // Save/restore errno.
01365       ACE_Errno_Guard error (errno);
01366       cv.mutex ().release ();
01367       ACE_RETURN (-1);
01368     }
01369   else
01370     // Synchronous.
01371     {
01372       // Block on condition variable.
01373       while (cv.wait ((ACE_Time_Value *) options.time_value ()) == -1)
01374         {
01375           // Note, this should obey whatever thread-specific
01376           // interrupt policy is currently in place...
01377           if (errno == EINTR)
01378             continue;
01379           // We come here if a timeout occurs or some serious
01380           // ACE_Condition object error.
01381           cv.mutex ().release ();
01382           ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("condition variable wait")
01383                              ACE_TEXT (" bombed.")), -1);
01384         }
01385 
01386       if (this->debug_)
01387         ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("(%t) unblocking %s.\n"),
01388                     this->client_id ()));
01389       cv.mutex ().release ();
01390       return 0;       // operation succeeded
01391     }
01392 }
01393 
01394 int
01395 ACE_Token_Proxy::release (ACE_Synch_Options &)
01396 {
01397   ACE_TRACE ("ACE_Token_Proxy::release");
01398 
01399   if (this->token_ == 0)
01400     {
01401       errno = ENOENT;
01402       if (debug_)
01403         ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("Must open before releasing.\n")));
01404       ACE_RETURN (-1);
01405     }
01406 
01407   if (this->token_->release (waiter_) != 0)
01408     {
01409       // Release failed.
01410       this->token_->remove (this->waiter_);
01411       if (debug_)
01412         ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("(%t) %p.\n"), ACE_TEXT ("release failed")));
01413       return -1;
01414     }
01415   else
01416     {
01417       if (this->debug_)
01418         ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("(%t) released %s, owner is %s\n"),
01419                     this->name (),
01420                     token_->owner_id ()));
01421 
01422       return 0;
01423     }
01424 }
01425 
01426 int
01427 ACE_Token_Proxy::remove (ACE_Synch_Options &)
01428 {
01429   ACE_TRACE ("ACE_Token_Proxy::remove");
01430   return 0;
01431 }
01432 
01433 void
01434 ACE_Token_Proxy::sleep_hook (void)
01435 {
01436   ACE_TRACE ("ACE_Token_Proxy::sleep_hook");
01437   // Somebody wants our token!  (Let'em wait...)
01438   return;
01439 }
01440 
01441 void
01442 ACE_Token_Proxy::token_acquired (ACE_TPQ_Entry *e)
01443 {
01444   ACE_TRACE ("ACE_Token_Proxy::token_acquired");
01445   e->cond_var_.mutex ().acquire ();
01446   // We've been taken off the waiters list and given the token!
01447   // This implementation signals the internal condition
01448   // variable. Thus, if asynchronous acquires are used, this must be
01449   // overriden to do something more useful!
01450   e->cond_var_.signal ();
01451   e->cond_var_.mutex ().release ();
01452 
01453   return;
01454 }
01455 
01456 int
01457 ACE_Token_Proxy::type (void) const
01458 {
01459   ACE_TRACE ("ACE_Token_Proxy::type");
01460   return 0;
01461 }
01462 
01463 int
01464 ACE_Token_Proxy::acquire_read (int notify,
01465                                void (*sleep_hook)(void *),
01466                                ACE_Synch_Options &options)
01467 {
01468   return this->acquire (notify,
01469                         sleep_hook,
01470                         options);
01471 }
01472 
01473 int
01474 ACE_Token_Proxy::acquire_write (int notify,
01475                                 void (*sleep_hook)(void *),
01476                                 ACE_Synch_Options &options)
01477 {
01478   return this->acquire (notify,
01479                         sleep_hook,
01480                         options);
01481 }
01482 
01483 int
01484 ACE_Token_Proxy::tryacquire_read (void (*sleep_hook)(void *))
01485 {
01486   return this->tryacquire (sleep_hook);
01487 }
01488 
01489 int
01490 ACE_Token_Proxy::tryacquire_write (void (*sleep_hook)(void *))
01491 {
01492   return this->tryacquire (sleep_hook);
01493 }
01494 
01495 ACE_Token_Name::ACE_Token_Name (const ACE_TCHAR *token_name)
01496 {
01497   ACE_TRACE ("ACE_Token_Name::ACE_Token_Name");
01498   this->name (token_name);
01499 }
01500 
01501 ACE_Token_Name::ACE_Token_Name (const ACE_Token_Name &rhs)
01502 {
01503   ACE_TRACE ("ACE_Token_Name::ACE_Token_Name");
01504   this->name (rhs.name ());
01505 }
01506 
01507 ACE_Token_Name::~ACE_Token_Name ()
01508 {
01509   ACE_TRACE ("ACE_Token_Name::~ACE_Token_Name");
01510 }
01511 
01512 void
01513 ACE_Token_Name::dump (void) const
01514 {
01515 #if defined (ACE_HAS_DUMP)
01516   ACE_TRACE ("ACE_Token_Name::dump");
01517   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
01518   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("ACE_Token_Name::dump:\n")
01519                         ACE_TEXT (" token_name_ = %s\n"),
01520               token_name_ == 0 ? ACE_TEXT ("no name") : token_name_));
01521   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
01522 #endif /* ACE_HAS_DUMP */
01523 }
01524 
01525 // ************************************************************
01526 
01527 ACE_Token_Proxy *
01528 ACE_Local_Mutex::clone (void) const
01529 {
01530   ACE_Token_Proxy *temp = 0;
01531   ACE_NEW_RETURN (temp,
01532                   ACE_Local_Mutex (token_->name (),
01533                                    ignore_deadlock_,
01534                                    debug_),
01535                   0);
01536   return temp;
01537 }
01538 
01539 ACE_Tokens *
01540 ACE_Local_Mutex::create_token (const ACE_TCHAR *name)
01541 {
01542   ACE_Tokens *temp = 0;
01543   ACE_NEW_RETURN (temp,
01544                   ACE_Mutex_Token (name),
01545                   0);
01546   return temp;
01547 }
01548 
01549 ACE_Local_Mutex::~ACE_Local_Mutex (void)
01550 {
01551 }
01552 
01553 // ************************************************************
01554 
01555 ACE_Local_RLock::~ACE_Local_RLock (void)
01556 {
01557 }
01558 
01559 ACE_Tokens *
01560 ACE_Local_RLock::create_token (const ACE_TCHAR *name)
01561 {
01562   ACE_Tokens *temp = 0;
01563   ACE_NEW_RETURN (temp,
01564                   ACE_RW_Token (name),
01565                   0);
01566   return temp;
01567 }
01568 
01569 int
01570 ACE_Local_RLock::type (void) const
01571 {
01572   return ACE_RW_Token::READER;
01573 }
01574 
01575 ACE_Token_Proxy *
01576 ACE_Local_RLock::clone (void) const
01577 {
01578   ACE_Token_Proxy *temp = 0;
01579   ACE_NEW_RETURN (temp,
01580                   ACE_Local_RLock (token_->name (),
01581                                    ignore_deadlock_,
01582                                    debug_),
01583                   0);
01584   return temp;
01585 }
01586 
01587 // ************************************************************
01588 
01589 ACE_Local_WLock::~ACE_Local_WLock (void)
01590 {
01591 }
01592 
01593 ACE_Tokens *
01594 ACE_Local_WLock::create_token (const ACE_TCHAR *name)
01595 {
01596   ACE_Tokens *temp = 0;
01597   ACE_NEW_RETURN (temp,
01598                   ACE_RW_Token (name),
01599                   0);
01600   return temp;
01601 }
01602 
01603 int
01604 ACE_Local_WLock::type (void) const
01605 {
01606   return ACE_RW_Token::WRITER;
01607 }
01608 
01609 ACE_Token_Proxy *
01610 ACE_Local_WLock::clone (void) const
01611 {
01612   ACE_Token_Proxy *temp = 0;
01613   ACE_NEW_RETURN (temp,
01614                   ACE_Local_WLock (token_->name (),
01615                                    ignore_deadlock_,
01616                                    debug_),
01617                   0);
01618   return temp;
01619 }
01620 
01621 ACE_END_VERSIONED_NAMESPACE_DECL
01622 
01623 #endif /* ACE_HAS_TOKENS_LIBRARY */

Generated on Tue Feb 2 17:18:40 2010 for ACE by  doxygen 1.4.7