TSS_T.cpp

Go to the documentation of this file.
00001 // TSS_T.cpp,v 4.23 2006/05/07 21:13:13 jeliazkov_i Exp
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_ != 0)
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_LIB_TEXT ("key_ = %d\n"), this->key_));
00075   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nonce_ = %d"), this->once_));
00076   ACE_DEBUG ((LM_DEBUG, ACE_LIB_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_ == 0)
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_ = 1;
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_ (0),
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_LIB_TEXT ("ACE_Thread::keycreate() failed!"),
00144                         ACE_LIB_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;
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_LIB_TEXT ("%p\n"),
00168                       ACE_LIB_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_LIB_TEXT ("%p\n"),
00175                     ACE_LIB_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_ == 0)
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   // Ensure that we are serialized!
00267   ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, (ACE_Thread_Mutex &) this->keylock_, 0);
00268 
00269   if (this->once_ == 0) // Return 0 if we've never been initialized.
00270     return 0;
00271 
00272   TYPE *ts_obj = 0;
00273 
00274 #if defined (ACE_HAS_THR_C_DEST)
00275   ACE_TSS_Adapter *tss_adapter = 0;
00276 
00277   // Get the tss adapter from thread-specific storage
00278   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00279   if (ACE_Thread::getspecific (this->key_, &temp) == -1)
00280     {
00281       return 0; // This should not happen!
00282     }
00283   else
00284     {
00285       tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00286       {
00287         if (tss_adapter != 0)
00288             // Extract the real TS object.
00289             ts_obj = static_cast <TYPE *> (tss_adapter->ts_obj_);
00290       }
00291     }
00292 #else
00293   void *temp = ts_obj; // Need this temp to keep G++ from complaining.
00294   if (ACE_Thread::getspecific (this->key_, &temp) == -1)
00295     return 0; // This should not happen!
00296   ts_obj = static_cast <TYPE *> (temp);
00297 #endif /* ACE_HAS_THR_C_DEST */
00298 
00299   return ts_obj;
00300 }
00301 
00302 template <class TYPE> TYPE *
00303 ACE_TSS<TYPE>::ts_object (TYPE *new_ts_obj)
00304 {
00305   // Note, we shouldn't hold the keylock at this point because
00306   // <ts_init> does it for us and we'll end up with deadlock
00307   // otherwise...
00308   if (this->once_ == 0)
00309     {
00310       // Create and initialize thread-specific ts_obj.
00311       if (this->ts_init () == -1)
00312         return 0;
00313     }
00314 
00315   // Ensure that we are serialized!
00316   ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->keylock_, 0);
00317 
00318   TYPE *ts_obj = 0;
00319 
00320 #if defined (ACE_HAS_THR_C_DEST)
00321   ACE_TSS_Adapter *tss_adapter = 0;
00322 
00323   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00324   if (ACE_Thread::getspecific (this->key_, &temp) == -1)
00325     return 0; // This should not happen!
00326   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00327 
00328   if (tss_adapter != 0)
00329     {
00330       ts_obj = static_cast <TYPE *> (tss_adapter->ts_obj_);
00331       delete tss_adapter;       // don't need this anymore
00332     }
00333 
00334   ACE_NEW_RETURN (tss_adapter,
00335                   ACE_TSS_Adapter ((void *) new_ts_obj,
00336                                    ACE_TSS<TYPE>::cleanup),
00337                   0);
00338 
00339   if (ACE_Thread::setspecific (this->key_,
00340                                (void *) tss_adapter) == -1)
00341     {
00342       delete tss_adapter;
00343       return ts_obj; // This should not happen!
00344     }
00345 #else
00346   void *temp = ts_obj; // Need this temp to keep G++ from complaining.
00347   if (ACE_Thread::getspecific (this->key_,
00348                                &temp) == -1)
00349     return 0; // This should not happen!
00350   ts_obj = static_cast <TYPE *> (temp);
00351   if (ACE_Thread::setspecific (this->key_,
00352                                (void *) new_ts_obj) == -1)
00353     return ts_obj; // This should not happen!
00354 #endif /* ACE_HAS_THR_C_DEST */
00355 
00356   return ts_obj;
00357 }
00358 
00359 ACE_ALLOC_HOOK_DEFINE(ACE_TSS_Guard)
00360 
00361 template <class ACE_LOCK> void
00362 ACE_TSS_Guard<ACE_LOCK>::dump (void) const
00363 {
00364 #if defined (ACE_HAS_DUMP)
00365 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::dump");
00366 
00367   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00368   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("key_ = %d"), this->key_));
00369   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n")));
00370   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00371 #endif /* ACE_HAS_DUMP */
00372 }
00373 
00374 template <class ACE_LOCK> void
00375 ACE_TSS_Guard<ACE_LOCK>::init_key (void)
00376 {
00377 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::init_key");
00378 
00379   this->key_ = ACE_OS::NULL_key;
00380   ACE_Thread::keycreate (&this->key_,
00381 #if defined (ACE_HAS_THR_C_DEST)
00382                          &ACE_TSS_C_cleanup,
00383 #else
00384                          &ACE_TSS_Guard<ACE_LOCK>::cleanup,
00385 #endif /* ACE_HAS_THR_C_DEST */
00386                          (void *) this);
00387 }
00388 
00389 template <class ACE_LOCK>
00390 ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard (void)
00391 {
00392 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard");
00393   this->init_key ();
00394 }
00395 
00396 template <class ACE_LOCK> int
00397 ACE_TSS_Guard<ACE_LOCK>::release (void)
00398 {
00399 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::release");
00400 
00401   ACE_Guard<ACE_LOCK> *guard = 0;
00402 
00403 #if defined (ACE_HAS_THR_C_DEST)
00404   ACE_TSS_Adapter *tss_adapter = 0;
00405   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00406   ACE_Thread::getspecific (this->key_, &temp);
00407   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00408   guard = static_cast <ACE_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00409 #else
00410   void *temp = guard; // Need this temp to keep G++ from complaining.
00411   ACE_Thread::getspecific (this->key_, &temp);
00412   guard = static_cast <ACE_Guard<ACE_LOCK> *> (temp);
00413 #endif /* ACE_HAS_THR_C_DEST */
00414 
00415   return guard->release ();
00416 }
00417 
00418 template <class ACE_LOCK> int
00419 ACE_TSS_Guard<ACE_LOCK>::remove (void)
00420 {
00421 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::remove");
00422 
00423   ACE_Guard<ACE_LOCK> *guard = 0;
00424 
00425 #if defined (ACE_HAS_THR_C_DEST)
00426   ACE_TSS_Adapter *tss_adapter = 0;
00427   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00428   ACE_Thread::getspecific (this->key_, &temp);
00429   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00430   guard = static_cast <ACE_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00431 #else
00432   void *temp = guard; // Need this temp to keep G++ from complaining.
00433   ACE_Thread::getspecific (this->key_, &temp);
00434   guard = static_cast <ACE_Guard<ACE_LOCK> *> (temp);
00435 #endif /* ACE_HAS_THR_C_DEST */
00436 
00437   return guard->remove ();
00438 }
00439 
00440 template <class ACE_LOCK>
00441 ACE_TSS_Guard<ACE_LOCK>::~ACE_TSS_Guard (void)
00442 {
00443 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::~ACE_TSS_Guard");
00444 
00445   ACE_Guard<ACE_LOCK> *guard = 0;
00446 
00447 #if defined (ACE_HAS_THR_C_DEST)
00448   ACE_TSS_Adapter *tss_adapter = 0;
00449   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00450   ACE_Thread::getspecific (this->key_, &temp);
00451   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00452   guard = static_cast <ACE_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00453 #else
00454   void *temp = guard; // Need this temp to keep G++ from complaining.
00455   ACE_Thread::getspecific (this->key_, &temp);
00456   guard = static_cast <ACE_Guard<ACE_LOCK> *> (temp);
00457 #endif /* ACE_HAS_THR_C_DEST */
00458 
00459   // Make sure that this pointer is NULL when we shut down...
00460   ACE_Thread::setspecific (this->key_, 0);
00461   ACE_Thread::keyfree (this->key_);
00462   // Destructor releases lock.
00463   delete guard;
00464 }
00465 
00466 template <class ACE_LOCK> void
00467 ACE_TSS_Guard<ACE_LOCK>::cleanup (void *ptr)
00468 {
00469 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::cleanup");
00470 
00471   // Destructor releases lock.
00472   delete (ACE_Guard<ACE_LOCK> *) ptr;
00473 }
00474 
00475 template <class ACE_LOCK>
00476 ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard (ACE_LOCK &lock, int block)
00477 {
00478 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard");
00479 
00480   this->init_key ();
00481   ACE_Guard<ACE_LOCK> *guard;
00482   ACE_NEW (guard,
00483            ACE_Guard<ACE_LOCK> (lock,
00484                                 block));
00485 
00486 #if defined (ACE_HAS_THR_C_DEST)
00487   ACE_TSS_Adapter *tss_adapter;
00488   ACE_NEW (tss_adapter,
00489            ACE_TSS_Adapter ((void *) guard,
00490                             ACE_TSS_Guard<ACE_LOCK>::cleanup));
00491   ACE_Thread::setspecific (this->key_,
00492                            (void *) tss_adapter);
00493 #else
00494   ACE_Thread::setspecific (this->key_,
00495                            (void *) guard);
00496 #endif /* ACE_HAS_THR_C_DEST */
00497 }
00498 
00499 template <class ACE_LOCK> int
00500 ACE_TSS_Guard<ACE_LOCK>::acquire (void)
00501 {
00502 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::acquire");
00503 
00504   ACE_Guard<ACE_LOCK> *guard = 0;
00505 
00506 #if defined (ACE_HAS_THR_C_DEST)
00507   ACE_TSS_Adapter *tss_adapter = 0;
00508   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00509   ACE_Thread::getspecific (this->key_, &temp);
00510   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00511   guard = static_cast <ACE_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00512 #else
00513   void *temp = guard; // Need this temp to keep G++ from complaining.
00514   ACE_Thread::getspecific (this->key_, &temp);
00515   guard = static_cast <ACE_Guard<ACE_LOCK> *> (temp);
00516 #endif /* ACE_HAS_THR_C_DEST */
00517 
00518   return guard->acquire ();
00519 }
00520 
00521 template <class ACE_LOCK> int
00522 ACE_TSS_Guard<ACE_LOCK>::tryacquire (void)
00523 {
00524 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::tryacquire");
00525 
00526   ACE_Guard<ACE_LOCK> *guard = 0;
00527 
00528 #if defined (ACE_HAS_THR_C_DEST)
00529   ACE_TSS_Adapter *tss_adapter = 0;
00530   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00531   ACE_Thread::getspecific (this->key_, &temp);
00532   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00533   guard = static_cast <ACE_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00534 #else
00535   void *temp = guard; // Need this temp to keep G++ from complaining.
00536   ACE_Thread::getspecific (this->key_, &temp);
00537   guard = static_cast <ACE_Guard<ACE_LOCK> *> (temp);
00538 #endif /* ACE_HAS_THR_C_DEST */
00539 
00540   return guard->tryacquire ();
00541 }
00542 
00543 template <class ACE_LOCK>
00544 ACE_TSS_Write_Guard<ACE_LOCK>::ACE_TSS_Write_Guard (ACE_LOCK &lock,
00545                                                     int block)
00546 {
00547 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::ACE_TSS_Write_Guard");
00548 
00549   this->init_key ();
00550   ACE_Guard<ACE_LOCK> *guard;
00551   ACE_NEW (guard,
00552            ACE_Write_Guard<ACE_LOCK> (lock,
00553                                       block));
00554 
00555 #if defined (ACE_HAS_THR_C_DEST)
00556   ACE_TSS_Adapter *tss_adapter;
00557   ACE_NEW (tss_adapter,
00558            ACE_TSS_Adapter ((void *) guard,
00559                             ACE_TSS_Guard<ACE_LOCK>::cleanup));
00560   ACE_Thread::setspecific (this->key_,
00561                            (void *) tss_adapter);
00562 #else
00563   ACE_Thread::setspecific (this->key_,
00564                            (void *) guard);
00565 #endif /* ACE_HAS_THR_C_DEST */
00566 }
00567 
00568 template <class ACE_LOCK> int
00569 ACE_TSS_Write_Guard<ACE_LOCK>::acquire (void)
00570 {
00571 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::acquire");
00572 
00573   ACE_Write_Guard<ACE_LOCK> *guard = 0;
00574 
00575 #if defined (ACE_HAS_THR_C_DEST)
00576   ACE_TSS_Adapter *tss_adapter = 0;
00577   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00578   ACE_Thread::getspecific (this->key_, &temp);
00579   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00580   guard = static_cast <ACE_Write_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00581 #else
00582   void *temp = guard; // Need this temp to keep G++ from complaining.
00583   ACE_Thread::getspecific (this->key_, &temp);
00584   guard = static_cast <ACE_Write_Guard<ACE_LOCK> *> (temp);
00585 #endif /* ACE_HAS_THR_C_DEST */
00586 
00587   return guard->acquire_write ();
00588 }
00589 
00590 template <class ACE_LOCK> int
00591 ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire (void)
00592 {
00593 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire");
00594 
00595   ACE_Write_Guard<ACE_LOCK> *guard = 0;
00596 
00597 #if defined (ACE_HAS_THR_C_DEST)
00598   ACE_TSS_Adapter *tss_adapter = 0;
00599   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00600   ACE_Thread::getspecific (this->key_, &temp);
00601   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00602   guard = static_cast <ACE_Write_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00603 #else
00604   void *temp = guard; // Need this temp to keep G++ from complaining.
00605   ACE_Thread::getspecific (this->key_, temp);
00606   guard = static_cast <ACE_Write_Guard<ACE_LOCK> *> (temp);
00607 #endif /* ACE_HAS_THR_C_DEST */
00608 
00609   return guard->tryacquire_write ();
00610 }
00611 
00612 template <class ACE_LOCK> int
00613 ACE_TSS_Write_Guard<ACE_LOCK>::acquire_write (void)
00614 {
00615 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::acquire_write");
00616 
00617   return this->acquire ();
00618 }
00619 
00620 template <class ACE_LOCK> int
00621 ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire_write (void)
00622 {
00623 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire_write");
00624 
00625   return this->tryacquire ();
00626 }
00627 
00628 template <class ACE_LOCK> void
00629 ACE_TSS_Write_Guard<ACE_LOCK>::dump (void) const
00630 {
00631 #if defined (ACE_HAS_DUMP)
00632 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::dump");
00633   ACE_TSS_Guard<ACE_LOCK>::dump ();
00634 #endif /* ACE_HAS_DUMP */
00635 }
00636 
00637 template <class ACE_LOCK>
00638 ACE_TSS_Read_Guard<ACE_LOCK>::ACE_TSS_Read_Guard (ACE_LOCK &lock, int block)
00639 {
00640 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::ACE_TSS_Read_Guard");
00641 
00642   this->init_key ();
00643   ACE_Guard<ACE_LOCK> *guard;
00644   ACE_NEW (guard,
00645            ACE_Read_Guard<ACE_LOCK> (lock,
00646                                      block));
00647 #if defined (ACE_HAS_THR_C_DEST)
00648   ACE_TSS_Adapter *tss_adapter;
00649   ACE_NEW (tss_adapter,
00650            ACE_TSS_Adapter ((void *)guard,
00651                             ACE_TSS_Guard<ACE_LOCK>::cleanup));
00652   ACE_Thread::setspecific (this->key_,
00653                            (void *) tss_adapter);
00654 #else
00655   ACE_Thread::setspecific (this->key_,
00656                            (void *) guard);
00657 #endif /* ACE_HAS_THR_C_DEST */
00658 }
00659 
00660 template <class ACE_LOCK> int
00661 ACE_TSS_Read_Guard<ACE_LOCK>::acquire (void)
00662 {
00663 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::acquire");
00664 
00665   ACE_Read_Guard<ACE_LOCK> *guard = 0;
00666 
00667 #if defined (ACE_HAS_THR_C_DEST)
00668   ACE_TSS_Adapter *tss_adapter = 0;
00669   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00670   ACE_Thread::getspecific (this->key_, &temp);
00671   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00672   guard = static_cast <ACE_Read_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00673 #else
00674   void *temp = guard; // Need this temp to keep G++ from complaining.
00675   ACE_Thread::getspecific (this->key_, &temp);
00676   guard = static_cast <ACE_Read_Guard<ACE_LOCK> *> (temp);
00677 #endif /* ACE_HAS_THR_C_DEST */
00678 
00679   return guard->acquire_read ();
00680 }
00681 
00682 template <class ACE_LOCK> int
00683 ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire (void)
00684 {
00685 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire");
00686 
00687   ACE_Read_Guard<ACE_LOCK> *guard = 0;
00688 
00689 #if defined (ACE_HAS_THR_C_DEST)
00690   ACE_TSS_Adapter *tss_adapter = 0;
00691   void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
00692   ACE_Thread::getspecific (this->key_, &temp);
00693   tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
00694   guard = static_cast <ACE_Read_Guard<ACE_LOCK> *> (tss_adapter->ts_obj_);
00695 #else
00696   void *temp = guard; // Need this temp to keep G++ from complaining.
00697   ACE_Thread::getspecific (this->key_, &temp);
00698   guard = static_cast <ACE_Read_Guard<ACE_LOCK> *> (temp);
00699 #endif /* ACE_HAS_THR_C_DEST */
00700 
00701   return guard->tryacquire_read ();
00702 }
00703 
00704 template <class ACE_LOCK> int
00705 ACE_TSS_Read_Guard<ACE_LOCK>::acquire_read (void)
00706 {
00707 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::acquire_read");
00708 
00709   return this->acquire ();
00710 }
00711 
00712 template <class ACE_LOCK> int
00713 ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire_read (void)
00714 {
00715 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire_read");
00716 
00717   return this->tryacquire ();
00718 }
00719 
00720 template <class ACE_LOCK> void
00721 ACE_TSS_Read_Guard<ACE_LOCK>::dump (void) const
00722 {
00723 #if defined (ACE_HAS_DUMP)
00724 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::dump");
00725   ACE_TSS_Guard<ACE_LOCK>::dump ();
00726 #endif /* ACE_HAS_DUMP */
00727 }
00728 
00729 #endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */
00730 
00731 ACE_END_VERSIONED_NAMESPACE_DECL
00732 
00733 #endif /* ACE_TSS_T_CPP */

Generated on Thu Nov 9 09:42:08 2006 for ACE by doxygen 1.3.6