PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/dep/acelite/ace/TSS_T.cpp

https://github.com/chucho/FaceCore
C++ | 662 lines | 522 code | 94 blank | 46 comment | 47 complexity | ccee80f050702a4516b26bd4784c9c1d MD5 | raw file
  1. // $Id: TSS_T.cpp 91693 2010-09-09 12:57:54Z johnnyw $
  2. #ifndef ACE_TSS_T_CPP
  3. #define ACE_TSS_T_CPP
  4. #include "ace/TSS_T.h"
  5. #if !defined (ACE_LACKS_PRAGMA_ONCE)
  6. # pragma once
  7. #endif /* ACE_LACKS_PRAGMA_ONCE */
  8. #if !defined (__ACE_INLINE__)
  9. #include "ace/TSS_T.inl"
  10. #endif /* __ACE_INLINE__ */
  11. #include "ace/Thread.h"
  12. #include "ace/Log_Msg.h"
  13. #include "ace/Guard_T.h"
  14. #include "ace/OS_NS_stdio.h"
  15. #if defined (ACE_HAS_THR_C_DEST)
  16. # include "ace/TSS_Adapter.h"
  17. #endif /* ACE_HAS_THR_C_DEST */
  18. ACE_BEGIN_VERSIONED_NAMESPACE_DECL
  19. ACE_ALLOC_HOOK_DEFINE(ACE_TSS)
  20. #if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
  21. # if defined (ACE_HAS_THR_C_DEST)
  22. extern "C" void ACE_TSS_C_cleanup (void *);
  23. # endif /* ACE_HAS_THR_C_DEST */
  24. #endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */
  25. template <class TYPE>
  26. ACE_TSS<TYPE>::~ACE_TSS (void)
  27. {
  28. #if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
  29. if (this->once_)
  30. {
  31. # if defined (ACE_HAS_THR_C_DEST)
  32. ACE_TSS_Adapter *tss_adapter = this->ts_value ();
  33. this->ts_value (0);
  34. ACE_TSS_C_cleanup (tss_adapter);
  35. # else
  36. TYPE *ts_obj = this->ts_value ();
  37. this->ts_value (0);
  38. ACE_TSS<TYPE>::cleanup (ts_obj);
  39. # endif /* ACE_HAS_THR_C_DEST */
  40. ACE_OS::thr_key_detach (this->key_);
  41. ACE_OS::thr_keyfree (this->key_);
  42. }
  43. #else // defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
  44. // We own it, we need to delete it.
  45. delete type_;
  46. #endif // defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
  47. }
  48. template <class TYPE> TYPE *
  49. ACE_TSS<TYPE>::operator-> () const
  50. {
  51. return this->ts_get ();
  52. }
  53. template <class TYPE>
  54. ACE_TSS<TYPE>::operator TYPE *(void) const
  55. {
  56. return this->ts_get ();
  57. }
  58. template <class TYPE> TYPE *
  59. ACE_TSS<TYPE>::make_TSS_TYPE (void) const
  60. {
  61. TYPE *temp = 0;
  62. ACE_NEW_RETURN (temp,
  63. TYPE,
  64. 0);
  65. return temp;
  66. }
  67. template <class TYPE> void
  68. ACE_TSS<TYPE>::dump (void) const
  69. {
  70. #if defined (ACE_HAS_DUMP)
  71. #if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
  72. ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
  73. this->keylock_.dump ();
  74. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("key_ = %d\n"), this->key_));
  75. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nonce_ = %d\n"), this->once_));
  76. ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
  77. #endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */
  78. #endif /* ACE_HAS_DUMP */
  79. }
  80. #if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
  81. template <class TYPE> void
  82. ACE_TSS<TYPE>::cleanup (void *ptr)
  83. {
  84. // Cast this to the concrete TYPE * so the destructor gets called.
  85. delete (TYPE *) ptr;
  86. }
  87. template <class TYPE> int
  88. ACE_TSS<TYPE>::ts_init (void)
  89. {
  90. // Ensure that we are serialized!
  91. ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->keylock_, 0);
  92. // Use the Double-Check pattern to make sure we only create the key
  93. // once!
  94. if (!this->once_)
  95. {
  96. if (ACE_Thread::keycreate (&this->key_,
  97. #if defined (ACE_HAS_THR_C_DEST)
  98. &ACE_TSS_C_cleanup
  99. #else
  100. &ACE_TSS<TYPE>::cleanup
  101. #endif /* ACE_HAS_THR_C_DEST */
  102. ) != 0)
  103. return -1; // Major problems, this should *never* happen!
  104. else
  105. {
  106. // This *must* come last to avoid race conditions!
  107. this->once_ = true;
  108. return 0;
  109. }
  110. }
  111. return 0;
  112. }
  113. template <class TYPE>
  114. ACE_TSS<TYPE>::ACE_TSS (TYPE *ts_obj)
  115. : once_ (false),
  116. key_ (ACE_OS::NULL_key)
  117. {
  118. // If caller has passed us a non-NULL TYPE *, then we'll just use
  119. // this to initialize the thread-specific value. Thus, subsequent
  120. // calls to operator->() will return this value. This is useful
  121. // since it enables us to assign objects to thread-specific data
  122. // that have arbitrarily complex constructors!
  123. if (ts_obj != 0)
  124. {
  125. if (this->ts_init () == -1)
  126. {
  127. // Save/restore errno.
  128. ACE_Errno_Guard error (errno);
  129. // What should we do if this call fails?!
  130. #if defined (ACE_HAS_WINCE)
  131. ::MessageBox (0,
  132. ACE_TEXT ("ACE_Thread::keycreate() failed!"),
  133. ACE_TEXT ("ACE_TSS::ACE_TSS"),
  134. MB_OK);
  135. #else
  136. ACE_OS::fprintf (stderr,
  137. "ACE_Thread::keycreate() failed!");
  138. #endif /* ACE_HAS_WINCE */
  139. return;
  140. }
  141. #if defined (ACE_HAS_THR_C_DEST)
  142. // Encapsulate a ts_obj and it's destructor in an
  143. // ACE_TSS_Adapter.
  144. ACE_TSS_Adapter *tss_adapter = 0;
  145. ACE_NEW (tss_adapter,
  146. ACE_TSS_Adapter ((void *) ts_obj,
  147. ACE_TSS<TYPE>::cleanup));
  148. // Put the adapter in thread specific storage
  149. if (this->ts_value (tss_adapter) == -1)
  150. {
  151. delete tss_adapter;
  152. }
  153. #else
  154. this->ts_value (ts_obj);
  155. #endif /* ACE_HAS_THR_C_DEST */
  156. }
  157. }
  158. template <class TYPE> TYPE *
  159. ACE_TSS<TYPE>::ts_get (void) const
  160. {
  161. if (!this->once_)
  162. {
  163. // Create and initialize thread-specific ts_obj.
  164. if (const_cast< ACE_TSS < TYPE > * >(this)->ts_init () == -1)
  165. // Seriously wrong..
  166. return 0;
  167. }
  168. TYPE *ts_obj = 0;
  169. #if defined (ACE_HAS_THR_C_DEST)
  170. ACE_TSS_Adapter *tss_adapter = this->ts_value ();
  171. ACE_TSS_Adapter *fake_tss_adapter = 0;
  172. // If tss_adapter is not 0 but its ts_obj_ is 0 then we still need to create
  173. // a proper ts_obj. That's the intent of this member function.
  174. if (tss_adapter != 0 && tss_adapter->ts_obj_ == 0)
  175. {
  176. fake_tss_adapter = tss_adapter;
  177. tss_adapter = 0;
  178. }
  179. // Check to see if this is the first time in for this thread.
  180. if (tss_adapter == 0)
  181. #else
  182. ts_obj = this->ts_value ();
  183. // Check to see if this is the first time in for this thread.
  184. if (ts_obj == 0)
  185. #endif /* ACE_HAS_THR_C_DEST */
  186. {
  187. // Allocate memory off the heap and store it in a pointer in
  188. // thread-specific storage (on the stack...).
  189. ts_obj = this->make_TSS_TYPE ();
  190. if (ts_obj == 0)
  191. return 0;
  192. #if defined (ACE_HAS_THR_C_DEST)
  193. // Encapsulate a ts_obj and it's destructor in an
  194. // ACE_TSS_Adapter.
  195. ACE_NEW_RETURN (tss_adapter,
  196. ACE_TSS_Adapter (ts_obj,
  197. ACE_TSS<TYPE>::cleanup), 0);
  198. // Put the adapter in thread specific storage
  199. if (this->ts_value (tss_adapter) == -1)
  200. {
  201. delete tss_adapter;
  202. delete ts_obj;
  203. return 0; // Major problems, this should *never* happen!
  204. }
  205. #else
  206. // Store the dynamically allocated pointer in thread-specific
  207. // storage.
  208. if (this->ts_value (ts_obj) == -1)
  209. {
  210. delete ts_obj;
  211. return 0; // Major problems, this should *never* happen!
  212. }
  213. #endif /* ACE_HAS_THR_C_DEST */
  214. }
  215. #if defined (ACE_HAS_THR_C_DEST)
  216. // Delete the adapter that didn't actually have a real ts_obj.
  217. delete fake_tss_adapter;
  218. // Return the underlying ts object.
  219. return static_cast <TYPE *> (tss_adapter->ts_obj_);
  220. #else
  221. return ts_obj;
  222. #endif /* ACE_HAS_THR_C_DEST */
  223. }
  224. // Get the thread-specific object for the key associated with this
  225. // object. Returns 0 if the ts_obj has never been initialized,
  226. // otherwise returns a pointer to the ts_obj.
  227. template <class TYPE> TYPE *
  228. ACE_TSS<TYPE>::ts_object (void) const
  229. {
  230. if (!this->once_) // Return 0 if we've never been initialized.
  231. return 0;
  232. TYPE *ts_obj = 0;
  233. #if defined (ACE_HAS_THR_C_DEST)
  234. ACE_TSS_Adapter *tss_adapter = this->ts_value ();
  235. if (tss_adapter != 0)
  236. {
  237. // Extract the real TS object.
  238. ts_obj = static_cast <TYPE *> (tss_adapter->ts_obj_);
  239. }
  240. #else
  241. ts_obj = this->ts_value ();
  242. #endif /* ACE_HAS_THR_C_DEST */
  243. return ts_obj;
  244. }
  245. template <class TYPE> TYPE *
  246. ACE_TSS<TYPE>::ts_object (TYPE *new_ts_obj)
  247. {
  248. // Note, we shouldn't hold the keylock at this point because
  249. // <ts_init> does it for us and we'll end up with deadlock
  250. // otherwise...
  251. if (!this->once_)
  252. {
  253. // Create and initialize thread-specific ts_obj.
  254. if (this->ts_init () == -1)
  255. return 0;
  256. }
  257. TYPE *ts_obj = 0;
  258. #if defined (ACE_HAS_THR_C_DEST)
  259. ACE_TSS_Adapter *tss_adapter = this->ts_value ();
  260. if (tss_adapter != 0)
  261. {
  262. ts_obj = static_cast <TYPE *> (tss_adapter->ts_obj_);
  263. // Don't delete tss_adapter yet. It can be double-deleted
  264. // in case setspecific below fails.
  265. }
  266. ACE_TSS_Adapter *new_tss_adapter = 0;
  267. ACE_NEW_RETURN (new_tss_adapter,
  268. ACE_TSS_Adapter ((void *) new_ts_obj,
  269. ACE_TSS<TYPE>::cleanup),
  270. 0);
  271. if (this->ts_value (new_tss_adapter) == -1)
  272. {
  273. delete new_tss_adapter;
  274. }
  275. else
  276. {
  277. // Now it's fine to delete the old tss_adapter.
  278. delete tss_adapter;
  279. }
  280. #else
  281. ts_obj = this->ts_value ();
  282. this->ts_value (new_ts_obj);
  283. #endif /* ACE_HAS_THR_C_DEST */
  284. return ts_obj;
  285. }
  286. ACE_ALLOC_HOOK_DEFINE(ACE_TSS_Guard)
  287. template <class ACE_LOCK> void
  288. ACE_TSS_Guard<ACE_LOCK>::dump (void) const
  289. {
  290. #if defined (ACE_HAS_DUMP)
  291. ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
  292. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("key_ = %d\n"), this->key_));
  293. ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
  294. #endif /* ACE_HAS_DUMP */
  295. }
  296. template <class ACE_LOCK> void
  297. ACE_TSS_Guard<ACE_LOCK>::init_key (void)
  298. {
  299. this->key_ = ACE_OS::NULL_key;
  300. ACE_Thread::keycreate (&this->key_,
  301. #if defined (ACE_HAS_THR_C_DEST)
  302. &ACE_TSS_C_cleanup,
  303. #else
  304. &ACE_TSS_Guard<ACE_LOCK>::cleanup,
  305. #endif /* ACE_HAS_THR_C_DEST */
  306. (void *) this);
  307. }
  308. template <class ACE_LOCK>
  309. ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard (void)
  310. {
  311. this->init_key ();
  312. }
  313. template <class ACE_LOCK> int
  314. ACE_TSS_Guard<ACE_LOCK>::release (void)
  315. {
  316. Guard_Type *guard = 0;
  317. #if defined (ACE_HAS_THR_C_DEST)
  318. ACE_TSS_Adapter *tss_adapter = 0;
  319. void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
  320. ACE_Thread::getspecific (this->key_, &temp);
  321. tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
  322. guard = static_cast <Guard_Type *> (tss_adapter->ts_obj_);
  323. #else
  324. void *temp = guard; // Need this temp to keep G++ from complaining.
  325. ACE_Thread::getspecific (this->key_, &temp);
  326. guard = static_cast <Guard_Type *> (temp);
  327. #endif /* ACE_HAS_THR_C_DEST */
  328. return guard->release ();
  329. }
  330. template <class ACE_LOCK> int
  331. ACE_TSS_Guard<ACE_LOCK>::remove (void)
  332. {
  333. Guard_Type *guard = 0;
  334. #if defined (ACE_HAS_THR_C_DEST)
  335. ACE_TSS_Adapter *tss_adapter = 0;
  336. void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
  337. ACE_Thread::getspecific (this->key_, &temp);
  338. tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
  339. guard = static_cast <Guard_Type *> (tss_adapter->ts_obj_);
  340. #else
  341. void *temp = guard; // Need this temp to keep G++ from complaining.
  342. ACE_Thread::getspecific (this->key_, &temp);
  343. guard = static_cast <Guard_Type *> (temp);
  344. #endif /* ACE_HAS_THR_C_DEST */
  345. return guard->remove ();
  346. }
  347. template <class ACE_LOCK>
  348. ACE_TSS_Guard<ACE_LOCK>::~ACE_TSS_Guard (void)
  349. {
  350. Guard_Type *guard = 0;
  351. #if defined (ACE_HAS_THR_C_DEST)
  352. ACE_TSS_Adapter *tss_adapter = 0;
  353. void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
  354. ACE_Thread::getspecific (this->key_, &temp);
  355. tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
  356. guard = static_cast <Guard_Type *> (tss_adapter->ts_obj_);
  357. #else
  358. void *temp = guard; // Need this temp to keep G++ from complaining.
  359. ACE_Thread::getspecific (this->key_, &temp);
  360. guard = static_cast <Guard_Type *> (temp);
  361. #endif /* ACE_HAS_THR_C_DEST */
  362. // Make sure that this pointer is NULL when we shut down...
  363. ACE_Thread::setspecific (this->key_, 0);
  364. ACE_Thread::keyfree (this->key_);
  365. // Destructor releases lock.
  366. delete guard;
  367. }
  368. template <class ACE_LOCK> void
  369. ACE_TSS_Guard<ACE_LOCK>::cleanup (void *ptr)
  370. {
  371. // Destructor releases lock.
  372. delete (Guard_Type *) ptr;
  373. }
  374. template <class ACE_LOCK>
  375. ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard (ACE_LOCK &lock, bool block)
  376. {
  377. this->init_key ();
  378. Guard_Type *guard = 0;
  379. ACE_NEW (guard,
  380. Guard_Type (lock, block));
  381. #if defined (ACE_HAS_THR_C_DEST)
  382. ACE_TSS_Adapter *tss_adapter = 0;
  383. ACE_NEW (tss_adapter,
  384. ACE_TSS_Adapter ((void *) guard,
  385. ACE_TSS_Guard<ACE_LOCK>::cleanup));
  386. ACE_Thread::setspecific (this->key_,
  387. (void *) tss_adapter);
  388. #else
  389. ACE_Thread::setspecific (this->key_,
  390. (void *) guard);
  391. #endif /* ACE_HAS_THR_C_DEST */
  392. }
  393. template <class ACE_LOCK> int
  394. ACE_TSS_Guard<ACE_LOCK>::acquire (void)
  395. {
  396. Guard_Type *guard = 0;
  397. #if defined (ACE_HAS_THR_C_DEST)
  398. ACE_TSS_Adapter *tss_adapter = 0;
  399. void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
  400. ACE_Thread::getspecific (this->key_, &temp);
  401. tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
  402. guard = static_cast <Guard_Type *> (tss_adapter->ts_obj_);
  403. #else
  404. void *temp = guard; // Need this temp to keep G++ from complaining.
  405. ACE_Thread::getspecific (this->key_, &temp);
  406. guard = static_cast <Guard_Type *> (temp);
  407. #endif /* ACE_HAS_THR_C_DEST */
  408. return guard->acquire ();
  409. }
  410. template <class ACE_LOCK> int
  411. ACE_TSS_Guard<ACE_LOCK>::tryacquire (void)
  412. {
  413. Guard_Type *guard = 0;
  414. #if defined (ACE_HAS_THR_C_DEST)
  415. ACE_TSS_Adapter *tss_adapter = 0;
  416. void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
  417. ACE_Thread::getspecific (this->key_, &temp);
  418. tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
  419. guard = static_cast <Guard_Type *> (tss_adapter->ts_obj_);
  420. #else
  421. void *temp = guard; // Need this temp to keep G++ from complaining.
  422. ACE_Thread::getspecific (this->key_, &temp);
  423. guard = static_cast <Guard_Type *> (temp);
  424. #endif /* ACE_HAS_THR_C_DEST */
  425. return guard->tryacquire ();
  426. }
  427. template <class ACE_LOCK>
  428. ACE_TSS_Write_Guard<ACE_LOCK>::ACE_TSS_Write_Guard (ACE_LOCK &lock,
  429. bool block)
  430. {
  431. this->init_key ();
  432. Guard_Type *guard = 0;
  433. ACE_NEW (guard,
  434. Write_Guard_Type (lock, block));
  435. #if defined (ACE_HAS_THR_C_DEST)
  436. ACE_TSS_Adapter *tss_adapter = 0;
  437. ACE_NEW (tss_adapter,
  438. ACE_TSS_Adapter ((void *) guard,
  439. ACE_TSS_Guard<ACE_LOCK>::cleanup));
  440. ACE_Thread::setspecific (this->key_, (void *) tss_adapter);
  441. #else
  442. ACE_Thread::setspecific (this->key_, (void *) guard);
  443. #endif /* ACE_HAS_THR_C_DEST */
  444. }
  445. template <class ACE_LOCK> int
  446. ACE_TSS_Write_Guard<ACE_LOCK>::acquire (void)
  447. {
  448. Write_Guard_Type *guard = 0;
  449. #if defined (ACE_HAS_THR_C_DEST)
  450. ACE_TSS_Adapter *tss_adapter = 0;
  451. void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
  452. ACE_Thread::getspecific (this->key_, &temp);
  453. tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
  454. guard = static_cast <Write_Guard_Type *> (tss_adapter->ts_obj_);
  455. #else
  456. void *temp = guard; // Need this temp to keep G++ from complaining.
  457. ACE_Thread::getspecific (this->key_, &temp);
  458. guard = static_cast <Write_Guard_Type *> (temp);
  459. #endif /* ACE_HAS_THR_C_DEST */
  460. return guard->acquire_write ();
  461. }
  462. template <class ACE_LOCK> int
  463. ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire (void)
  464. {
  465. Write_Guard_Type *guard = 0;
  466. #if defined (ACE_HAS_THR_C_DEST)
  467. ACE_TSS_Adapter *tss_adapter = 0;
  468. void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
  469. ACE_Thread::getspecific (this->key_, &temp);
  470. tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
  471. guard = static_cast <Write_Guard_Type *> (tss_adapter->ts_obj_);
  472. #else
  473. void *temp = guard; // Need this temp to keep G++ from complaining.
  474. ACE_Thread::getspecific (this->key_, &temp);
  475. guard = static_cast <Write_Guard_Type *> (temp);
  476. #endif /* ACE_HAS_THR_C_DEST */
  477. return guard->tryacquire_write ();
  478. }
  479. template <class ACE_LOCK> int
  480. ACE_TSS_Write_Guard<ACE_LOCK>::acquire_write (void)
  481. {
  482. return this->acquire ();
  483. }
  484. template <class ACE_LOCK> int
  485. ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire_write (void)
  486. {
  487. return this->tryacquire ();
  488. }
  489. template <class ACE_LOCK> void
  490. ACE_TSS_Write_Guard<ACE_LOCK>::dump (void) const
  491. {
  492. #if defined (ACE_HAS_DUMP)
  493. ACE_TSS_Guard<ACE_LOCK>::dump ();
  494. #endif /* ACE_HAS_DUMP */
  495. }
  496. template <class ACE_LOCK>
  497. ACE_TSS_Read_Guard<ACE_LOCK>::ACE_TSS_Read_Guard (ACE_LOCK &lock, bool block)
  498. {
  499. this->init_key ();
  500. Guard_Type *guard = 0;
  501. ACE_NEW (guard,
  502. Read_Guard_Type (lock, block));
  503. #if defined (ACE_HAS_THR_C_DEST)
  504. ACE_TSS_Adapter *tss_adapter;
  505. ACE_NEW (tss_adapter,
  506. ACE_TSS_Adapter ((void *)guard,
  507. ACE_TSS_Guard<ACE_LOCK>::cleanup));
  508. ACE_Thread::setspecific (this->key_,
  509. (void *) tss_adapter);
  510. #else
  511. ACE_Thread::setspecific (this->key_,
  512. (void *) guard);
  513. #endif /* ACE_HAS_THR_C_DEST */
  514. }
  515. template <class ACE_LOCK> int
  516. ACE_TSS_Read_Guard<ACE_LOCK>::acquire (void)
  517. {
  518. Read_Guard_Type *guard = 0;
  519. #if defined (ACE_HAS_THR_C_DEST)
  520. ACE_TSS_Adapter *tss_adapter = 0;
  521. void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
  522. ACE_Thread::getspecific (this->key_, &temp);
  523. tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
  524. guard = static_cast <Read_Guard_Type *> (tss_adapter->ts_obj_);
  525. #else
  526. void *temp = guard; // Need this temp to keep G++ from complaining.
  527. ACE_Thread::getspecific (this->key_, &temp);
  528. guard = static_cast <Read_Guard_Type *> (temp);
  529. #endif /* ACE_HAS_THR_C_DEST */
  530. return guard->acquire_read ();
  531. }
  532. template <class ACE_LOCK> int
  533. ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire (void)
  534. {
  535. Read_Guard_Type *guard = 0;
  536. #if defined (ACE_HAS_THR_C_DEST)
  537. ACE_TSS_Adapter *tss_adapter = 0;
  538. void *temp = tss_adapter; // Need this temp to keep G++ from complaining.
  539. ACE_Thread::getspecific (this->key_, &temp);
  540. tss_adapter = static_cast <ACE_TSS_Adapter *> (temp);
  541. guard = static_cast <Read_Guard_Type *> (tss_adapter->ts_obj_);
  542. #else
  543. void *temp = guard; // Need this temp to keep G++ from complaining.
  544. ACE_Thread::getspecific (this->key_, &temp);
  545. guard = static_cast <Read_Guard_Type *> (temp);
  546. #endif /* ACE_HAS_THR_C_DEST */
  547. return guard->tryacquire_read ();
  548. }
  549. template <class ACE_LOCK> int
  550. ACE_TSS_Read_Guard<ACE_LOCK>::acquire_read (void)
  551. {
  552. return this->acquire ();
  553. }
  554. template <class ACE_LOCK> int
  555. ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire_read (void)
  556. {
  557. return this->tryacquire ();
  558. }
  559. template <class ACE_LOCK> void
  560. ACE_TSS_Read_Guard<ACE_LOCK>::dump (void) const
  561. {
  562. #if defined (ACE_HAS_DUMP)
  563. ACE_TSS_Guard<ACE_LOCK>::dump ();
  564. #endif /* ACE_HAS_DUMP */
  565. }
  566. #endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */
  567. ACE_END_VERSIONED_NAMESPACE_DECL
  568. #endif /* ACE_TSS_T_CPP */