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

Synch_T.cpp

Go to the documentation of this file.
00001 // $Id: Synch_T.cpp,v 1.1.1.4 2003/02/21 18:36:32 chad Exp $
00002 
00003 #ifndef ACE_SYNCH_T_C
00004 #define ACE_SYNCH_T_C
00005 
00006 #include "ace/Thread.h"
00007 
00008 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00009 # pragma once
00010 #endif /* ACE_LACKS_PRAGMA_ONCE */
00011 
00012 #include "ace/Synch_T.h"
00013 #include "ace/Log_Msg.h"
00014 
00015 ACE_RCSID(ace, Synch_T, "$Id: Synch_T.cpp,v 1.1.1.4 2003/02/21 18:36:32 chad Exp $")
00016 
00017 #if !defined (__ACE_INLINE__)
00018 #include "ace/Synch_T.i"
00019 #endif /* __ACE_INLINE__ */
00020 
00021 // This constructor isn't inlined, because SunPRO C++ 4.2 + patch
00022 // 104631-07 has trouble compiling TAO with it inline.
00023 template <class ACE_LOCKING_MECHANISM>
00024 ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::ACE_Lock_Adapter (void)
00025   : lock_ (0),
00026     delete_lock_ (1)
00027 {
00028   ACE_NEW (this->lock_,
00029            ACE_LOCKING_MECHANISM);
00030 }
00031 
00032 template <class ACE_LOCKING_MECHANISM>
00033 ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::~ACE_Reverse_Lock (void)
00034 {
00035 }
00036 // ****************************************************************
00037 // ACE_ALLOC_HOOK_DEFINE(ACE_Guard)
00038 
00039 template <class ACE_LOCK> void
00040 ACE_Guard<ACE_LOCK>::dump (void) const
00041 {
00042 // ACE_TRACE ("ACE_Guard<ACE_LOCK>::dump");
00043 
00044   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00045   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("mutex_ = %x\n"), this->lock_));
00046   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("owner_ = %d\n"), this->owner_));
00047   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00048 }
00049 
00050 // ACE_ALLOC_HOOK_DEFINE(ACE_Write_Guard)
00051 
00052 template <class ACE_LOCK> void
00053 ACE_Write_Guard<ACE_LOCK>::dump (void) const
00054 {
00055 // ACE_TRACE ("ACE_Write_Guard<ACE_LOCK>::dump");
00056   ACE_Guard<ACE_LOCK>::dump ();
00057 }
00058 
00059 // ACE_ALLOC_HOOK_DEFINE(ACE_Read_Guard)
00060 
00061 template <class ACE_LOCK> void
00062 ACE_Read_Guard<ACE_LOCK>::dump (void) const
00063 {
00064 // ACE_TRACE ("ACE_Read_Guard<ACE_LOCK>::dump");
00065   ACE_Guard<ACE_LOCK>::dump ();
00066 }
00067 
00068 #if defined (ACE_HAS_THREADS)
00069 
00070 ACE_ALLOC_HOOK_DEFINE(ACE_Condition)
00071 
00072 template <class MUTEX> void
00073 ACE_Condition<MUTEX>::dump (void) const
00074 {
00075 // ACE_TRACE ("ACE_Condition<MUTEX>::dump");
00076 
00077   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00078 #if defined (CHORUS)
00079   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("condname_ = %s\n"), this->condname_));
00080   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("process_cond_ = %x\n"), this->process_cond_));
00081 #endif /* CHORUS */
00082   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n")));
00083   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00084 }
00085 
00086 template <class MUTEX>
00087 ACE_Thread_Condition<MUTEX>::ACE_Thread_Condition (MUTEX &m,
00088                                                    const ACE_TCHAR *name,
00089                                                    void *arg)
00090   : ACE_Condition<MUTEX> (m, USYNC_THREAD, name, arg)
00091 {
00092 // ACE_TRACE ("ACE_Thread_Condition<MUTEX>::ACE_Thread_Condition");
00093 }
00094 
00095 template <class MUTEX> void
00096 ACE_Thread_Condition<MUTEX>::dump (void) const
00097 {
00098 // ACE_TRACE ("ACE_Thread_Condition<MUTEX>::dump");
00099 
00100   ACE_Condition<MUTEX>::dump ();
00101 }
00102 
00103 template <class MUTEX>
00104 ACE_Condition<MUTEX>::ACE_Condition (MUTEX &m,
00105                                      int type,
00106                                      const ACE_TCHAR *name,
00107                                      void *arg)
00108   :
00109 #if defined (CHORUS)
00110     process_cond_(0),
00111     condname_ (0),
00112 #endif /* CHORUS */
00113     mutex_ (m)
00114 {
00115 
00116 #if defined(CHORUS)
00117   if (type == USYNC_PROCESS)
00118     {
00119       // Let's see if the shared memory entity already exists.
00120       ACE_HANDLE fd = ACE_OS::shm_open (name,
00121                                         O_RDWR | O_CREAT | O_EXCL,
00122                                         ACE_DEFAULT_FILE_PERMS);
00123       if (fd == ACE_INVALID_HANDLE)
00124         {
00125           if (errno == EEXIST)
00126             fd = ACE_OS::shm_open (name,
00127                                    O_RDWR | O_CREAT,
00128                                    ACE_DEFAULT_FILE_PERMS);
00129           else
00130             return;
00131         }
00132       else
00133         {
00134           // We own this shared memory object!  Let's set its size.
00135           if (ACE_OS::ftruncate (fd,
00136                                  sizeof (ACE_mutex_t)) == -1)
00137             {
00138               ACE_OS::close (fd);
00139               return;
00140             }
00141           this->condname_ = ACE_OS::strdup (name);
00142           if (this->condname_ == 0)
00143             {
00144               ACE_OS::close (fd);
00145               return;
00146             }
00147         }
00148 
00149       this->process_cond_ =
00150         (ACE_cond_t *) ACE_OS::mmap (0,
00151                                      sizeof (ACE_cond_t),
00152                                      PROT_RDWR,
00153                                      MAP_SHARED,
00154                                      fd,
00155                                      0);
00156       ACE_OS::close (fd);
00157       if (this->process_cond_ == MAP_FAILED)
00158         return;
00159 
00160       if (this->condname_
00161           && ACE_OS::cond_init (this->process_cond_,
00162                                 type,
00163                                 name,
00164                                 arg) != 0)
00165         return;
00166     }
00167    // It is ok to fall through into the <cond_init> below if the
00168    // USYNC_PROCESS flag is not enabled.
00169 #endif /* CHORUS */
00170 
00171   // ACE_TRACE ("ACE_Condition<MUTEX>::ACE_Condition");
00172 
00173   if (ACE_OS::cond_init (&this->cond_,
00174                          (short) type,
00175                          name,
00176                          arg) != 0)
00177     ACE_ERROR ((LM_ERROR,
00178                 ACE_LIB_TEXT ("%p\n"),
00179                 ACE_LIB_TEXT ("ACE_Condition::ACE_Condition")));
00180 }
00181 
00182 template <class MUTEX>
00183 ACE_Condition<MUTEX>::~ACE_Condition (void)
00184 {
00185   // ACE_TRACE ("ACE_Condition<MUTEX>::~ACE_Condition");
00186 
00187   if (this->remove () == -1)
00188     ACE_ERROR ((LM_ERROR,
00189                 ACE_LIB_TEXT ("%p\n"),
00190                 ACE_LIB_TEXT ("ACE_Condition::~ACE_Condition")));
00191 }
00192 
00193 template <class MUTEX> int
00194 ACE_Condition<MUTEX>::wait (void)
00195 {
00196   // ACE_TRACE ("ACE_Condition<MUTEX>::wait");
00197 #if defined (CHORUS)
00198   if (this->process_cond_ != 0)
00199     return ACE_OS::cond_wait (this->process_cond_,
00200                               &this->mutex_.lock_);
00201 #endif /* CHORUS */
00202   return ACE_OS::cond_wait (&this->cond_,
00203                             &this->mutex_.lock_);
00204 }
00205 
00206 template <class MUTEX> int
00207 ACE_Condition<MUTEX>::wait (MUTEX &mutex,
00208                             const ACE_Time_Value *abstime)
00209 {
00210 // ACE_TRACE ("ACE_Condition<MUTEX>::wait");
00211   if (abstime == 0)
00212     return this->wait ();
00213   else
00214     {
00215 #if defined (CHORUS)
00216       if (this->process_cond_ != 0)
00217         return ACE_OS::cond_timedwait (this->process_cond_,
00218                                       &mutex_.lock_,
00219                                       (ACE_Time_Value *) abstime);
00220 #endif /* CHORUS */
00221       return ACE_OS::cond_timedwait (&this->cond_,
00222                                      &mutex.lock_,
00223                                      (ACE_Time_Value *) abstime);
00224     }
00225 }
00226 
00227 // Peform an "alertable" timed wait.  If the argument ABSTIME == 0
00228 // then we do a regular cond_wait(), else we do a timed wait for up to
00229 // ABSTIME using the Solaris cond_timedwait() function.
00230 
00231 template <class MUTEX> int
00232 ACE_Condition<MUTEX>::wait (const ACE_Time_Value *abstime)
00233 {
00234 // ACE_TRACE ("ACE_Condition<MUTEX>::wait");
00235   return this->wait (this->mutex_, abstime);
00236 }
00237 #endif /* ACE_HAS_THREADS */
00238 
00239 ACE_ALLOC_HOOK_DEFINE(ACE_TSS)
00240 
00241 template <class TYPE>
00242 ACE_TSS<TYPE>::~ACE_TSS (void)
00243 {
00244   // We can't call <ACE_OS::thr_keyfree> until *all* of the threads
00245   // that are using that key have done an <ACE_OS::thr_key_detach>.
00246   // Otherwise, we'll end up with "dangling TSS pointers."
00247   ACE_OS::thr_key_detach (this);
00248 }
00249 
00250 template <class TYPE> TYPE *
00251 ACE_TSS<TYPE>::operator-> () const
00252 {
00253   return this->ts_get ();
00254 }
00255 
00256 template <class TYPE>
00257 ACE_TSS<TYPE>::operator TYPE *(void) const
00258 {
00259   return this->ts_get ();
00260 }
00261 
00262 template <class TYPE> TYPE *
00263 ACE_TSS<TYPE>::make_TSS_TYPE (void) const
00264 {
00265   TYPE *temp = 0;
00266   ACE_NEW_RETURN (temp,
00267                   TYPE,
00268                   0);
00269   return temp;
00270 }
00271 
00272 template <class TYPE> void
00273 ACE_TSS<TYPE>::dump (void) const
00274 {
00275 // ACE_TRACE ("ACE_TSS<TYPE>::dump");
00276 #if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
00277   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00278   this->keylock_.dump ();
00279   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("key_ = %d\n"), this->key_));
00280   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nonce_ = %d"), this->once_));
00281   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n")));
00282   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00283 #endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */
00284 }
00285 
00286 #if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
00287 #if defined (ACE_HAS_THR_C_DEST)
00288 extern "C" void ACE_TSS_C_cleanup(void *); // defined in Synch.cpp
00289 #endif /* ACE_HAS_THR_C_DEST */
00290 
00291 template <class TYPE> void
00292 ACE_TSS<TYPE>::cleanup (void *ptr)
00293 {
00294   // Cast this to the concrete TYPE * so the destructor gets called.
00295   delete (TYPE *) ptr;
00296 }
00297 
00298 template <class TYPE> int
00299 ACE_TSS<TYPE>::ts_init (void) const
00300 {
00301   // Insure that we are serialized!
00302   ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, (ACE_Thread_Mutex &) this->keylock_, 0);
00303 
00304   // Use the Double-Check pattern to make sure we only create the key
00305   // once!
00306   if (this->once_ == 0)
00307     {
00308       if (ACE_Thread::keycreate (ACE_const_cast (ACE_thread_key_t *, &this->key_),
00309 #if defined (ACE_HAS_THR_C_DEST)
00310                                  &ACE_TSS_C_cleanup,
00311 #else
00312                                  &ACE_TSS<TYPE>::cleanup,
00313 #endif /* ACE_HAS_THR_C_DEST */
00314                                  (void *) this) != 0)
00315         return -1; // Major problems, this should *never* happen!
00316       else
00317         {
00318           // This *must* come last to avoid race conditions!  Note that
00319           // we need to "cast away const..."
00320           * ACE_const_cast (int*, &this->once_) = 1;
00321           return 0;
00322         }
00323     }
00324 
00325   return -1;
00326 }
00327 
00328 template <class TYPE>
00329 ACE_TSS<TYPE>::ACE_TSS (TYPE *ts_obj)
00330   : once_ (0),
00331     key_ (ACE_OS::NULL_key)
00332 {
00333   // If caller has passed us a non-NULL TYPE *, then we'll just use
00334   // this to initialize the thread-specific value.  Thus, subsequent
00335   // calls to operator->() will return this value.  This is useful
00336   // since it enables us to assign objects to thread-specific data
00337   // that have arbitrarily complex constructors!
00338 
00339   if (ts_obj != 0)
00340     {
00341       if (this->ts_init () == -1)
00342         {
00343           // Save/restore errno.
00344           ACE_Errno_Guard error (errno);
00345           // What should we do if this call fails?!
00346 #if defined (ACE_HAS_WINCE)
00347           ::MessageBox (0,
00348                         L"ACE_Thread::keycreate() failed!",
00349                         L"ACE_TSS::ACE_TSS",
00350                         MB_OK);
00351 #else
00352           ACE_OS::fprintf (stderr,
00353                            "ACE_Thread::keycreate() failed!");
00354 #endif /* ACE_HAS_WINCE */
00355           return;
00356         }
00357 
00358 #if defined (ACE_HAS_THR_C_DEST)
00359       // Encapsulate a ts_obj and it's destructor in an
00360       // ACE_TSS_Adapter.
00361       ACE_TSS_Adapter *tss_adapter;
00362       ACE_NEW (tss_adapter,
00363                ACE_TSS_Adapter ((void *) ts_obj,
00364                                 ACE_TSS<TYPE>::cleanup));
00365 
00366       // Put the adapter in thread specific storage
00367       if (ACE_Thread::setspecific (this->key_,
00368                                    (void *) tss_adapter) != 0)
00369         {
00370           delete tss_adapter;
00371           ACE_ERROR ((LM_ERROR,
00372                       ACE_LIB_TEXT ("%p\n"),
00373                       ACE_LIB_TEXT ("ACE_Thread::setspecific() failed!")));
00374         }
00375 #else
00376       if (ACE_Thread::setspecific (this->key_,
00377                                    (void *) ts_obj) != 0)
00378         ACE_ERROR ((LM_ERROR,
00379                     ACE_LIB_TEXT ("%p\n"),
00380                     ACE_LIB_TEXT ("ACE_Thread::setspecific() failed!")));
00381 #endif /* ACE_HAS_THR_C_DEST */
00382     }
00383 }
00384 
00385 template <class TYPE> TYPE *
00386 ACE_TSS<TYPE>::ts_get (void) const
00387 {
00388   if (this->once_ == 0)
00389     // Create and initialize thread-specific ts_obj.
00390     this->ts_init ();
00391 
00392   TYPE *ts_obj = 0;
00393 
00394 #if defined (ACE_HAS_THR_C_DEST)
00395   ACE_TSS_Adapter *tss_adapter = 0;
00396 
00397   // Get the adapter from thread-specific storage
00398   if (ACE_Thread::getspecific (this->key_,
00399                                (void **) &tss_adapter) == -1)
00400     return 0; // This should not happen!
00401 
00402   // Check to see if this is the first time in for this thread.
00403   if (tss_adapter == 0)
00404 #else
00405   // Get the ts_obj from thread-specific storage.  Note that no locks
00406   // are required here...
00407   if (ACE_Thread::getspecific (this->key_,
00408                                (void **) &ts_obj) == -1)
00409     return 0; // This should not happen!
00410 
00411   // Check to see if this is the first time in for this thread.
00412   if (ts_obj == 0)
00413 #endif /* ACE_HAS_THR_C_DEST */
00414     {
00415       // Allocate memory off the heap and store it in a pointer in
00416       // thread-specific storage (on the stack...).
00417 
00418       ts_obj = this->make_TSS_TYPE ();
00419 
00420       if (ts_obj == 0)
00421         return 0;
00422 
00423 #if defined (ACE_HAS_THR_C_DEST)
00424       // Encapsulate a ts_obj and it's destructor in an
00425       // ACE_TSS_Adapter.
00426       ACE_NEW_RETURN (tss_adapter,
00427                       ACE_TSS_Adapter (ts_obj,
00428                                        ACE_TSS<TYPE>::cleanup), 0);
00429 
00430       // Put the adapter in thread specific storage
00431       if (ACE_Thread::setspecific (this->key_,
00432                                    (void *) tss_adapter) != 0)
00433         {
00434           delete tss_adapter;
00435           delete ts_obj;
00436           return 0; // Major problems, this should *never* happen!
00437         }
00438 #else
00439       // Store the dynamically allocated pointer in thread-specific
00440       // storage.
00441       if (ACE_Thread::setspecific (this->key_,
00442                                    (void *) ts_obj) != 0)
00443         {
00444           delete ts_obj;
00445           return 0; // Major problems, this should *never* happen!
00446         }
00447 #endif /* ACE_HAS_THR_C_DEST */
00448     }
00449 
00450 #if defined (ACE_HAS_THR_C_DEST)
00451   // Return the underlying ts object.
00452   return (TYPE *) tss_adapter->ts_obj_;
00453 #else
00454   return ts_obj;
00455 #endif /* ACE_HAS_THR_C_DEST */
00456 }
00457 
00458 // Get the thread-specific object for the key associated with this
00459 // object.  Returns 0 if the ts_obj has never been initialized,
00460 // otherwise returns a pointer to the ts_obj.
00461 
00462 template <class TYPE> TYPE *
00463 ACE_TSS<TYPE>::ts_object (void) const
00464 {
00465   // Ensure that we are serialized!
00466   ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, (ACE_Thread_Mutex &) this->keylock_, 0);
00467 
00468   if (this->once_ == 0) // Return 0 if we've never been initialized.
00469     return 0;
00470 
00471   TYPE *ts_obj = 0;
00472 
00473 #if defined (ACE_HAS_THR_C_DEST)
00474   ACE_TSS_Adapter *tss_adapter = 0;
00475 
00476   // Get the tss adapter from thread-specific storage
00477   if (ACE_Thread::getspecific (this->key_,
00478                                (void **) &tss_adapter) == -1)
00479     return 0; // This should not happen!
00480   else if (tss_adapter != 0)
00481     // Extract the real TS object.
00482     ts_obj = (TYPE *) tss_adapter->ts_obj_;
00483 #else
00484   if (ACE_Thread::getspecific (this->key_,
00485                                (void **) &ts_obj) == -1)
00486     return 0; // This should not happen!
00487 #endif /* ACE_HAS_THR_C_DEST */
00488 
00489   return ts_obj;
00490 }
00491 
00492 template <class TYPE> TYPE *
00493 ACE_TSS<TYPE>::ts_object (TYPE *new_ts_obj)
00494 {
00495   // Note, we shouldn't hold the keylock at this point because
00496   // <ts_init> does it for us and we'll end up with deadlock
00497   // otherwise...
00498   if (this->once_ == 0)
00499     // Create and initialize thread-specific ts_obj.
00500     this->ts_init ();
00501 
00502   // Ensure that we are serialized!
00503   ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->keylock_, 0);
00504 
00505   TYPE *ts_obj = 0;
00506 
00507 #if defined (ACE_HAS_THR_C_DEST)
00508   ACE_TSS_Adapter *tss_adapter = 0;
00509 
00510   if (ACE_Thread::getspecific (this->key_,
00511                                (void **) &tss_adapter) == -1)
00512     return 0; // This should not happen!
00513 
00514   if (tss_adapter != 0)
00515     {
00516       ts_obj = (TYPE *) tss_adapter->ts_obj_;
00517       delete tss_adapter;       // don't need this anymore
00518     }
00519 
00520   ACE_NEW_RETURN (tss_adapter,
00521                   ACE_TSS_Adapter ((void *) new_ts_obj,
00522                                    ACE_TSS<TYPE>::cleanup),
00523                   0);
00524 
00525   if (ACE_Thread::setspecific (this->key_,
00526                                (void *) tss_adapter) == -1)
00527     {
00528       delete tss_adapter;
00529       return ts_obj; // This should not happen!
00530     }
00531 #else
00532   if (ACE_Thread::getspecific (this->key_,
00533                                (void **) &ts_obj) == -1)
00534     return 0; // This should not happen!
00535   if (ACE_Thread::setspecific (this->key_,
00536                                (void *) new_ts_obj) == -1)
00537     return ts_obj; // This should not happen!
00538 #endif /* ACE_HAS_THR_C_DEST */
00539 
00540   return ts_obj;
00541 }
00542 
00543 ACE_ALLOC_HOOK_DEFINE(ACE_TSS_Guard)
00544 
00545 template <class ACE_LOCK> void
00546 ACE_TSS_Guard<ACE_LOCK>::dump (void) const
00547 {
00548 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::dump");
00549 
00550   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00551   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("key_ = %d"), this->key_));
00552   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n")));
00553   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00554 }
00555 
00556 template <class ACE_LOCK> void
00557 ACE_TSS_Guard<ACE_LOCK>::init_key (void)
00558 {
00559 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::init_key");
00560 
00561   this->key_ = ACE_OS::NULL_key;
00562   ACE_Thread::keycreate (&this->key_,
00563 #if defined (ACE_HAS_THR_C_DEST)
00564                          &ACE_TSS_C_cleanup,
00565 #else
00566                          &ACE_TSS_Guard<ACE_LOCK>::cleanup,
00567 #endif /* ACE_HAS_THR_C_DEST */
00568                          (void *) this);
00569 }
00570 
00571 template <class ACE_LOCK>
00572 ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard (void)
00573 {
00574 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard");
00575   this->init_key ();
00576 }
00577 
00578 template <class ACE_LOCK> int
00579 ACE_TSS_Guard<ACE_LOCK>::release (void)
00580 {
00581 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::release");
00582 
00583   ACE_Guard<ACE_LOCK> *guard = 0;
00584 
00585 #if defined (ACE_HAS_THR_C_DEST)
00586   ACE_TSS_Adapter *tss_adapter = 0;
00587   ACE_Thread::getspecific (this->key_,
00588                            (void **) &tss_adapter);
00589   guard = (ACE_Guard<ACE_LOCK> *)tss_adapter->ts_obj_;
00590 #else
00591   ACE_Thread::getspecific (this->key_,
00592                            (void **) &guard);
00593 #endif /* ACE_HAS_THR_C_DEST */
00594 
00595   return guard->release ();
00596 }
00597 
00598 template <class ACE_LOCK> int
00599 ACE_TSS_Guard<ACE_LOCK>::remove (void)
00600 {
00601 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::remove");
00602 
00603   ACE_Guard<ACE_LOCK> *guard = 0;
00604 
00605 #if defined (ACE_HAS_THR_C_DEST)
00606   ACE_TSS_Adapter *tss_adapter = 0;
00607   ACE_Thread::getspecific (this->key_,
00608                            (void **) &tss_adapter);
00609   guard = (ACE_Guard<ACE_LOCK> *) tss_adapter->ts_obj_;
00610 #else
00611   ACE_Thread::getspecific (this->key_,
00612                            (void **) &guard);
00613 #endif /* ACE_HAS_THR_C_DEST */
00614 
00615   return guard->remove ();
00616 }
00617 
00618 template <class ACE_LOCK>
00619 ACE_TSS_Guard<ACE_LOCK>::~ACE_TSS_Guard (void)
00620 {
00621 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::~ACE_TSS_Guard");
00622 
00623   ACE_Guard<ACE_LOCK> *guard = 0;
00624 
00625 #if defined (ACE_HAS_THR_C_DEST)
00626   ACE_TSS_Adapter *tss_adapter = 0;
00627   ACE_Thread::getspecific (this->key_,
00628                            (void **) &tss_adapter);
00629   guard = (ACE_Guard<ACE_LOCK> *) tss_adapter->ts_obj_;
00630 #else
00631   ACE_Thread::getspecific (this->key_,
00632                            (void **) &guard);
00633 #endif /* ACE_HAS_THR_C_DEST */
00634 
00635   // Make sure that this pointer is NULL when we shut down...
00636   ACE_Thread::setspecific (this->key_, 0);
00637   ACE_Thread::keyfree (this->key_);
00638   // Destructor releases lock.
00639   delete guard;
00640 }
00641 
00642 template <class ACE_LOCK> void
00643 ACE_TSS_Guard<ACE_LOCK>::cleanup (void *ptr)
00644 {
00645 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::cleanup");
00646 
00647   // Destructor releases lock.
00648   delete (ACE_Guard<ACE_LOCK> *) ptr;
00649 }
00650 
00651 template <class ACE_LOCK>
00652 ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard (ACE_LOCK &lock, int block)
00653 {
00654 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard");
00655 
00656   this->init_key ();
00657   ACE_Guard<ACE_LOCK> *guard;
00658   ACE_NEW (guard,
00659            ACE_Guard<ACE_LOCK> (lock,
00660                                 block));
00661 
00662 #if defined (ACE_HAS_THR_C_DEST)
00663   ACE_TSS_Adapter *tss_adapter;
00664   ACE_NEW (tss_adapter,
00665            ACE_TSS_Adapter ((void *) guard,
00666                             ACE_TSS_Guard<ACE_LOCK>::cleanup));
00667   ACE_Thread::setspecific (this->key_,
00668                            (void *) tss_adapter);
00669 #else
00670   ACE_Thread::setspecific (this->key_,
00671                            (void *) guard);
00672 #endif /* ACE_HAS_THR_C_DEST */
00673 }
00674 
00675 template <class ACE_LOCK> int
00676 ACE_TSS_Guard<ACE_LOCK>::acquire (void)
00677 {
00678 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::acquire");
00679 
00680   ACE_Guard<ACE_LOCK> *guard = 0;
00681 
00682 #if defined (ACE_HAS_THR_C_DEST)
00683   ACE_TSS_Adapter *tss_adapter = 0;
00684   ACE_Thread::getspecific (this->key_,
00685                            (void **) &tss_adapter);
00686   guard = (ACE_Guard<ACE_LOCK> *) tss_adapter->ts_obj_;
00687 #else
00688   ACE_Thread::getspecific (this->key_,
00689                            (void **) &guard);
00690 #endif /* ACE_HAS_THR_C_DEST */
00691 
00692   return guard->acquire ();
00693 }
00694 
00695 template <class ACE_LOCK> int
00696 ACE_TSS_Guard<ACE_LOCK>::tryacquire (void)
00697 {
00698 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::tryacquire");
00699 
00700   ACE_Guard<ACE_LOCK> *guard = 0;
00701 
00702 #if defined (ACE_HAS_THR_C_DEST)
00703   ACE_TSS_Adapter *tss_adapter = 0;
00704   ACE_Thread::getspecific (this->key_,
00705                            (void **) &tss_adapter);
00706   guard = (ACE_Guard<ACE_LOCK> *) tss_adapter->ts_obj_;
00707 #else
00708   ACE_Thread::getspecific (this->key_,
00709                            (void **) &guard);
00710 #endif /* ACE_HAS_THR_C_DEST */
00711 
00712   return guard->tryacquire ();
00713 }
00714 
00715 template <class ACE_LOCK>
00716 ACE_TSS_Write_Guard<ACE_LOCK>::ACE_TSS_Write_Guard (ACE_LOCK &lock,
00717                                                     int block)
00718 {
00719 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::ACE_TSS_Write_Guard");
00720 
00721   this->init_key ();
00722   ACE_Guard<ACE_LOCK> *guard;
00723   ACE_NEW (guard,
00724            ACE_Write_Guard<ACE_LOCK> (lock,
00725                                       block));
00726 
00727 #if defined (ACE_HAS_THR_C_DEST)
00728   ACE_TSS_Adapter *tss_adapter;
00729   ACE_NEW (tss_adapter,
00730            ACE_TSS_Adapter ((void *) guard,
00731                             ACE_TSS_Guard<ACE_LOCK>::cleanup));
00732   ACE_Thread::setspecific (this->key_,
00733                            (void *) tss_adapter);
00734 #else
00735   ACE_Thread::setspecific (this->key_,
00736                            (void *) guard);
00737 #endif /* ACE_HAS_THR_C_DEST */
00738 }
00739 
00740 template <class ACE_LOCK> int
00741 ACE_TSS_Write_Guard<ACE_LOCK>::acquire (void)
00742 {
00743 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::acquire");
00744 
00745   ACE_Write_Guard<ACE_LOCK> *guard = 0;
00746 
00747 #if defined (ACE_HAS_THR_C_DEST)
00748   ACE_TSS_Adapter *tss_adapter = 0;
00749   ACE_Thread::getspecific (this->key_,
00750                            (void **) &tss_adapter);
00751   guard = (ACE_Guard<ACE_LOCK> *) tss_adapter->ts_obj_;
00752 #else
00753   ACE_Thread::getspecific (this->key_,
00754                            (void **) &guard);
00755 #endif /* ACE_HAS_THR_C_DEST */
00756 
00757   return guard->acquire_write ();
00758 }
00759 
00760 template <class ACE_LOCK> int
00761 ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire (void)
00762 {
00763 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire");
00764 
00765   ACE_Write_Guard<ACE_LOCK> *guard = 0;
00766 
00767 #if defined (ACE_HAS_THR_C_DEST)
00768   ACE_TSS_Adapter *tss_adapter = 0;
00769   ACE_Thread::getspecific (this->key_,
00770                            (void **) &tss_adapter);
00771   guard = (ACE_Guard<ACE_LOCK> *) tss_adapter->ts_obj_;
00772 #else
00773   ACE_Thread::getspecific (this->key_,
00774                            (void **) &guard);
00775 #endif /* ACE_HAS_THR_C_DEST */
00776 
00777   return guard->tryacquire_write ();
00778 }
00779 
00780 template <class ACE_LOCK> int
00781 ACE_TSS_Write_Guard<ACE_LOCK>::acquire_write (void)
00782 {
00783 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::acquire_write");
00784 
00785   return this->acquire ();
00786 }
00787 
00788 template <class ACE_LOCK> int
00789 ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire_write (void)
00790 {
00791 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire_write");
00792 
00793   return this->tryacquire ();
00794 }
00795 
00796 template <class ACE_LOCK> void
00797 ACE_TSS_Write_Guard<ACE_LOCK>::dump (void) const
00798 {
00799 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::dump");
00800   ACE_TSS_Guard<ACE_LOCK>::dump ();
00801 }
00802 
00803 template <class ACE_LOCK>
00804 ACE_TSS_Read_Guard<ACE_LOCK>::ACE_TSS_Read_Guard (ACE_LOCK &lock, int block)
00805 {
00806 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::ACE_TSS_Read_Guard");
00807 
00808   this->init_key ();
00809   ACE_Guard<ACE_LOCK> *guard;
00810   ACE_NEW (guard,
00811            ACE_Read_Guard<ACE_LOCK> (lock,
00812                                      block));
00813 #if defined (ACE_HAS_THR_C_DEST)
00814   ACE_TSS_Adapter *tss_adapter;
00815   ACE_NEW (tss_adapter,
00816            ACE_TSS_Adapter ((void *)guard,
00817                             ACE_TSS_Guard<ACE_LOCK>::cleanup));
00818   ACE_Thread::setspecific (this->key_,
00819                            (void *) tss_adapter);
00820 #else
00821   ACE_Thread::setspecific (this->key_,
00822                            (void *) guard);
00823 #endif /* ACE_HAS_THR_C_DEST */
00824 }
00825 
00826 template <class ACE_LOCK> int
00827 ACE_TSS_Read_Guard<ACE_LOCK>::acquire (void)
00828 {
00829 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::acquire");
00830 
00831   ACE_Read_Guard<ACE_LOCK> *guard = 0;
00832 
00833 #if defined (ACE_HAS_THR_C_DEST)
00834   ACE_TSS_Adapter *tss_adapter = 0;
00835   ACE_Thread::getspecific (this->key_,
00836                            (void **) &tss_adapter);
00837   guard = (ACE_Guard<ACE_LOCK> *) tss_adapter->ts_obj_;
00838 #else
00839   ACE_Thread::getspecific (this->key_,
00840                            (void **) &guard);
00841 #endif /* ACE_HAS_THR_C_DEST */
00842 
00843   return guard->acquire_read ();
00844 }
00845 
00846 template <class ACE_LOCK> int
00847 ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire (void)
00848 {
00849 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire");
00850 
00851   ACE_Read_Guard<ACE_LOCK> *guard = 0;
00852 
00853 #if defined (ACE_HAS_THR_C_DEST)
00854   ACE_TSS_Adapter *tss_adapter = 0;
00855   ACE_Thread::getspecific (this->key_,
00856                            (void **) &tss_adapter);
00857   guard = (ACE_Guard<ACE_LOCK> *) tss_adapter->ts_obj_;
00858 #else
00859   ACE_Thread::getspecific (this->key_,
00860                            (void **) &guard);
00861 #endif /* ACE_HAS_THR_C_DEST */
00862 
00863   return guard->tryacquire_read ();
00864 }
00865 
00866 template <class ACE_LOCK> int
00867 ACE_TSS_Read_Guard<ACE_LOCK>::acquire_read (void)
00868 {
00869 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::acquire_read");
00870 
00871   return this->acquire ();
00872 }
00873 
00874 template <class ACE_LOCK> int
00875 ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire_read (void)
00876 {
00877 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire_read");
00878 
00879   return this->tryacquire ();
00880 }
00881 
00882 template <class ACE_LOCK> void
00883 ACE_TSS_Read_Guard<ACE_LOCK>::dump (void) const
00884 {
00885 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::dump");
00886   ACE_TSS_Guard<ACE_LOCK>::dump ();
00887 }
00888 
00889 
00890 #endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */
00891 
00892 #endif /* ACE_SYNCH_T_C */

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