TSS_T.cpp

Go to the documentation of this file.
00001 // $Id: TSS_T.cpp 80826 2008-03-04 14:51:23Z wotte $
00002 
00003 #ifndef ACE_TSS_T_CPP
00004 #define ACE_TSS_T_CPP
00005 
00006 #include "ace/TSS_T.h"
00007 
00008 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00009 # pragma once
00010 #endif /* ACE_LACKS_PRAGMA_ONCE */
00011 
00012 #if !defined (__ACE_INLINE__)
00013 #include "ace/TSS_T.inl"
00014 #endif /* __ACE_INLINE__ */
00015 
00016 #include "ace/Thread.h"
00017 #include "ace/Log_Msg.h"
00018 #include "ace/Guard_T.h"
00019 #include "ace/OS_NS_stdio.h"
00020 
00021 #if defined (ACE_HAS_THR_C_DEST)
00022 #  include "ace/TSS_Adapter.h"
00023 #endif /* ACE_HAS_THR_C_DEST */
00024 
00025 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00026 
00027 ACE_ALLOC_HOOK_DEFINE(ACE_TSS)
00028 
00029 template <class TYPE>
00030 ACE_TSS<TYPE>::~ACE_TSS (void)
00031 {
00032 #if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
00033   if (this->once_)
00034   {
00035     ACE_OS::thr_key_detach (this->key_, this);
00036     ACE_OS::thr_keyfree (this->key_);
00037   }
00038 #else // defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
00039   // We own it, we need to delete it.
00040   delete type_;
00041 #endif // defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
00042 }
00043 
00044 template <class TYPE> TYPE *
00045 ACE_TSS<TYPE>::operator-> () const
00046 {
00047   return this->ts_get ();
00048 }
00049 
00050 template <class TYPE>
00051 ACE_TSS<TYPE>::operator TYPE *(void) const
00052 {
00053   return this->ts_get ();
00054 }
00055 
00056 template <class TYPE> TYPE *
00057 ACE_TSS<TYPE>::make_TSS_TYPE (void) const
00058 {
00059   TYPE *temp = 0;
00060   ACE_NEW_RETURN (temp,
00061                   TYPE,
00062                   0);
00063   return temp;
00064 }
00065 
00066 template <class TYPE> void
00067 ACE_TSS<TYPE>::dump (void) const
00068 {
00069 #if defined (ACE_HAS_DUMP)
00070 // ACE_TRACE ("ACE_TSS<TYPE>::dump");
00071 #if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
00072   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00073   this->keylock_.dump ();
00074   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("key_ = %d\n"), this->key_));
00075   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nonce_ = %d"), this->once_));
00076   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n")));
00077   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00078 #endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */
00079 #endif /* ACE_HAS_DUMP */
00080 }
00081 
00082 #if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
00083 #if defined (ACE_HAS_THR_C_DEST)
00084 extern "C" void ACE_TSS_C_cleanup (void *); // defined in Synch.cpp
00085 #endif /* ACE_HAS_THR_C_DEST */
00086 
00087 template <class TYPE> void
00088 ACE_TSS<TYPE>::cleanup (void *ptr)
00089 {
00090   // Cast this to the concrete TYPE * so the destructor gets called.
00091   delete (TYPE *) ptr;
00092 }
00093 
00094 template <class TYPE> int
00095 ACE_TSS<TYPE>::ts_init (void)
00096 {
00097   // Ensure that we are serialized!
00098   ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->keylock_, 0);
00099 
00100   // Use the Double-Check pattern to make sure we only create the key
00101   // once!
00102   if (!this->once_)
00103     {
00104       if (ACE_Thread::keycreate (&this->key_,
00105 #if defined (ACE_HAS_THR_C_DEST)
00106                                  &ACE_TSS_C_cleanup,
00107 #else
00108                                  &ACE_TSS<TYPE>::cleanup,
00109 #endif /* ACE_HAS_THR_C_DEST */
00110                                  (void *) this) != 0)
00111         return -1; // Major problems, this should *never* happen!
00112       else
00113         {
00114           // This *must* come last to avoid race conditions!
00115           this->once_ = true;
00116           return 0;
00117         }
00118     }
00119 
00120   return 0;
00121 }
00122 
00123 template <class TYPE>
00124 ACE_TSS<TYPE>::ACE_TSS (TYPE *ts_obj)
00125   : once_ (false),
00126     key_ (ACE_OS::NULL_key)
00127 {
00128   // If caller has passed us a non-NULL TYPE *, then we'll just use
00129   // this to initialize the thread-specific value.  Thus, subsequent
00130   // calls to operator->() will return this value.  This is useful
00131   // since it enables us to assign objects to thread-specific data
00132   // that have arbitrarily complex constructors!
00133 
00134   if (ts_obj != 0)
00135     {
00136       if (this->ts_init () == -1)
00137         {
00138           // Save/restore errno.
00139           ACE_Errno_Guard error (errno);
00140           // What should we do if this call fails?!
00141 #if defined (ACE_HAS_WINCE)
00142           ::MessageBox (0,
00143                         ACE_TEXT ("ACE_Thread::keycreate() failed!"),
00144                         ACE_TEXT ("ACE_TSS::ACE_TSS"),
00145                         MB_OK);
00146 #else
00147           ACE_OS::fprintf (stderr,
00148                            "ACE_Thread::keycreate() failed!");
00149 #endif /* ACE_HAS_WINCE */
00150           return;
00151         }
00152 
00153 #if defined (ACE_HAS_THR_C_DEST)
00154       // Encapsulate a ts_obj and it's destructor in an
00155       // ACE_TSS_Adapter.
00156       ACE_TSS_Adapter *tss_adapter = 0;
00157       ACE_NEW (tss_adapter,
00158                ACE_TSS_Adapter ((void *) ts_obj,
00159                                 ACE_TSS<TYPE>::cleanup));
00160 
00161       // Put the adapter in thread specific storage
00162       if (ACE_Thread::setspecific (this->key_,
00163                                    (void *) tss_adapter) != 0)
00164         {
00165           delete tss_adapter;
00166           ACE_ERROR ((LM_ERROR,
00167                       ACE_TEXT ("%p\n"),
00168                       ACE_TEXT ("ACE_Thread::setspecific() failed!")));
00169         }
00170 #else
00171       if (ACE_Thread::setspecific (this->key_,
00172                                    (void *) ts_obj) != 0)
00173         ACE_ERROR ((LM_ERROR,
00174                     ACE_TEXT ("%p\n"),
00175                     ACE_TEXT ("ACE_Thread::setspecific() failed!")));
00176 #endif /* ACE_HAS_THR_C_DEST */
00177     }
00178 }
00179 
00180 template <class TYPE> TYPE *
00181 ACE_TSS<TYPE>::ts_get (void) const
00182 {
00183   if (!this->once_)
00184     {
00185       // Create and initialize thread-specific ts_obj.
00186       if (const_cast< ACE_TSS < TYPE > * >(this)->ts_init () == -1)
00187         // Seriously wrong..
00188         return 0;
00189     }
00190 
00191   TYPE *ts_obj = 0;
00192 
00193 #if defined (ACE_HAS_THR_C_DEST)
00194   ACE_TSS_Adapter *tss_adapter = 0;
00195 
00196   // Get the adapter from thread-specific storage
00197   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00198   if (ACE_Thread::getspecific (this->key_, &temp) == -1)
00199     return 0; // This should not happen!
00200   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00201 
00202   // Check to see if this is the first time in for this thread.
00203   if (tss_adapter == 0)
00204 #else
00205   // Get the ts_obj from thread-specific storage.  Note that no locks
00206   // are required here...
00207   void *temp = ts_obj; // Need this temp to keep G++ from complaining.
00208   if (ACE_Thread::getspecific (this->key_, &temp) == -1)
00209     return 0; // This should not happen!
00210   ts_obj = static_cast <TYPE *> (temp);
00211 
00212   // Check to see if this is the first time in for this thread.
00213   if (ts_obj == 0)
00214 #endif /* ACE_HAS_THR_C_DEST */
00215     {
00216       // Allocate memory off the heap and store it in a pointer in
00217       // thread-specific storage (on the stack...).
00218 
00219       ts_obj = this->make_TSS_TYPE ();
00220 
00221       if (ts_obj == 0)
00222         return 0;
00223 
00224 #if defined (ACE_HAS_THR_C_DEST)
00225       // Encapsulate a ts_obj and it's destructor in an
00226       // ACE_TSS_Adapter.
00227       ACE_NEW_RETURN (tss_adapter,
00228                       ACE_TSS_Adapter (ts_obj,
00229                                        ACE_TSS<TYPE>::cleanup), 0);
00230 
00231       // Put the adapter in thread specific storage
00232       if (ACE_Thread::setspecific (this->key_,
00233                                    (void *) tss_adapter) != 0)
00234         {
00235           delete tss_adapter;
00236           delete ts_obj;
00237           return 0; // Major problems, this should *never* happen!
00238         }
00239 #else
00240       // Store the dynamically allocated pointer in thread-specific
00241       // storage.
00242       if (ACE_Thread::setspecific (this->key_,
00243                                    (void *) ts_obj) != 0)
00244         {
00245           delete ts_obj;
00246           return 0; // Major problems, this should *never* happen!
00247         }
00248 #endif /* ACE_HAS_THR_C_DEST */
00249     }
00250 
00251 #if defined (ACE_HAS_THR_C_DEST)
00252   // Return the underlying ts object.
00253   return static_cast <TYPE *> (tss_adapter->ts_obj_);
00254 #else
00255   return ts_obj;
00256 #endif /* ACE_HAS_THR_C_DEST */
00257 }
00258 
00259 // Get the thread-specific object for the key associated with this
00260 // object.  Returns 0 if the ts_obj has never been initialized,
00261 // otherwise returns a pointer to the ts_obj.
00262 
00263 template <class TYPE> TYPE *
00264 ACE_TSS<TYPE>::ts_object (void) const
00265 {
00266   if (!this->once_) // Return 0 if we've never been initialized.
00267     return 0;
00268 
00269   TYPE *ts_obj = 0;
00270 
00271 #if defined (ACE_HAS_THR_C_DEST)
00272   ACE_TSS_Adapter *tss_adapter = 0;
00273 
00274   // Get the tss adapter from thread-specific storage
00275   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00276   if (ACE_Thread::getspecific (this->key_, &temp) == -1)
00277     {
00278       return 0; // This should not happen!
00279     }
00280   else
00281     {
00282       tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00283       {
00284         if (tss_adapter != 0)
00285             // Extract the real TS object.
00286             ts_obj = static_cast <TYPE *> (tss_adapter->ts_obj_);
00287       }
00288     }
00289 #else
00290   void *temp = ts_obj; // Need this temp to keep G++ from complaining.
00291   if (ACE_Thread::getspecific (this->key_, &temp) == -1)
00292     return 0; // This should not happen!
00293   ts_obj = static_cast <TYPE *> (temp);
00294 #endif /* ACE_HAS_THR_C_DEST */
00295 
00296   return ts_obj;
00297 }
00298 
00299 template <class TYPE> TYPE *
00300 ACE_TSS<TYPE>::ts_object (TYPE *new_ts_obj)
00301 {
00302   // Note, we shouldn't hold the keylock at this point because
00303   // <ts_init> does it for us and we'll end up with deadlock
00304   // otherwise...
00305   if (!this->once_)
00306     {
00307       // Create and initialize thread-specific ts_obj.
00308       if (this->ts_init () == -1)
00309         return 0;
00310     }
00311 
00312   TYPE *ts_obj = 0;
00313 
00314 #if defined (ACE_HAS_THR_C_DEST)
00315   ACE_TSS_Adapter *tss_adapter = 0;
00316 
00317   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00318   if (ACE_Thread::getspecific (this->key_, &temp) == -1)
00319     return 0; // This should not happen!
00320   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00321 
00322   if (tss_adapter != 0)
00323     {
00324       ts_obj = static_cast <TYPE *> (tss_adapter->ts_obj_);
00325       delete tss_adapter;       // don't need this anymore
00326     }
00327 
00328   ACE_NEW_RETURN (tss_adapter,
00329                   ACE_TSS_Adapter ((void *) new_ts_obj,
00330                                    ACE_TSS<TYPE>::cleanup),
00331                   0);
00332 
00333   if (ACE_Thread::setspecific (this->key_,
00334                                (void *) tss_adapter) == -1)
00335     {
00336       delete tss_adapter;
00337       return ts_obj; // This should not happen!
00338     }
00339 #else
00340   void *temp = ts_obj; // Need this temp to keep G++ from complaining.
00341   if (ACE_Thread::getspecific (this->key_, &temp) == -1)
00342     return 0; // This should not happen!
00343   ts_obj = static_cast <TYPE *> (temp);
00344   if (ACE_Thread::setspecific (this->key_, (void *) new_ts_obj) == -1)
00345     return ts_obj; // This should not happen!
00346 #endif /* ACE_HAS_THR_C_DEST */
00347 
00348   return ts_obj;
00349 }
00350 
00351 ACE_ALLOC_HOOK_DEFINE(ACE_TSS_Guard)
00352 
00353 template <class ACE_LOCK> void
00354 ACE_TSS_Guard<ACE_LOCK>::dump (void) const
00355 {
00356 #if defined (ACE_HAS_DUMP)
00357 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::dump");
00358 
00359   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00360   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("key_ = %d"), this->key_));
00361   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n")));
00362   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00363 #endif /* ACE_HAS_DUMP */
00364 }
00365 
00366 template <class ACE_LOCK> void
00367 ACE_TSS_Guard<ACE_LOCK>::init_key (void)
00368 {
00369 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::init_key");
00370 
00371   this->key_ = ACE_OS::NULL_key;
00372   ACE_Thread::keycreate (&this->key_,
00373 #if defined (ACE_HAS_THR_C_DEST)
00374                          &ACE_TSS_C_cleanup,
00375 #else
00376                          &ACE_TSS_Guard<ACE_LOCK>::cleanup,
00377 #endif /* ACE_HAS_THR_C_DEST */
00378                          (void *) this);
00379 }
00380 
00381 template <class ACE_LOCK>
00382 ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard (void)
00383 {
00384 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard");
00385   this->init_key ();
00386 }
00387 
00388 template <class ACE_LOCK> int
00389 ACE_TSS_Guard<ACE_LOCK>::release (void)
00390 {
00391 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::release");
00392 
00393   ACE_Guard<ACE_LOCK> *guard = 0;
00394 
00395 #if defined (ACE_HAS_THR_C_DEST)
00396   ACE_TSS_Adapter *tss_adapter = 0;
00397   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00398   ACE_Thread::getspecific (this->key_, &temp);
00399   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00400   guard = static_cast <ACE_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00401 #else
00402   void *temp = guard; // Need this temp to keep G++ from complaining.
00403   ACE_Thread::getspecific (this->key_, &temp);
00404   guard = static_cast <ACE_Guard<ACE_LOCK> *> (temp);
00405 #endif /* ACE_HAS_THR_C_DEST */
00406 
00407   return guard->release ();
00408 }
00409 
00410 template <class ACE_LOCK> int
00411 ACE_TSS_Guard<ACE_LOCK>::remove (void)
00412 {
00413 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::remove");
00414 
00415   ACE_Guard<ACE_LOCK> *guard = 0;
00416 
00417 #if defined (ACE_HAS_THR_C_DEST)
00418   ACE_TSS_Adapter *tss_adapter = 0;
00419   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00420   ACE_Thread::getspecific (this->key_, &temp);
00421   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00422   guard = static_cast <ACE_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00423 #else
00424   void *temp = guard; // Need this temp to keep G++ from complaining.
00425   ACE_Thread::getspecific (this->key_, &temp);
00426   guard = static_cast <ACE_Guard<ACE_LOCK> *> (temp);
00427 #endif /* ACE_HAS_THR_C_DEST */
00428 
00429   return guard->remove ();
00430 }
00431 
00432 template <class ACE_LOCK>
00433 ACE_TSS_Guard<ACE_LOCK>::~ACE_TSS_Guard (void)
00434 {
00435 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::~ACE_TSS_Guard");
00436 
00437   ACE_Guard<ACE_LOCK> *guard = 0;
00438 
00439 #if defined (ACE_HAS_THR_C_DEST)
00440   ACE_TSS_Adapter *tss_adapter = 0;
00441   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00442   ACE_Thread::getspecific (this->key_, &temp);
00443   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00444   guard = static_cast <ACE_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00445 #else
00446   void *temp = guard; // Need this temp to keep G++ from complaining.
00447   ACE_Thread::getspecific (this->key_, &temp);
00448   guard = static_cast <ACE_Guard<ACE_LOCK> *> (temp);
00449 #endif /* ACE_HAS_THR_C_DEST */
00450 
00451   // Make sure that this pointer is NULL when we shut down...
00452   ACE_Thread::setspecific (this->key_, 0);
00453   ACE_Thread::keyfree (this->key_);
00454   // Destructor releases lock.
00455   delete guard;
00456 }
00457 
00458 template <class ACE_LOCK> void
00459 ACE_TSS_Guard<ACE_LOCK>::cleanup (void *ptr)
00460 {
00461 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::cleanup");
00462 
00463   // Destructor releases lock.
00464   delete (ACE_Guard<ACE_LOCK> *) ptr;
00465 }
00466 
00467 template <class ACE_LOCK>
00468 ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard (ACE_LOCK &lock, int block)
00469 {
00470 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard");
00471 
00472   this->init_key ();
00473   ACE_Guard<ACE_LOCK> *guard = 0;
00474   ACE_NEW (guard,
00475            ACE_Guard<ACE_LOCK> (lock,
00476                                 block));
00477 
00478 #if defined (ACE_HAS_THR_C_DEST)
00479   ACE_TSS_Adapter *tss_adapter = 0;
00480   ACE_NEW (tss_adapter,
00481            ACE_TSS_Adapter ((void *) guard,
00482                             ACE_TSS_Guard<ACE_LOCK>::cleanup));
00483   ACE_Thread::setspecific (this->key_,
00484                            (void *) tss_adapter);
00485 #else
00486   ACE_Thread::setspecific (this->key_,
00487                            (void *) guard);
00488 #endif /* ACE_HAS_THR_C_DEST */
00489 }
00490 
00491 template <class ACE_LOCK> int
00492 ACE_TSS_Guard<ACE_LOCK>::acquire (void)
00493 {
00494 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::acquire");
00495 
00496   ACE_Guard<ACE_LOCK> *guard = 0;
00497 
00498 #if defined (ACE_HAS_THR_C_DEST)
00499   ACE_TSS_Adapter *tss_adapter = 0;
00500   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00501   ACE_Thread::getspecific (this->key_, &temp);
00502   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00503   guard = static_cast <ACE_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00504 #else
00505   void *temp = guard; // Need this temp to keep G++ from complaining.
00506   ACE_Thread::getspecific (this->key_, &temp);
00507   guard = static_cast <ACE_Guard<ACE_LOCK> *> (temp);
00508 #endif /* ACE_HAS_THR_C_DEST */
00509 
00510   return guard->acquire ();
00511 }
00512 
00513 template <class ACE_LOCK> int
00514 ACE_TSS_Guard<ACE_LOCK>::tryacquire (void)
00515 {
00516 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::tryacquire");
00517 
00518   ACE_Guard<ACE_LOCK> *guard = 0;
00519 
00520 #if defined (ACE_HAS_THR_C_DEST)
00521   ACE_TSS_Adapter *tss_adapter = 0;
00522   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00523   ACE_Thread::getspecific (this->key_, &temp);
00524   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00525   guard = static_cast <ACE_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00526 #else
00527   void *temp = guard; // Need this temp to keep G++ from complaining.
00528   ACE_Thread::getspecific (this->key_, &temp);
00529   guard = static_cast <ACE_Guard<ACE_LOCK> *> (temp);
00530 #endif /* ACE_HAS_THR_C_DEST */
00531 
00532   return guard->tryacquire ();
00533 }
00534 
00535 template <class ACE_LOCK>
00536 ACE_TSS_Write_Guard<ACE_LOCK>::ACE_TSS_Write_Guard (ACE_LOCK &lock,
00537                                                     int block)
00538 {
00539 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::ACE_TSS_Write_Guard");
00540 
00541   this->init_key ();
00542   ACE_Guard<ACE_LOCK> *guard;
00543   ACE_NEW (guard,
00544            ACE_Write_Guard<ACE_LOCK> (lock,
00545                                       block));
00546 
00547 #if defined (ACE_HAS_THR_C_DEST)
00548   ACE_TSS_Adapter *tss_adapter = 0;
00549   ACE_NEW (tss_adapter,
00550            ACE_TSS_Adapter ((void *) guard,
00551                             ACE_TSS_Guard<ACE_LOCK>::cleanup));
00552   ACE_Thread::setspecific (this->key_,
00553                            (void *) tss_adapter);
00554 #else
00555   ACE_Thread::setspecific (this->key_,
00556                            (void *) guard);
00557 #endif /* ACE_HAS_THR_C_DEST */
00558 }
00559 
00560 template <class ACE_LOCK> int
00561 ACE_TSS_Write_Guard<ACE_LOCK>::acquire (void)
00562 {
00563 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::acquire");
00564 
00565   ACE_Write_Guard<ACE_LOCK> *guard = 0;
00566 
00567 #if defined (ACE_HAS_THR_C_DEST)
00568   ACE_TSS_Adapter *tss_adapter = 0;
00569   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00570   ACE_Thread::getspecific (this->key_, &temp);
00571   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00572   guard = static_cast <ACE_Write_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00573 #else
00574   void *temp = guard; // Need this temp to keep G++ from complaining.
00575   ACE_Thread::getspecific (this->key_, &temp);
00576   guard = static_cast <ACE_Write_Guard<ACE_LOCK> *> (temp);
00577 #endif /* ACE_HAS_THR_C_DEST */
00578 
00579   return guard->acquire_write ();
00580 }
00581 
00582 template <class ACE_LOCK> int
00583 ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire (void)
00584 {
00585 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire");
00586 
00587   ACE_Write_Guard<ACE_LOCK> *guard = 0;
00588 
00589 #if defined (ACE_HAS_THR_C_DEST)
00590   ACE_TSS_Adapter *tss_adapter = 0;
00591   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00592   ACE_Thread::getspecific (this->key_, &temp);
00593   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00594   guard = static_cast <ACE_Write_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00595 #else
00596   void *temp = guard; // Need this temp to keep G++ from complaining.
00597   ACE_Thread::getspecific (this->key_, &temp);
00598   guard = static_cast <ACE_Write_Guard<ACE_LOCK> *> (temp);
00599 #endif /* ACE_HAS_THR_C_DEST */
00600 
00601   return guard->tryacquire_write ();
00602 }
00603 
00604 template <class ACE_LOCK> int
00605 ACE_TSS_Write_Guard<ACE_LOCK>::acquire_write (void)
00606 {
00607 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::acquire_write");
00608 
00609   return this->acquire ();
00610 }
00611 
00612 template <class ACE_LOCK> int
00613 ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire_write (void)
00614 {
00615 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire_write");
00616 
00617   return this->tryacquire ();
00618 }
00619 
00620 template <class ACE_LOCK> void
00621 ACE_TSS_Write_Guard<ACE_LOCK>::dump (void) const
00622 {
00623 #if defined (ACE_HAS_DUMP)
00624 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::dump");
00625   ACE_TSS_Guard<ACE_LOCK>::dump ();
00626 #endif /* ACE_HAS_DUMP */
00627 }
00628 
00629 template <class ACE_LOCK>
00630 ACE_TSS_Read_Guard<ACE_LOCK>::ACE_TSS_Read_Guard (ACE_LOCK &lock, int block)
00631 {
00632 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::ACE_TSS_Read_Guard");
00633 
00634   this->init_key ();
00635   ACE_Guard<ACE_LOCK> *guard;
00636   ACE_NEW (guard,
00637            ACE_Read_Guard<ACE_LOCK> (lock,
00638                                      block));
00639 #if defined (ACE_HAS_THR_C_DEST)
00640   ACE_TSS_Adapter *tss_adapter;
00641   ACE_NEW (tss_adapter,
00642            ACE_TSS_Adapter ((void *)guard,
00643                             ACE_TSS_Guard<ACE_LOCK>::cleanup));
00644   ACE_Thread::setspecific (this->key_,
00645                            (void *) tss_adapter);
00646 #else
00647   ACE_Thread::setspecific (this->key_,
00648                            (void *) guard);
00649 #endif /* ACE_HAS_THR_C_DEST */
00650 }
00651 
00652 template <class ACE_LOCK> int
00653 ACE_TSS_Read_Guard<ACE_LOCK>::acquire (void)
00654 {
00655 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::acquire");
00656 
00657   ACE_Read_Guard<ACE_LOCK> *guard = 0;
00658 
00659 #if defined (ACE_HAS_THR_C_DEST)
00660   ACE_TSS_Adapter *tss_adapter = 0;
00661   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00662   ACE_Thread::getspecific (this->key_, &temp);
00663   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00664   guard = static_cast <ACE_Read_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00665 #else
00666   void *temp = guard; // Need this temp to keep G++ from complaining.
00667   ACE_Thread::getspecific (this->key_, &temp);
00668   guard = static_cast <ACE_Read_Guard<ACE_LOCK> *> (temp);
00669 #endif /* ACE_HAS_THR_C_DEST */
00670 
00671   return guard->acquire_read ();
00672 }
00673 
00674 template <class ACE_LOCK> int
00675 ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire (void)
00676 {
00677 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire");
00678 
00679   ACE_Read_Guard<ACE_LOCK> *guard = 0;
00680 
00681 #if defined (ACE_HAS_THR_C_DEST)
00682   ACE_TSS_Adapter *tss_adapter = 0;
00683   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00684   ACE_Thread::getspecific (this->key_, &temp);
00685   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00686   guard = static_cast <ACE_Read_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00687 #else
00688   void *temp = guard; // Need this temp to keep G++ from complaining.
00689   ACE_Thread::getspecific (this->key_, &temp);
00690   guard = static_cast <ACE_Read_Guard<ACE_LOCK> *> (temp);
00691 #endif /* ACE_HAS_THR_C_DEST */
00692 
00693   return guard->tryacquire_read ();
00694 }
00695 
00696 template <class ACE_LOCK> int
00697 ACE_TSS_Read_Guard<ACE_LOCK>::acquire_read (void)
00698 {
00699 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::acquire_read");
00700 
00701   return this->acquire ();
00702 }
00703 
00704 template <class ACE_LOCK> int
00705 ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire_read (void)
00706 {
00707 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire_read");
00708 
00709   return this->tryacquire ();
00710 }
00711 
00712 template <class ACE_LOCK> void
00713 ACE_TSS_Read_Guard<ACE_LOCK>::dump (void) const
00714 {
00715 #if defined (ACE_HAS_DUMP)
00716 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::dump");
00717   ACE_TSS_Guard<ACE_LOCK>::dump ();
00718 #endif /* ACE_HAS_DUMP */
00719 }
00720 
00721 #endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */
00722 
00723 ACE_END_VERSIONED_NAMESPACE_DECL
00724 
00725 #endif /* ACE_TSS_T_CPP */

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