Collaboration diagram for ACE_TSS_Cleanup:
Public Member Functions | |
int | insert (ACE_thread_key_t key, void(*destructor)(void *)) |
void | thread_use_key (ACE_thread_key_t key) |
Mark a key as being used by this thread. | |
int | thread_detach_key (ACE_thread_key_t key) |
int | free_key (ACE_thread_key_t key) |
void | thread_exit (void) |
Private Types | |
typedef ACE_TSS_Info | ACE_TSS_TABLE [ACE_DEFAULT_THREAD_KEYS] |
typedef ACE_TSS_Info * | ACE_TSS_TABLE_ITERATOR |
Private Member Functions | |
void | dump (void) |
void | thread_release (ACE_TSS_Info &info, ACE_TSS_Info::Destructor &destructor, void *&tss_obj) |
int | remove_key (ACE_TSS_Info &info) |
bool | find_tss_keys (ACE_TSS_Keys *&thread_keys) const |
ACE_TSS_Keys * | tss_keys () |
ACE_TSS_Cleanup (void) | |
Ensure singleton. | |
~ACE_TSS_Cleanup (void) | |
Private Attributes | |
ACE_TSS_TABLE | table_ |
Table of 's. | |
ACE_thread_key_t | in_use_ |
Friends | |
class | TSS_Cleanup_Instance |
ACE_TSS_Cleanup access only via TSS_Cleanup_Instance. |
Definition at line 532 of file OS_NS_Thread.cpp.
|
Definition at line 591 of file OS_NS_Thread.cpp. |
|
Definition at line 592 of file OS_NS_Thread.cpp. Referenced by dump(). |
|
Ensure singleton.
Definition at line 854 of file OS_NS_Thread.cpp. References ACE_OS_TRACE.
00855 : in_use_ (ACE_OS::NULL_key) 00856 { 00857 ACE_OS_TRACE ("ACE_TSS_Cleanup::ACE_TSS_Cleanup"); 00858 } |
|
Definition at line 771 of file OS_NS_Thread.cpp.
00772 { 00773 } |
|
Definition at line 1003 of file OS_NS_Thread.cpp. References ACE_DEFAULT_THREAD_KEYS, ACE_TSS_TABLE_ITERATOR, and ACE_TSS_Info::dump().
01004 { 01005 # if defined (ACE_HAS_DUMP) 01006 // Iterate through all the thread-specific items and dump them all. 01007 01008 ACE_TSS_TABLE_ITERATOR key_info = table_; 01009 for (unsigned int i = 0; 01010 i < ACE_DEFAULT_THREAD_KEYS; 01011 ++key_info, ++i) 01012 key_info->dump (); 01013 # endif /* ACE_HAS_DUMP */ 01014 } |
|
Find the TSS keys (if any) for this thread.
Definition at line 1017 of file OS_NS_Thread.cpp. References ACE_ASSERT, in_use_, and ACE_OS::thr_getspecific(). Referenced by thread_exit(), and thread_release().
01018 { 01019 if (this->in_use_ == ACE_OS::NULL_key) 01020 return false; 01021 if (ACE_OS::thr_getspecific (in_use_, 01022 reinterpret_cast<void **> (&tss_keys)) == -1) 01023 { 01024 ACE_ASSERT (false); 01025 return false; // This should not happen! 01026 } 01027 return tss_keys != 0; 01028 } |
|
This key is no longer used Release key if use count == 0 fail if use_count != 0;
Definition at line 884 of file OS_NS_Thread.cpp. References ACE_DEFAULT_THREAD_KEYS, ACE_KEY_INDEX, ACE_OS_TRACE, ACE_thread_key_t, ACE_TSS_CLEANUP_GUARD, and remove_key().
00885 { 00886 ACE_OS_TRACE ("ACE_TSS_Cleanup::free_key"); 00887 ACE_TSS_CLEANUP_GUARD 00888 ACE_KEY_INDEX (key_index, key); 00889 if (key_index < ACE_DEFAULT_THREAD_KEYS) 00890 { 00891 return remove_key (this->table_ [key_index]); 00892 } 00893 return -1; 00894 } |
|
Register a newly-allocated key
Definition at line 861 of file OS_NS_Thread.cpp. References ACE_ASSERT, ACE_DEFAULT_THREAD_KEYS, ACE_KEY_INDEX, ACE_OS_TRACE, ACE_thread_key_t, ACE_TSS_CLEANUP_GUARD, and ACE_TSS_Info::thread_count_.
00863 { 00864 ACE_OS_TRACE ("ACE_TSS_Cleanup::insert"); 00865 ACE_TSS_CLEANUP_GUARD 00866 00867 ACE_KEY_INDEX (key_index, key); 00868 ACE_ASSERT (key_index < ACE_DEFAULT_THREAD_KEYS); 00869 if (key_index < ACE_DEFAULT_THREAD_KEYS) 00870 { 00871 ACE_ASSERT (table_[key_index].thread_count_ == -1); 00872 table_[key_index] = ACE_TSS_Info (key, destructor); 00873 table_[key_index].thread_count_ = 0; // inserting it does not use it 00874 // but it does "allocate" it 00875 return 0; 00876 } 00877 else 00878 { 00879 return -1; 00880 } 00881 } |
|
remove key if it's unused (thread_count == 0)
Definition at line 897 of file OS_NS_Thread.cpp. References ACE_OS_thread_key_t, ACE_OS_TRACE, ACE_TSS_Info::destructor_, in_use_, ACE_TSS_Info::key_, ACE_TSS_Info::key_in_use(), and ACE_TSS_Info::thread_count_. Referenced by free_key().
00898 { 00899 // assume CLEANUP_GUARD is held by caller 00900 ACE_OS_TRACE ("ACE_TSS_Cleanup::remove_key"); 00901 00902 #if 0 // This was a good idea, but POSIX says it's legal to delete used keys. 00903 // When this is done, any existing TSS objects controlled by this key are leaked 00904 // There is no "right thing" to do in this case 00905 00906 // only remove it if all threads are done with it 00907 if (info.thread_count_ != 0) 00908 { 00909 return -1; 00910 } 00911 #endif // 0 00912 00913 #if !defined (ACE_HAS_TSS_EMULATION) 00914 ACE_OS_thread_key_t temp_key = info.key_; 00915 ACE_OS::thr_keyfree_native (temp_key); 00916 #endif /* !ACE_HAS_TSS_EMULATION */ 00917 if (info.key_ == this->in_use_) 00918 { 00919 this->in_use_ = ACE_OS::NULL_key; 00920 } 00921 info.key_in_use (0); 00922 info.destructor_ = 0; 00923 return 0; 00924 } |
|
This thread is no longer using this key call destructor if appropriate Definition at line 927 of file OS_NS_Thread.cpp. References ACE_ASSERT, ACE_KEY_INDEX, ACE_thread_key_t, ACE_TSS_CLEANUP_GUARD, ACE_TSS_Info::Destructor, ACE_TSS_Info::key_in_use(), and thread_release().
00928 { 00929 // variables to hold the destructor and the object to be destructed 00930 // the actual call is deferred until the guard is released 00931 ACE_TSS_Info::Destructor destructor = 0; 00932 void * tss_obj = 0; 00933 00934 // scope the guard 00935 { 00936 ACE_TSS_CLEANUP_GUARD 00937 00938 ACE_KEY_INDEX (key_index, key); 00939 ACE_ASSERT (key_index < sizeof(this->table_)/sizeof(this->table_[0]) 00940 && this->table_[key_index].key_ == key); 00941 ACE_TSS_Info &info = this->table_ [key_index]; 00942 00943 // sanity check 00944 if (!info.key_in_use ()) 00945 { 00946 return -1; 00947 } 00948 00949 this->thread_release (info, destructor, tss_obj); 00950 } // end of scope for the Guard 00951 // if there's a destructor and an object to be destroyed 00952 if (destructor != 0 && tss_obj != 0) 00953 { 00954 (*destructor) (tss_obj); 00955 } 00956 return 0; 00957 } |
|
Cleanup the thread-specific objects. Does _NOT_ exit the thread. For each used key perform the same actions as free_key. Definition at line 776 of file OS_NS_Thread.cpp. References ACE_DEFAULT_THREAD_KEYS, ACE_KEY_INDEX, ACE_OS_TRACE, ACE_TSS_CLEANUP_GUARD, ACE_TSS_Info::Destructor, find_tss_keys(), in_use_, ACE_TSS_Info::key_, ACE_TSS_Info::key_in_use(), and thread_release().
00777 { 00778 ACE_OS_TRACE ("ACE_TSS_Cleanup::thread_exit"); 00779 // variables to hold the destructors 00780 // and pointers to the object to be destructed 00781 // the actual destruction is deferred until the guard is released 00782 ACE_TSS_Info::Destructor destructor[ACE_DEFAULT_THREAD_KEYS]; 00783 void * tss_obj[ACE_DEFAULT_THREAD_KEYS]; 00784 // count of items to be destroyed 00785 unsigned int d_count = 0; 00786 00787 // scope the guard 00788 { 00789 ACE_TSS_CLEANUP_GUARD 00790 00791 // if not initialized or already cleaned up 00792 ACE_TSS_Keys *this_thread_keys = 0; 00793 if (! find_tss_keys (this_thread_keys) ) 00794 { 00795 return; 00796 } 00797 00798 // Minor hack: Iterating in reverse order means the LOG buffer which is 00799 // accidentally allocated first will be accidentally deallocated (almost) 00800 // last -- in case someone logs something from the other destructors. 00801 // applications should not count on this behavior because platforms which 00802 // do not use ACE_TSS_Cleanup may delete objects in other orders. 00803 unsigned int key_index = ACE_DEFAULT_THREAD_KEYS; 00804 while( key_index > 0) 00805 { 00806 --key_index; 00807 ACE_TSS_Info & info = this->table_[key_index]; 00808 // if this key is in use by this thread 00809 if (info.key_in_use () && this_thread_keys->is_set(info.key_)) 00810 { 00811 // defer deleting the in-use key until all others have been deleted 00812 if(info.key_ != this->in_use_) 00813 { 00814 destructor[d_count] = 0; 00815 tss_obj[d_count] = 0; 00816 this->thread_release (info, destructor[d_count], tss_obj[d_count]); 00817 if (destructor[d_count] != 0 && tss_obj[d_count] != 0) 00818 { 00819 ++d_count; 00820 } 00821 } 00822 } 00823 } 00824 00825 // remove the in_use bit vector last 00826 ACE_KEY_INDEX (use_index, this->in_use_); 00827 ACE_TSS_Info & info = this->table_[use_index]; 00828 destructor[d_count] = 0; 00829 tss_obj[d_count] = 0; 00830 this->thread_release (info, destructor[d_count], tss_obj[d_count]); 00831 if (destructor[d_count] != 0 && tss_obj[d_count] != 0) 00832 { 00833 ++d_count; 00834 } 00835 #if defined (ACE_HAS_TSS_EMULATION) 00836 ACE_TSS_Emulation::ts_object (this->in_use_) = 0; 00837 #else // defined (ACE_HAS_TSS_EMULATION) 00838 ACE_OS::thr_setspecific_native (info.key_, 0); 00839 #endif // defined (ACE_HAS_TSS_EMULATION) 00840 00841 } // end of guard scope 00842 for (unsigned int d_index = 0; d_index < d_count; ++d_index) 00843 { 00844 (*destructor[d_index])(tss_obj[d_index]); 00845 } 00846 } |
|
Release a key used by this thread
Definition at line 960 of file OS_NS_Thread.cpp. References ACE_ASSERT, ACE_TSS_Info::Destructor, ACE_TSS_Info::destructor_, find_tss_keys(), ACE_TSS_Info::key_, ACE_TSS_Keys::test_and_clear(), ACE_OS::thr_getspecific(), and ACE_TSS_Info::thread_count_. Referenced by thread_detach_key(), and thread_exit().
00964 { 00965 // assume guard is held by caller 00966 // Find the TSS keys (if any) for this thread 00967 // do not create them if they don't exist 00968 ACE_TSS_Keys * thread_keys = 0; 00969 if (find_tss_keys (thread_keys)) 00970 { 00971 // if this key is in use by this thread 00972 if (thread_keys->test_and_clear(info.key_) == 0) 00973 { 00974 // save destructor & pointer to tss object 00975 // until after the guard is released 00976 destructor = info.destructor_; 00977 ACE_OS::thr_getspecific (info.key_, &tss_obj); 00978 ACE_ASSERT (info.thread_count_ > 0); 00979 --info.thread_count_; 00980 } 00981 } 00982 } |
|
Mark a key as being used by this thread.
Definition at line 985 of file OS_NS_Thread.cpp. References ACE_ASSERT, ACE_KEY_INDEX, ACE_thread_key_t, ACE_TSS_CLEANUP_GUARD, ACE_TSS_Info::key_in_use(), ACE_TSS_Keys::test_and_set(), ACE_TSS_Info::thread_count_, and tss_keys().
00986 { 00987 // If the key's ACE_TSS_Info in-use bit for this thread is not set, 00988 // set it and increment the key's thread_count_. 00989 if (! tss_keys ()->test_and_set (key)) 00990 { 00991 ACE_TSS_CLEANUP_GUARD 00992 00993 // Retrieve the key's ACE_TSS_Info and increment its thread_count_. 00994 ACE_KEY_INDEX (key_index, key); 00995 ACE_TSS_Info &key_info = this->table_ [key_index]; 00996 00997 ACE_ASSERT (key_info.key_in_use ()); 00998 ++key_info.thread_count_; 00999 } 01000 } |
|
Accessor for this threads ACE_TSS_Keys instance. Creates the keys if necessary. Definition at line 1031 of file OS_NS_Thread.cpp. References ACE_ASSERT, ACE_NEW_RETURN, ACE_TSS_CLEANUP_GUARD, ACE_TSS_Cleanup_keys_destroyer(), in_use_, ACE_OS::thr_getspecific(), ACE_OS::thr_keycreate(), and ACE_OS::thr_setspecific(). Referenced by thread_use_key().
01032 { 01033 if (this->in_use_ == ACE_OS::NULL_key) 01034 { 01035 ACE_TSS_CLEANUP_GUARD 01036 // Double-check; 01037 if (in_use_ == ACE_OS::NULL_key) 01038 { 01039 // Initialize in_use_ with a new key. 01040 if (ACE_OS::thr_keycreate (&in_use_, 01041 &ACE_TSS_Cleanup_keys_destroyer)) 01042 { 01043 ACE_ASSERT (false); 01044 return 0; // Major problems, this should *never* happen! 01045 } 01046 } 01047 } 01048 01049 ACE_TSS_Keys *ts_keys = 0; 01050 if (ACE_OS::thr_getspecific (in_use_, 01051 reinterpret_cast <void **> (&ts_keys)) == -1) 01052 { 01053 ACE_ASSERT (false); 01054 return 0; // This should not happen! 01055 } 01056 01057 if (ts_keys == 0) 01058 { 01059 ACE_NEW_RETURN (ts_keys, 01060 ACE_TSS_Keys, 01061 0); 01062 // Store the dynamically allocated pointer in thread-specific 01063 // storage. 01064 if (ACE_OS::thr_setspecific (in_use_, 01065 reinterpret_cast <void *> (ts_keys)) == -1) 01066 { 01067 ACE_ASSERT (false); 01068 delete ts_keys; 01069 return 0; // Major problems, this should *never* happen! 01070 } 01071 } 01072 01073 return ts_keys; 01074 } |
|
ACE_TSS_Cleanup access only via TSS_Cleanup_Instance.
Definition at line 587 of file OS_NS_Thread.cpp. |
|
Key for the thread-specific ACE_TSS_Keys Used by find_tss_keys() or tss_keys() to find the bit array that records whether each TSS key is in use by this thread. Definition at line 601 of file OS_NS_Thread.cpp. Referenced by find_tss_keys(), remove_key(), thread_exit(), and tss_keys(). |
|
Table of 's.
Definition at line 595 of file OS_NS_Thread.cpp. |