1 // $Id: TSS_T.cpp 82508 2008-08-05 13:52:48Z johnnyw $
8 #if !defined (ACE_LACKS_PRAGMA_ONCE)
10 #endif /* ACE_LACKS_PRAGMA_ONCE */
12 #if !defined (__ACE_INLINE__)
13 #include "ace/TSS_T.inl"
14 #endif /* __ACE_INLINE__ */
16 #include "ace/Thread.h"
17 #include "ace/Log_Msg.h"
18 #include "ace/Guard_T.h"
19 #include "ace/OS_NS_stdio.h"
21 #if defined (ACE_HAS_THR_C_DEST)
22 # include "ace/TSS_Adapter.h"
23 #endif /* ACE_HAS_THR_C_DEST */
25 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
27 ACE_ALLOC_HOOK_DEFINE(ACE_TSS
)
30 ACE_TSS
<TYPE
>::~ACE_TSS (void)
32 #if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
35 ACE_OS::thr_key_detach (this->key_
, this);
36 ACE_OS::thr_keyfree (this->key_
);
38 #else // defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
39 // We own it, we need to delete it.
41 #endif // defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
44 template <class TYPE
> TYPE
*
45 ACE_TSS
<TYPE
>::operator-> () const
47 return this->ts_get ();
51 ACE_TSS
<TYPE
>::operator TYPE
*(void) const
53 return this->ts_get ();
56 template <class TYPE
> TYPE
*
57 ACE_TSS
<TYPE
>::make_TSS_TYPE (void) const
66 template <class TYPE
> void
67 ACE_TSS
<TYPE
>::dump (void) const
69 #if defined (ACE_HAS_DUMP)
70 // ACE_TRACE ("ACE_TSS<TYPE>::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"), this->once_
));
76 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\n")));
77 ACE_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
78 #endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */
79 #endif /* ACE_HAS_DUMP */
82 #if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
83 #if defined (ACE_HAS_THR_C_DEST)
84 extern "C" void ACE_TSS_C_cleanup (void *); // defined in Synch.cpp
85 #endif /* ACE_HAS_THR_C_DEST */
87 template <class TYPE
> void
88 ACE_TSS
<TYPE
>::cleanup (void *ptr
)
90 // Cast this to the concrete TYPE * so the destructor gets called.
94 template <class TYPE
> int
95 ACE_TSS
<TYPE
>::ts_init (void)
97 // Ensure that we are serialized!
98 ACE_GUARD_RETURN (ACE_Thread_Mutex
, ace_mon
, this->keylock_
, 0);
100 // Use the Double-Check pattern to make sure we only create the key
104 if (ACE_Thread::keycreate (&this->key_
,
105 #if defined (ACE_HAS_THR_C_DEST)
108 &ACE_TSS
<TYPE
>::cleanup
,
109 #endif /* ACE_HAS_THR_C_DEST */
111 return -1; // Major problems, this should *never* happen!
114 // This *must* come last to avoid race conditions!
123 template <class TYPE
>
124 ACE_TSS
<TYPE
>::ACE_TSS (TYPE
*ts_obj
)
126 key_ (ACE_OS::NULL_key
)
128 // If caller has passed us a non-NULL TYPE *, then we'll just use
129 // this to initialize the thread-specific value. Thus, subsequent
130 // calls to operator->() will return this value. This is useful
131 // since it enables us to assign objects to thread-specific data
132 // that have arbitrarily complex constructors!
136 if (this->ts_init () == -1)
138 // Save/restore errno.
139 ACE_Errno_Guard
error (errno
);
140 // What should we do if this call fails?!
141 #if defined (ACE_HAS_WINCE)
143 ACE_TEXT ("ACE_Thread::keycreate() failed!"),
144 ACE_TEXT ("ACE_TSS::ACE_TSS"),
147 ACE_OS::fprintf (stderr
,
148 "ACE_Thread::keycreate() failed!");
149 #endif /* ACE_HAS_WINCE */
153 #if defined (ACE_HAS_THR_C_DEST)
154 // Encapsulate a ts_obj and it's destructor in an
156 ACE_TSS_Adapter
*tss_adapter
= 0;
157 ACE_NEW (tss_adapter
,
158 ACE_TSS_Adapter ((void *) ts_obj
,
159 ACE_TSS
<TYPE
>::cleanup
));
161 // Put the adapter in thread specific storage
162 if (ACE_Thread::setspecific (this->key_
,
163 (void *) tss_adapter
) != 0)
166 ACE_ERROR ((LM_ERROR
,
168 ACE_TEXT ("ACE_Thread::setspecific() failed!")));
171 if (ACE_Thread::setspecific (this->key_
,
172 (void *) ts_obj
) != 0)
173 ACE_ERROR ((LM_ERROR
,
175 ACE_TEXT ("ACE_Thread::setspecific() failed!")));
176 #endif /* ACE_HAS_THR_C_DEST */
180 template <class TYPE
> TYPE
*
181 ACE_TSS
<TYPE
>::ts_get (void) const
185 // Create and initialize thread-specific ts_obj.
186 if (const_cast< ACE_TSS
< TYPE
> * >(this)->ts_init () == -1)
193 #if defined (ACE_HAS_THR_C_DEST)
194 ACE_TSS_Adapter
*tss_adapter
= 0;
196 // Get the adapter from thread-specific storage
197 void *temp
= tss_adapter
; // Need this temp to keep G++ from complaining.
198 if (ACE_Thread::getspecific (this->key_
, &temp
) == -1)
199 return 0; // This should not happen!
200 tss_adapter
= static_cast <ACE_TSS_Adapter
*> (temp
);
202 // Check to see if this is the first time in for this thread.
203 if (tss_adapter
== 0)
205 // Get the ts_obj from thread-specific storage. Note that no locks
206 // are required here...
207 void *temp
= ts_obj
; // Need this temp to keep G++ from complaining.
208 if (ACE_Thread::getspecific (this->key_
, &temp
) == -1)
209 return 0; // This should not happen!
210 ts_obj
= static_cast <TYPE
*> (temp
);
212 // Check to see if this is the first time in for this thread.
214 #endif /* ACE_HAS_THR_C_DEST */
216 // Allocate memory off the heap and store it in a pointer in
217 // thread-specific storage (on the stack...).
219 ts_obj
= this->make_TSS_TYPE ();
224 #if defined (ACE_HAS_THR_C_DEST)
225 // Encapsulate a ts_obj and it's destructor in an
227 ACE_NEW_RETURN (tss_adapter
,
228 ACE_TSS_Adapter (ts_obj
,
229 ACE_TSS
<TYPE
>::cleanup
), 0);
231 // Put the adapter in thread specific storage
232 if (ACE_Thread::setspecific (this->key_
,
233 (void *) tss_adapter
) != 0)
237 return 0; // Major problems, this should *never* happen!
240 // Store the dynamically allocated pointer in thread-specific
242 if (ACE_Thread::setspecific (this->key_
,
243 (void *) ts_obj
) != 0)
246 return 0; // Major problems, this should *never* happen!
248 #endif /* ACE_HAS_THR_C_DEST */
251 #if defined (ACE_HAS_THR_C_DEST)
252 // Return the underlying ts object.
253 return static_cast <TYPE
*> (tss_adapter
->ts_obj_
);
256 #endif /* ACE_HAS_THR_C_DEST */
259 // Get the thread-specific object for the key associated with this
260 // object. Returns 0 if the ts_obj has never been initialized,
261 // otherwise returns a pointer to the ts_obj.
263 template <class TYPE
> TYPE
*
264 ACE_TSS
<TYPE
>::ts_object (void) const
266 if (!this->once_
) // Return 0 if we've never been initialized.
271 #if defined (ACE_HAS_THR_C_DEST)
272 ACE_TSS_Adapter
*tss_adapter
= 0;
274 // Get the tss adapter from thread-specific storage
275 void *temp
= tss_adapter
; // Need this temp to keep G++ from complaining.
276 if (ACE_Thread::getspecific (this->key_
, &temp
) == -1)
278 return 0; // This should not happen!
282 tss_adapter
= static_cast <ACE_TSS_Adapter
*> (temp
);
284 if (tss_adapter
!= 0)
285 // Extract the real TS object.
286 ts_obj
= static_cast <TYPE
*> (tss_adapter
->ts_obj_
);
290 void *temp
= ts_obj
; // Need this temp to keep G++ from complaining.
291 if (ACE_Thread::getspecific (this->key_
, &temp
) == -1)
292 return 0; // This should not happen!
293 ts_obj
= static_cast <TYPE
*> (temp
);
294 #endif /* ACE_HAS_THR_C_DEST */
299 template <class TYPE
> TYPE
*
300 ACE_TSS
<TYPE
>::ts_object (TYPE
*new_ts_obj
)
302 // Note, we shouldn't hold the keylock at this point because
303 // <ts_init> does it for us and we'll end up with deadlock
307 // Create and initialize thread-specific ts_obj.
308 if (this->ts_init () == -1)
314 #if defined (ACE_HAS_THR_C_DEST)
315 ACE_TSS_Adapter
*tss_adapter
= 0;
317 void *temp
= tss_adapter
; // Need this temp to keep G++ from complaining.
318 if (ACE_Thread::getspecific (this->key_
, &temp
) == -1)
319 return 0; // This should not happen!
320 tss_adapter
= static_cast <ACE_TSS_Adapter
*> (temp
);
322 if (tss_adapter
!= 0)
324 ts_obj
= static_cast <TYPE
*> (tss_adapter
->ts_obj_
);
325 delete tss_adapter
; // don't need this anymore
328 ACE_NEW_RETURN (tss_adapter
,
329 ACE_TSS_Adapter ((void *) new_ts_obj
,
330 ACE_TSS
<TYPE
>::cleanup
),
333 if (ACE_Thread::setspecific (this->key_
,
334 (void *) tss_adapter
) == -1)
337 return ts_obj
; // This should not happen!
340 void *temp
= ts_obj
; // Need this temp to keep G++ from complaining.
341 if (ACE_Thread::getspecific (this->key_
, &temp
) == -1)
342 return 0; // This should not happen!
343 ts_obj
= static_cast <TYPE
*> (temp
);
344 if (ACE_Thread::setspecific (this->key_
, (void *) new_ts_obj
) == -1)
345 return ts_obj
; // This should not happen!
346 #endif /* ACE_HAS_THR_C_DEST */
351 ACE_ALLOC_HOOK_DEFINE(ACE_TSS_Guard
)
353 template <class ACE_LOCK
> void
354 ACE_TSS_Guard
<ACE_LOCK
>::dump (void) const
356 #if defined (ACE_HAS_DUMP)
357 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::dump");
359 ACE_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
360 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("key_ = %d"), this->key_
));
361 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\n")));
362 ACE_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
363 #endif /* ACE_HAS_DUMP */
366 template <class ACE_LOCK
> void
367 ACE_TSS_Guard
<ACE_LOCK
>::init_key (void)
369 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::init_key");
371 this->key_
= ACE_OS::NULL_key
;
372 ACE_Thread::keycreate (&this->key_
,
373 #if defined (ACE_HAS_THR_C_DEST)
376 &ACE_TSS_Guard
<ACE_LOCK
>::cleanup
,
377 #endif /* ACE_HAS_THR_C_DEST */
381 template <class ACE_LOCK
>
382 ACE_TSS_Guard
<ACE_LOCK
>::ACE_TSS_Guard (void)
384 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard");
388 template <class ACE_LOCK
> int
389 ACE_TSS_Guard
<ACE_LOCK
>::release (void)
391 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::release");
393 ACE_Guard
<ACE_LOCK
> *guard
= 0;
395 #if defined (ACE_HAS_THR_C_DEST)
396 ACE_TSS_Adapter
*tss_adapter
= 0;
397 void *temp
= tss_adapter
; // Need this temp to keep G++ from complaining.
398 ACE_Thread::getspecific (this->key_
, &temp
);
399 tss_adapter
= static_cast <ACE_TSS_Adapter
*> (temp
);
400 guard
= static_cast <ACE_Guard
<ACE_LOCK
> *> (tss_adapter
->ts_obj_
);
402 void *temp
= guard
; // Need this temp to keep G++ from complaining.
403 ACE_Thread::getspecific (this->key_
, &temp
);
404 guard
= static_cast <ACE_Guard
<ACE_LOCK
> *> (temp
);
405 #endif /* ACE_HAS_THR_C_DEST */
407 return guard
->release ();
410 template <class ACE_LOCK
> int
411 ACE_TSS_Guard
<ACE_LOCK
>::remove (void)
413 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::remove");
415 ACE_Guard
<ACE_LOCK
> *guard
= 0;
417 #if defined (ACE_HAS_THR_C_DEST)
418 ACE_TSS_Adapter
*tss_adapter
= 0;
419 void *temp
= tss_adapter
; // Need this temp to keep G++ from complaining.
420 ACE_Thread::getspecific (this->key_
, &temp
);
421 tss_adapter
= static_cast <ACE_TSS_Adapter
*> (temp
);
422 guard
= static_cast <ACE_Guard
<ACE_LOCK
> *> (tss_adapter
->ts_obj_
);
424 void *temp
= guard
; // Need this temp to keep G++ from complaining.
425 ACE_Thread::getspecific (this->key_
, &temp
);
426 guard
= static_cast <ACE_Guard
<ACE_LOCK
> *> (temp
);
427 #endif /* ACE_HAS_THR_C_DEST */
429 return guard
->remove ();
432 template <class ACE_LOCK
>
433 ACE_TSS_Guard
<ACE_LOCK
>::~ACE_TSS_Guard (void)
435 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::~ACE_TSS_Guard");
437 ACE_Guard
<ACE_LOCK
> *guard
= 0;
439 #if defined (ACE_HAS_THR_C_DEST)
440 ACE_TSS_Adapter
*tss_adapter
= 0;
441 void *temp
= tss_adapter
; // Need this temp to keep G++ from complaining.
442 ACE_Thread::getspecific (this->key_
, &temp
);
443 tss_adapter
= static_cast <ACE_TSS_Adapter
*> (temp
);
444 guard
= static_cast <ACE_Guard
<ACE_LOCK
> *> (tss_adapter
->ts_obj_
);
446 void *temp
= guard
; // Need this temp to keep G++ from complaining.
447 ACE_Thread::getspecific (this->key_
, &temp
);
448 guard
= static_cast <ACE_Guard
<ACE_LOCK
> *> (temp
);
449 #endif /* ACE_HAS_THR_C_DEST */
451 // Make sure that this pointer is NULL when we shut down...
452 ACE_Thread::setspecific (this->key_
, 0);
453 ACE_Thread::keyfree (this->key_
);
454 // Destructor releases lock.
458 template <class ACE_LOCK
> void
459 ACE_TSS_Guard
<ACE_LOCK
>::cleanup (void *ptr
)
461 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::cleanup");
463 // Destructor releases lock.
464 delete (ACE_Guard
<ACE_LOCK
> *) ptr
;
467 template <class ACE_LOCK
>
468 ACE_TSS_Guard
<ACE_LOCK
>::ACE_TSS_Guard (ACE_LOCK
&lock
, bool block
)
470 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard");
473 ACE_Guard
<ACE_LOCK
> *guard
= 0;
475 ACE_Guard
<ACE_LOCK
> (lock
,
478 #if defined (ACE_HAS_THR_C_DEST)
479 ACE_TSS_Adapter
*tss_adapter
= 0;
480 ACE_NEW (tss_adapter
,
481 ACE_TSS_Adapter ((void *) guard
,
482 ACE_TSS_Guard
<ACE_LOCK
>::cleanup
));
483 ACE_Thread::setspecific (this->key_
,
484 (void *) tss_adapter
);
486 ACE_Thread::setspecific (this->key_
,
488 #endif /* ACE_HAS_THR_C_DEST */
491 template <class ACE_LOCK
> int
492 ACE_TSS_Guard
<ACE_LOCK
>::acquire (void)
494 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::acquire");
496 ACE_Guard
<ACE_LOCK
> *guard
= 0;
498 #if defined (ACE_HAS_THR_C_DEST)
499 ACE_TSS_Adapter
*tss_adapter
= 0;
500 void *temp
= tss_adapter
; // Need this temp to keep G++ from complaining.
501 ACE_Thread::getspecific (this->key_
, &temp
);
502 tss_adapter
= static_cast <ACE_TSS_Adapter
*> (temp
);
503 guard
= static_cast <ACE_Guard
<ACE_LOCK
> *> (tss_adapter
->ts_obj_
);
505 void *temp
= guard
; // Need this temp to keep G++ from complaining.
506 ACE_Thread::getspecific (this->key_
, &temp
);
507 guard
= static_cast <ACE_Guard
<ACE_LOCK
> *> (temp
);
508 #endif /* ACE_HAS_THR_C_DEST */
510 return guard
->acquire ();
513 template <class ACE_LOCK
> int
514 ACE_TSS_Guard
<ACE_LOCK
>::tryacquire (void)
516 // ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::tryacquire");
518 ACE_Guard
<ACE_LOCK
> *guard
= 0;
520 #if defined (ACE_HAS_THR_C_DEST)
521 ACE_TSS_Adapter
*tss_adapter
= 0;
522 void *temp
= tss_adapter
; // Need this temp to keep G++ from complaining.
523 ACE_Thread::getspecific (this->key_
, &temp
);
524 tss_adapter
= static_cast <ACE_TSS_Adapter
*> (temp
);
525 guard
= static_cast <ACE_Guard
<ACE_LOCK
> *> (tss_adapter
->ts_obj_
);
527 void *temp
= guard
; // Need this temp to keep G++ from complaining.
528 ACE_Thread::getspecific (this->key_
, &temp
);
529 guard
= static_cast <ACE_Guard
<ACE_LOCK
> *> (temp
);
530 #endif /* ACE_HAS_THR_C_DEST */
532 return guard
->tryacquire ();
535 template <class ACE_LOCK
>
536 ACE_TSS_Write_Guard
<ACE_LOCK
>::ACE_TSS_Write_Guard (ACE_LOCK
&lock
,
539 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::ACE_TSS_Write_Guard");
542 ACE_Guard
<ACE_LOCK
> *guard
= 0;
544 ACE_Write_Guard
<ACE_LOCK
> (lock
,
547 #if defined (ACE_HAS_THR_C_DEST)
548 ACE_TSS_Adapter
*tss_adapter
= 0;
549 ACE_NEW (tss_adapter
,
550 ACE_TSS_Adapter ((void *) guard
,
551 ACE_TSS_Guard
<ACE_LOCK
>::cleanup
));
552 ACE_Thread::setspecific (this->key_
,
553 (void *) tss_adapter
);
555 ACE_Thread::setspecific (this->key_
,
557 #endif /* ACE_HAS_THR_C_DEST */
560 template <class ACE_LOCK
> int
561 ACE_TSS_Write_Guard
<ACE_LOCK
>::acquire (void)
563 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::acquire");
565 ACE_Write_Guard
<ACE_LOCK
> *guard
= 0;
567 #if defined (ACE_HAS_THR_C_DEST)
568 ACE_TSS_Adapter
*tss_adapter
= 0;
569 void *temp
= tss_adapter
; // Need this temp to keep G++ from complaining.
570 ACE_Thread::getspecific (this->key_
, &temp
);
571 tss_adapter
= static_cast <ACE_TSS_Adapter
*> (temp
);
572 guard
= static_cast <ACE_Write_Guard
<ACE_LOCK
> *> (tss_adapter
->ts_obj_
);
574 void *temp
= guard
; // Need this temp to keep G++ from complaining.
575 ACE_Thread::getspecific (this->key_
, &temp
);
576 guard
= static_cast <ACE_Write_Guard
<ACE_LOCK
> *> (temp
);
577 #endif /* ACE_HAS_THR_C_DEST */
579 return guard
->acquire_write ();
582 template <class ACE_LOCK
> int
583 ACE_TSS_Write_Guard
<ACE_LOCK
>::tryacquire (void)
585 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire");
587 ACE_Write_Guard
<ACE_LOCK
> *guard
= 0;
589 #if defined (ACE_HAS_THR_C_DEST)
590 ACE_TSS_Adapter
*tss_adapter
= 0;
591 void *temp
= tss_adapter
; // Need this temp to keep G++ from complaining.
592 ACE_Thread::getspecific (this->key_
, &temp
);
593 tss_adapter
= static_cast <ACE_TSS_Adapter
*> (temp
);
594 guard
= static_cast <ACE_Write_Guard
<ACE_LOCK
> *> (tss_adapter
->ts_obj_
);
596 void *temp
= guard
; // Need this temp to keep G++ from complaining.
597 ACE_Thread::getspecific (this->key_
, &temp
);
598 guard
= static_cast <ACE_Write_Guard
<ACE_LOCK
> *> (temp
);
599 #endif /* ACE_HAS_THR_C_DEST */
601 return guard
->tryacquire_write ();
604 template <class ACE_LOCK
> int
605 ACE_TSS_Write_Guard
<ACE_LOCK
>::acquire_write (void)
607 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::acquire_write");
609 return this->acquire ();
612 template <class ACE_LOCK
> int
613 ACE_TSS_Write_Guard
<ACE_LOCK
>::tryacquire_write (void)
615 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire_write");
617 return this->tryacquire ();
620 template <class ACE_LOCK
> void
621 ACE_TSS_Write_Guard
<ACE_LOCK
>::dump (void) const
623 #if defined (ACE_HAS_DUMP)
624 // ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::dump");
625 ACE_TSS_Guard
<ACE_LOCK
>::dump ();
626 #endif /* ACE_HAS_DUMP */
629 template <class ACE_LOCK
>
630 ACE_TSS_Read_Guard
<ACE_LOCK
>::ACE_TSS_Read_Guard (ACE_LOCK
&lock
, bool block
)
632 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::ACE_TSS_Read_Guard");
635 ACE_Guard
<ACE_LOCK
> *guard
= 0;
637 ACE_Read_Guard
<ACE_LOCK
> (lock
,
639 #if defined (ACE_HAS_THR_C_DEST)
640 ACE_TSS_Adapter
*tss_adapter
;
641 ACE_NEW (tss_adapter
,
642 ACE_TSS_Adapter ((void *)guard
,
643 ACE_TSS_Guard
<ACE_LOCK
>::cleanup
));
644 ACE_Thread::setspecific (this->key_
,
645 (void *) tss_adapter
);
647 ACE_Thread::setspecific (this->key_
,
649 #endif /* ACE_HAS_THR_C_DEST */
652 template <class ACE_LOCK
> int
653 ACE_TSS_Read_Guard
<ACE_LOCK
>::acquire (void)
655 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::acquire");
657 ACE_Read_Guard
<ACE_LOCK
> *guard
= 0;
659 #if defined (ACE_HAS_THR_C_DEST)
660 ACE_TSS_Adapter
*tss_adapter
= 0;
661 void *temp
= tss_adapter
; // Need this temp to keep G++ from complaining.
662 ACE_Thread::getspecific (this->key_
, &temp
);
663 tss_adapter
= static_cast <ACE_TSS_Adapter
*> (temp
);
664 guard
= static_cast <ACE_Read_Guard
<ACE_LOCK
> *> (tss_adapter
->ts_obj_
);
666 void *temp
= guard
; // Need this temp to keep G++ from complaining.
667 ACE_Thread::getspecific (this->key_
, &temp
);
668 guard
= static_cast <ACE_Read_Guard
<ACE_LOCK
> *> (temp
);
669 #endif /* ACE_HAS_THR_C_DEST */
671 return guard
->acquire_read ();
674 template <class ACE_LOCK
> int
675 ACE_TSS_Read_Guard
<ACE_LOCK
>::tryacquire (void)
677 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire");
679 ACE_Read_Guard
<ACE_LOCK
> *guard
= 0;
681 #if defined (ACE_HAS_THR_C_DEST)
682 ACE_TSS_Adapter
*tss_adapter
= 0;
683 void *temp
= tss_adapter
; // Need this temp to keep G++ from complaining.
684 ACE_Thread::getspecific (this->key_
, &temp
);
685 tss_adapter
= static_cast <ACE_TSS_Adapter
*> (temp
);
686 guard
= static_cast <ACE_Read_Guard
<ACE_LOCK
> *> (tss_adapter
->ts_obj_
);
688 void *temp
= guard
; // Need this temp to keep G++ from complaining.
689 ACE_Thread::getspecific (this->key_
, &temp
);
690 guard
= static_cast <ACE_Read_Guard
<ACE_LOCK
> *> (temp
);
691 #endif /* ACE_HAS_THR_C_DEST */
693 return guard
->tryacquire_read ();
696 template <class ACE_LOCK
> int
697 ACE_TSS_Read_Guard
<ACE_LOCK
>::acquire_read (void)
699 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::acquire_read");
701 return this->acquire ();
704 template <class ACE_LOCK
> int
705 ACE_TSS_Read_Guard
<ACE_LOCK
>::tryacquire_read (void)
707 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire_read");
709 return this->tryacquire ();
712 template <class ACE_LOCK
> void
713 ACE_TSS_Read_Guard
<ACE_LOCK
>::dump (void) const
715 #if defined (ACE_HAS_DUMP)
716 // ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::dump");
717 ACE_TSS_Guard
<ACE_LOCK
>::dump ();
718 #endif /* ACE_HAS_DUMP */
721 #endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */
723 ACE_END_VERSIONED_NAMESPACE_DECL
725 #endif /* ACE_TSS_T_CPP */