Local_Tokens.cpp

Go to the documentation of this file.
00001 // Local_Tokens.cpp,v 4.47 2006/05/30 11:38:43 jwillemsen Exp
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            "Local_Tokens.cpp,v 4.47 2006/05/30 11:38:43 jwillemsen Exp")
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_LIB_TEXT ("ACE_Tokens::dump:\n")
00029                         ACE_LIB_TEXT (" reference_cont_ = %d\n")
00030                         ACE_LIB_TEXT (" token_name_ = %s\n"),
00031                         reference_count_, token_name_));
00032   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_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_LIB_TEXT ("ACE_TPQ_Entry::dump:\n")
00088               ACE_LIB_TEXT (" nesting_level_ = %d\n")
00089               ACE_LIB_TEXT (" client_id_ = %s\n"),
00090               nesting_level_,
00091               client_id_));
00092 
00093   if (next_ != 0)
00094     {
00095       ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("next:.\n")));
00096       next_->dump ();
00097     }
00098 
00099   ACE_DEBUG ((LM_DEBUG, ACE_LIB_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_LIB_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_LIB_TEXT ("ACE_TSS_TPQ_Entry::dump:\n")
00195                         ACE_LIB_TEXT (" client_id_ = %s\n"),
00196                         client_id_ == 0 ? ACE_LIB_TEXT ("0") : client_id_));
00197   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_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_LIB_TEXT ("ACE_TPQ_Iterator::dump:\n")
00279               ACE_LIB_TEXT (" current_ = %d\n"),
00280               (long) this->current_));
00281   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_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_LIB_TEXT ("ACE_Token_Proxy_Queue::dump:\n")
00293                         ACE_LIB_TEXT (" size_ = %d\n"),
00294                         size_));
00295   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("head_ and tail_\n")));
00296   if (this->head_ != 0)
00297     this->head_->dump ();
00298 
00299   ACE_DEBUG ((LM_DEBUG, ACE_LIB_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_LIB_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_LIB_TEXT ("ACE_Mutex_Token::dump:\n")));
00457   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("lock_\n")));
00458   lock_.dump ();
00459   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("base:\n")));
00460   ACE_Tokens::dump ();
00461   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_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_LIB_TEXT ("ACE_RW_Token::dump:\n")
00712                         ACE_LIB_TEXT ("num_writers_ = %d\n"), num_writers_));
00713   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("lock_\n")));
00714   this->lock_.dump ();
00715   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("base:\n")));
00716   ACE_Tokens::dump ();
00717   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_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_LIB_TEXT ("ACE_Token_Proxy::dump:\n")
01094                         ACE_LIB_TEXT (" type = %d\n")
01095                         ACE_LIB_TEXT (" ignore_deadlock_ = %d\n")
01096                         ACE_LIB_TEXT (" debug_ = %d\n"),
01097                         (int) this->type (), ignore_deadlock_, debug_));
01098   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_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_LIB_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_LIB_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 ACE_Token_Proxy::ACE_Token_Proxy (void)
01145 : token_ (0),
01146   waiter_ (this, 0)
01147 {
01148   ACE_TRACE ("ACE_Token_Proxy::ACE_Token_Proxy");
01149 }
01150 
01151 // Notice the token_ (0).  Do *not* copy the token pointer.  This must
01152 // be obtained through the token manager.  Also, we don't copy any
01153 // waiter info.  A copied Proxy does *not* inherit client_id.
01154 
01155 ACE_Token_Proxy::ACE_Token_Proxy (const ACE_Token_Proxy &)
01156   : token_ (0),
01157     waiter_ (this, 0)
01158 {
01159   ACE_TRACE ("ACE_Token_Proxy::ACE_Token_Proxy");
01160 }
01161 
01162 // @@ should I do a mutex_->release ()?
01163 ACE_Token_Proxy::~ACE_Token_Proxy (void)
01164 {
01165   ACE_TRACE ("ACE_Token_Proxy::~ACE_Token_Proxy");
01166 
01167   if (token_ != 0)
01168     // notify token manager that we are done with it so it can
01169     // free it if necessary
01170     ACE_Token_Manager::instance ()->release_token (token_);
01171 }
01172 
01173 int
01174 ACE_Token_Proxy::open (const ACE_TCHAR *token_name,
01175                        int ignore_deadlock,
01176                        int debug)
01177 {
01178   ACE_TRACE ("ACE_Token_Proxy::open");
01179 
01180   // Store some parameters.
01181   this->ignore_deadlock_ = ignore_deadlock;
01182   this->debug_ = debug;
01183 
01184   // Used in case a name was not specified.
01185   ACE_TCHAR name[BUFSIZ];
01186 
01187   // We must have a name.
01188   if (token_name == 0)
01189     {
01190       ACE_OS::sprintf (name, ACE_LIB_TEXT ("token %lx"),
01191                        reinterpret_cast<long> (this));
01192       token_name = name;
01193     }
01194 
01195   // Get or create the underlying token.  The Token Manager will call
01196   // us back to set token_.
01197   ACE_Token_Manager::instance ()->get_token (this, token_name);
01198 
01199   // Check for failed get or failed new.
01200   if (this->token_ == 0)
01201     {
01202       errno = ENOMEM;
01203       ACE_ERROR_RETURN ((LM_ERROR, ACE_LIB_TEXT ("Can't allocate mutex")), -1);
01204     }
01205 
01206   return 0;
01207 }
01208 
01209 int
01210 ACE_Token_Proxy::acquire (int notify,
01211                           void (*sleep_hook)(void *),
01212                           ACE_Synch_Options &options)
01213 {
01214   ACE_TRACE ("ACE_Token_Proxy::acquire");
01215   if (this->token_ == 0)
01216     {
01217       errno = ENOENT;
01218       ACE_ERROR_RETURN ((LM_ERROR, ACE_LIB_TEXT ("Not open.\n")), -1);
01219     }
01220 
01221   // Make sure no one calls our token_acquired until we have a chance
01222   // to sleep first!  If after we call an EWOULDBLOCK
01223   // mutex_->acquire() below, but before we enter handle_options to
01224   // wait on the cond_var, a thread tries to give take us off the
01225   // waiter queue and signal us, IT WILL FIRST HAVE TO ACQUIRE THIS
01226   // cond_var.mutex ().  _This_ is why we acquire it.
01227   this->waiter_->cond_var_.mutex ().acquire ();
01228 
01229   this->waiter_->sleep_hook (sleep_hook);
01230 
01231   if (this->token_->acquire (this->waiter_, this->ignore_deadlock_, notify) == -1)
01232     // acquire failed
01233     {
01234       switch (errno)
01235         {
01236         case EDEADLK :
01237           if (!ignore_deadlock_)
01238             {
01239               waiter_->cond_var_.mutex ().release ();
01240               errno = EDEADLK;
01241               ACE_RETURN (-1);
01242             }
01243           // Else, fallthrough and block!
01244 
01245         case EWOULDBLOCK :
01246           if (this->debug_)
01247             ACE_DEBUG ((LM_DEBUG,
01248                         ACE_LIB_TEXT ("(%t) waiting for %s, owner is %s, ")
01249                         ACE_LIB_TEXT ("total waiters == %d\n"),
01250                         this->name (),
01251                         this->token_->owner_id (),
01252                         token_->no_of_waiters ()));
01253 
01254           // no error, but would block, if error, return error (-1),
01255           // otherwise, return whether we called the holder or not.
01256           int return_value;
01257           if (this->handle_options (options,
01258                                     waiter_->cond_var_) == -1)
01259             return_value = -1;
01260           else
01261             return_value = notify == 1;
01262 
01263           errno = EWOULDBLOCK;
01264           ACE_RETURN (return_value);
01265 
01266         default :
01267           waiter_->cond_var_.mutex ().release ();
01268           ACE_ERROR_RETURN ((LM_ERROR,
01269                              ACE_LIB_TEXT ("%p\n"),
01270                              ACE_LIB_TEXT ("Token Proxy acquire.")),
01271                             -1);
01272         }
01273     }
01274   else
01275     // we have the token
01276     {
01277       if (debug_)
01278         ACE_DEBUG ((LM_DEBUG,
01279                     ACE_LIB_TEXT ("(%t) acquired %s\n"),
01280                     this->name ()));
01281       waiter_->cond_var_.mutex ().release ();
01282     }
01283 
01284   return 0;
01285 }
01286 
01287 int
01288 ACE_Token_Proxy::tryacquire (void (*sleep_hook)(void *))
01289 {
01290   ACE_TRACE ("ACE_Token_Proxy::tryacquire");
01291   if (this->token_ == 0)
01292     {
01293       errno = ENOENT;
01294       ACE_ERROR_RETURN ((LM_ERROR,
01295                          ACE_LIB_TEXT ("Not open.\n")),
01296                         -1);
01297     }
01298 
01299   this->waiter_->sleep_hook (sleep_hook);
01300 
01301   return this->token_->tryacquire (waiter_);
01302 }
01303 
01304 int
01305 ACE_Token_Proxy::renew (int requeue_position,
01306                         ACE_Synch_Options &options)
01307 {
01308   ACE_TRACE ("ACE_Token_Proxy::renew");
01309   if (this->token_ == 0)
01310     {
01311       errno = ENOENT;
01312       ACE_ERROR_RETURN ((LM_ERROR,
01313                          ACE_LIB_TEXT ("Not open.\n")),
01314                         -1);
01315     }
01316 
01317   // Make sure no one calls our token_acquired until we have a chance
01318   // to sleep first!
01319   this->waiter_->cond_var_.mutex ().acquire ();
01320 
01321   if (this->token_->renew (this->waiter_, requeue_position) == -1)
01322     {
01323       // check for error
01324       if (errno != EWOULDBLOCK)
01325         ACE_ERROR_RETURN ((LM_ERROR,
01326                            ACE_LIB_TEXT ("%p renew failed\n"), ACE_LIB_TEXT ("ACE_Token_Proxy")), -1);
01327 
01328       if (this->debug_)
01329         ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("(%t) renew blocking for %s, owner is %s\n"),
01330                     this->name (),
01331                     token_->owner_id ()));
01332 
01333       // no error, but would block, so block or return
01334       return this->handle_options (options, waiter_->cond_var_);
01335     }
01336   else
01337     // we have the token
01338     {
01339       if (this->debug_)
01340         ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("(%t) renewed %s\n"),
01341                     this->name ()));
01342       waiter_->cond_var_.mutex ().release ();
01343       return 0;
01344     }
01345 }
01346 
01347 int
01348 ACE_Token_Proxy::handle_options (ACE_Synch_Options &options,
01349                                  ACE_TOKEN_CONST::COND_VAR &cv)
01350 {
01351   // Some operation failed with EWOULDBLOCK.
01352   ACE_TRACE ("ACE_Token_Proxy::handle_options");
01353 
01354   if (options[ACE_Synch_Options::USE_REACTOR] == 1)
01355     // Asynchronous.
01356     {
01357       // Save/restore errno.
01358       ACE_Errno_Guard error (errno);
01359       cv.mutex ().release ();
01360       ACE_RETURN (-1);
01361     }
01362   else
01363     // Synchronous.
01364     {
01365       // Block on condition variable.
01366       while (cv.wait ((ACE_Time_Value *) options.time_value ()) == -1)
01367         {
01368           // Note, this should obey whatever thread-specific
01369           // interrupt policy is currently in place...
01370           if (errno == EINTR)
01371             continue;
01372           // We come here if a timeout occurs or some serious
01373           // ACE_Condition object error.
01374           cv.mutex ().release ();
01375           ACE_ERROR_RETURN ((LM_ERROR, ACE_LIB_TEXT ("condition variable wait")
01376                              ACE_LIB_TEXT (" bombed.")), -1);
01377         }
01378 
01379       if (this->debug_)
01380         ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("(%t) unblocking %s.\n"),
01381                     this->client_id ()));
01382       cv.mutex ().release ();
01383       return 0;       // operation succeeded
01384     }
01385 }
01386 
01387 int
01388 ACE_Token_Proxy::release (ACE_Synch_Options &)
01389 {
01390   ACE_TRACE ("ACE_Token_Proxy::release");
01391 
01392   if (this->token_ == 0)
01393     {
01394       errno = ENOENT;
01395       if (debug_)
01396         ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("Must open before releasing.\n")));
01397       ACE_RETURN (-1);
01398     }
01399 
01400   if (this->token_->release (waiter_) != 0)
01401     {
01402       // Release failed.
01403       this->token_->remove (this->waiter_);
01404       if (debug_)
01405         ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("(%t) %p.\n"), ACE_LIB_TEXT ("release failed")));
01406       return -1;
01407     }
01408   else
01409     {
01410       if (this->debug_)
01411         ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("(%t) released %s, owner is %s\n"),
01412                     this->name (),
01413                     token_->owner_id ()));
01414 
01415       return 0;
01416     }
01417 }
01418 
01419 int
01420 ACE_Token_Proxy::remove (ACE_Synch_Options &)
01421 {
01422   ACE_TRACE ("ACE_Token_Proxy::remove");
01423   return 0;
01424 }
01425 
01426 void
01427 ACE_Token_Proxy::sleep_hook (void)
01428 {
01429   ACE_TRACE ("ACE_Token_Proxy::sleep_hook");
01430   // Somebody wants our token!  (Let'em wait...)
01431   return;
01432 }
01433 
01434 void
01435 ACE_Token_Proxy::token_acquired (ACE_TPQ_Entry *e)
01436 {
01437   ACE_TRACE ("ACE_Token_Proxy::token_acquired");
01438   e->cond_var_.mutex ().acquire ();
01439   // We've been taken off the waiters list and given the token!
01440   // This implementation signals the internal condition
01441   // variable. Thus, if asynchronous acquires are used, this must be
01442   // overriden to do something more useful!
01443   e->cond_var_.signal ();
01444   e->cond_var_.mutex ().release ();
01445 
01446   return;
01447 }
01448 
01449 int
01450 ACE_Token_Proxy::type (void) const
01451 {
01452   ACE_TRACE ("ACE_Token_Proxy::type");
01453   return 0;
01454 }
01455 
01456 int
01457 ACE_Token_Proxy::acquire_read (int notify,
01458                                void (*sleep_hook)(void *),
01459                                ACE_Synch_Options &options)
01460 {
01461   return this->acquire (notify,
01462                         sleep_hook,
01463                         options);
01464 }
01465 
01466 int
01467 ACE_Token_Proxy::acquire_write (int notify,
01468                                 void (*sleep_hook)(void *),
01469                                 ACE_Synch_Options &options)
01470 {
01471   return this->acquire (notify,
01472                         sleep_hook,
01473                         options);
01474 }
01475 
01476 int
01477 ACE_Token_Proxy::tryacquire_read (void (*sleep_hook)(void *))
01478 {
01479   return this->tryacquire (sleep_hook);
01480 }
01481 
01482 int
01483 ACE_Token_Proxy::tryacquire_write (void (*sleep_hook)(void *))
01484 {
01485   return this->tryacquire (sleep_hook);
01486 }
01487 
01488 ACE_Token_Name::ACE_Token_Name (const ACE_TCHAR *token_name)
01489 {
01490   ACE_TRACE ("ACE_Token_Name::ACE_Token_Name");
01491   this->name (token_name);
01492 }
01493 
01494 ACE_Token_Name::ACE_Token_Name (const ACE_Token_Name &rhs)
01495 {
01496   ACE_TRACE ("ACE_Token_Name::ACE_Token_Name");
01497   this->name (rhs.name ());
01498 }
01499 
01500 ACE_Token_Name::~ACE_Token_Name ()
01501 {
01502   ACE_TRACE ("ACE_Token_Name::~ACE_Token_Name");
01503 }
01504 
01505 void
01506 ACE_Token_Name::dump (void) const
01507 {
01508 #if defined (ACE_HAS_DUMP)
01509   ACE_TRACE ("ACE_Token_Name::dump");
01510   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
01511   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("ACE_Token_Name::dump:\n")
01512                         ACE_LIB_TEXT (" token_name_ = %s\n"),
01513               token_name_ == 0 ? ACE_LIB_TEXT ("no name") : token_name_));
01514   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
01515 #endif /* ACE_HAS_DUMP */
01516 }
01517 
01518 // ************************************************************
01519 
01520 ACE_Token_Proxy *
01521 ACE_Local_Mutex::clone (void) const
01522 {
01523   ACE_Token_Proxy *temp = 0;
01524   ACE_NEW_RETURN (temp,
01525                   ACE_Local_Mutex (token_->name (),
01526                                    ignore_deadlock_,
01527                                    debug_),
01528                   0);
01529   return temp;
01530 }
01531 
01532 ACE_Tokens *
01533 ACE_Local_Mutex::create_token (const ACE_TCHAR *name)
01534 {
01535   ACE_Tokens *temp = 0;
01536   ACE_NEW_RETURN (temp,
01537                   ACE_Mutex_Token (name),
01538                   0);
01539   return temp;
01540 }
01541 
01542 ACE_Local_Mutex::~ACE_Local_Mutex (void)
01543 {
01544 }
01545 
01546 // ************************************************************
01547 
01548 ACE_Local_RLock::~ACE_Local_RLock (void)
01549 {
01550 }
01551 
01552 ACE_Tokens *
01553 ACE_Local_RLock::create_token (const ACE_TCHAR *name)
01554 {
01555   ACE_Tokens *temp = 0;
01556   ACE_NEW_RETURN (temp,
01557                   ACE_RW_Token (name),
01558                   0);
01559   return temp;
01560 }
01561 
01562 int
01563 ACE_Local_RLock::type (void) const
01564 {
01565   return ACE_RW_Token::READER;
01566 }
01567 
01568 ACE_Token_Proxy *
01569 ACE_Local_RLock::clone (void) const
01570 {
01571   ACE_Token_Proxy *temp = 0;
01572   ACE_NEW_RETURN (temp,
01573                   ACE_Local_RLock (token_->name (),
01574                                    ignore_deadlock_,
01575                                    debug_),
01576                   0);
01577   return temp;
01578 }
01579 
01580 // ************************************************************
01581 
01582 ACE_Local_WLock::~ACE_Local_WLock (void)
01583 {
01584 }
01585 
01586 ACE_Tokens *
01587 ACE_Local_WLock::create_token (const ACE_TCHAR *name)
01588 {
01589   ACE_Tokens *temp = 0;
01590   ACE_NEW_RETURN (temp,
01591                   ACE_RW_Token (name),
01592                   0);
01593   return temp;
01594 }
01595 
01596 int
01597 ACE_Local_WLock::type (void) const
01598 {
01599   return ACE_RW_Token::WRITER;
01600 }
01601 
01602 ACE_Token_Proxy *
01603 ACE_Local_WLock::clone (void) const
01604 {
01605   ACE_Token_Proxy *temp = 0;
01606   ACE_NEW_RETURN (temp,
01607                   ACE_Local_WLock (token_->name (),
01608                                    ignore_deadlock_,
01609                                    debug_),
01610                   0);
01611   return temp;
01612 }
01613 
01614 ACE_END_VERSIONED_NAMESPACE_DECL
01615 
01616 #endif /* ACE_HAS_TOKENS_LIBRARY */

Generated on Thu Nov 9 09:41:53 2006 for ACE by doxygen 1.3.6