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 585 of file OS_NS_Thread.cpp.
|
Definition at line 644 of file OS_NS_Thread.cpp. |
|
Definition at line 645 of file OS_NS_Thread.cpp. Referenced by dump(). |
|
Ensure singleton.
Definition at line 907 of file OS_NS_Thread.cpp. References ACE_OS_TRACE.
00908 : in_use_ (ACE_OS::NULL_key) 00909 { 00910 ACE_OS_TRACE ("ACE_TSS_Cleanup::ACE_TSS_Cleanup"); 00911 } |
|
Definition at line 824 of file OS_NS_Thread.cpp.
00825 { 00826 } |
|
Definition at line 1056 of file OS_NS_Thread.cpp. References ACE_TSS_TABLE_ITERATOR, and ACE_TSS_Info::dump().
01057 { 01058 # if defined (ACE_HAS_DUMP) 01059 // Iterate through all the thread-specific items and dump them all. 01060 01061 ACE_TSS_TABLE_ITERATOR key_info = table_; 01062 for (unsigned int i = 0; 01063 i < ACE_DEFAULT_THREAD_KEYS; 01064 ++key_info, ++i) 01065 key_info->dump (); 01066 # endif /* ACE_HAS_DUMP */ 01067 } |
|
Find the TSS keys (if any) for this thread.
Definition at line 1070 of file OS_NS_Thread.cpp. References ACE_ASSERT, in_use_, and ACE_OS::thr_getspecific(). Referenced by thread_exit(), and thread_release().
01071 { 01072 if (this->in_use_ == ACE_OS::NULL_key) 01073 return false; 01074 if (ACE_OS::thr_getspecific (in_use_, 01075 reinterpret_cast<void **> (&tss_keys)) == -1) 01076 { 01077 ACE_ASSERT (false); 01078 return false; // This should not happen! 01079 } 01080 return tss_keys != 0; 01081 } |
|
This key is no longer used Release key if use count == 0 fail if use_count != 0;
Definition at line 937 of file OS_NS_Thread.cpp. References ACE_KEY_INDEX, ACE_OS_TRACE, ACE_thread_key_t, ACE_TSS_CLEANUP_GUARD, and remove_key().
00938 { 00939 ACE_OS_TRACE ("ACE_TSS_Cleanup::free_key"); 00940 ACE_TSS_CLEANUP_GUARD 00941 ACE_KEY_INDEX (key_index, key); 00942 if (key_index < ACE_DEFAULT_THREAD_KEYS) 00943 { 00944 return remove_key (this->table_ [key_index]); 00945 } 00946 return -1; 00947 } |
|
Register a newly-allocated key
Definition at line 914 of file OS_NS_Thread.cpp. References ACE_ASSERT, ACE_KEY_INDEX, ACE_OS_TRACE, ACE_thread_key_t, ACE_TSS_CLEANUP_GUARD, and ACE_TSS_Info::thread_count_.
00916 { 00917 ACE_OS_TRACE ("ACE_TSS_Cleanup::insert"); 00918 ACE_TSS_CLEANUP_GUARD 00919 00920 ACE_KEY_INDEX (key_index, key); 00921 ACE_ASSERT (key_index < ACE_DEFAULT_THREAD_KEYS); 00922 if (key_index < ACE_DEFAULT_THREAD_KEYS) 00923 { 00924 ACE_ASSERT (table_[key_index].thread_count_ == -1); 00925 table_[key_index] = ACE_TSS_Info (key, destructor); 00926 table_[key_index].thread_count_ = 0; // inserting it does not use it 00927 // but it does "allocate" it 00928 return 0; 00929 } 00930 else 00931 { 00932 return -1; 00933 } 00934 } |
|
remove key if it's unused (thread_count == 0)
Definition at line 950 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().
00951 { 00952 // assume CLEANUP_GUARD is held by caller 00953 ACE_OS_TRACE ("ACE_TSS_Cleanup::remove_key"); 00954 00955 #if 0 // This was a good idea, but POSIX says it's legal to delete used keys. 00956 // When this is done, any existing TSS objects controlled by this key are leaked 00957 // There is no "right thing" to do in this case 00958 00959 // only remove it if all threads are done with it 00960 if (info.thread_count_ != 0) 00961 { 00962 return -1; 00963 } 00964 #endif // 0 00965 00966 #if !defined (ACE_HAS_TSS_EMULATION) 00967 ACE_OS_thread_key_t temp_key = info.key_; 00968 ACE_OS::thr_keyfree_native (temp_key); 00969 #endif /* !ACE_HAS_TSS_EMULATION */ 00970 if (info.key_ == this->in_use_) 00971 { 00972 this->in_use_ = ACE_OS::NULL_key; 00973 } 00974 info.key_in_use (0); 00975 info.destructor_ = 0; 00976 return 0; 00977 } |
|
This thread is no longer using this key call destructor if appropriate Definition at line 980 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().
00981 { 00982 // variables to hold the destructor and the object to be destructed 00983 // the actual call is deferred until the guard is released 00984 ACE_TSS_Info::Destructor destructor = 0; 00985 void * tss_obj = 0; 00986 00987 // scope the guard 00988 { 00989 ACE_TSS_CLEANUP_GUARD 00990 00991 ACE_KEY_INDEX (key_index, key); 00992 ACE_ASSERT (key_index < sizeof(this->table_)/sizeof(this->table_[0]) 00993 && this->table_[key_index].key_ == key); 00994 ACE_TSS_Info &info = this->table_ [key_index]; 00995 00996 // sanity check 00997 if (!info.key_in_use ()) 00998 { 00999 return -1; 01000 } 01001 01002 this->thread_release (info, destructor, tss_obj); 01003 } // end of scope for the Guard 01004 // if there's a destructor and an object to be destroyed 01005 if (destructor != 0 && tss_obj != 0) 01006 { 01007 (*destructor) (tss_obj); 01008 } 01009 return 0; 01010 } |
|
Cleanup the thread-specific objects. Does _NOT_ exit the thread. For each used key perform the same actions as free_key. Definition at line 829 of file OS_NS_Thread.cpp. References 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().
00830 { 00831 ACE_OS_TRACE ("ACE_TSS_Cleanup::thread_exit"); 00832 // variables to hold the destructors 00833 // and pointers to the object to be destructed 00834 // the actual destruction is deferred until the guard is released 00835 ACE_TSS_Info::Destructor destructor[ACE_DEFAULT_THREAD_KEYS]; 00836 void * tss_obj[ACE_DEFAULT_THREAD_KEYS]; 00837 // count of items to be destroyed 00838 unsigned int d_count = 0; 00839 00840 // scope the guard 00841 { 00842 ACE_TSS_CLEANUP_GUARD 00843 00844 // if not initialized or already cleaned up 00845 ACE_TSS_Keys *this_thread_keys = 0; 00846 if (! find_tss_keys (this_thread_keys) ) 00847 { 00848 return; 00849 } 00850 00851 // Minor hack: Iterating in reverse order means the LOG buffer which is 00852 // accidentally allocated first will be accidentally deallocated (almost) 00853 // last -- in case someone logs something from the other destructors. 00854 // applications should not count on this behavior because platforms which 00855 // do not use ACE_TSS_Cleanup may delete objects in other orders. 00856 unsigned int key_index = ACE_DEFAULT_THREAD_KEYS; 00857 while( key_index > 0) 00858 { 00859 --key_index; 00860 ACE_TSS_Info & info = this->table_[key_index]; 00861 // if this key is in use by this thread 00862 if (info.key_in_use () && this_thread_keys->is_set(info.key_)) 00863 { 00864 // defer deleting the in-use key until all others have been deleted 00865 if(info.key_ != this->in_use_) 00866 { 00867 destructor[d_count] = 0; 00868 tss_obj[d_count] = 0; 00869 this->thread_release (info, destructor[d_count], tss_obj[d_count]); 00870 if (destructor[d_count] != 0 && tss_obj[d_count] != 0) 00871 { 00872 ++d_count; 00873 } 00874 } 00875 } 00876 } 00877 00878 // remove the in_use bit vector last 00879 ACE_KEY_INDEX (use_index, this->in_use_); 00880 ACE_TSS_Info & info = this->table_[use_index]; 00881 destructor[d_count] = 0; 00882 tss_obj[d_count] = 0; 00883 this->thread_release (info, destructor[d_count], tss_obj[d_count]); 00884 if (destructor[d_count] != 0 && tss_obj[d_count] != 0) 00885 { 00886 ++d_count; 00887 } 00888 #if defined (ACE_HAS_TSS_EMULATION) 00889 ACE_TSS_Emulation::ts_object (this->in_use_) = 0; 00890 #else // defined (ACE_HAS_TSS_EMULATION) 00891 ACE_OS::thr_setspecific_native (info.key_, 0); 00892 #endif // defined (ACE_HAS_TSS_EMULATION) 00893 00894 } // end of guard scope 00895 for (unsigned int d_index = 0; d_index < d_count; ++d_index) 00896 { 00897 (*destructor[d_index])(tss_obj[d_index]); 00898 } 00899 } |
|
Release a key used by this thread
Definition at line 1013 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().
01017 { 01018 // assume guard is held by caller 01019 // Find the TSS keys (if any) for this thread 01020 // do not create them if they don't exist 01021 ACE_TSS_Keys * thread_keys = 0; 01022 if (find_tss_keys (thread_keys)) 01023 { 01024 // if this key is in use by this thread 01025 if (thread_keys->test_and_clear(info.key_) == 0) 01026 { 01027 // save destructor & pointer to tss object 01028 // until after the guard is released 01029 destructor = info.destructor_; 01030 ACE_OS::thr_getspecific (info.key_, &tss_obj); 01031 ACE_ASSERT (info.thread_count_ > 0); 01032 --info.thread_count_; 01033 } 01034 } 01035 } |
|
Mark a key as being used by this thread.
Definition at line 1038 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().
01039 { 01040 // If the key's ACE_TSS_Info in-use bit for this thread is not set, 01041 // set it and increment the key's thread_count_. 01042 if (! tss_keys ()->test_and_set (key)) 01043 { 01044 ACE_TSS_CLEANUP_GUARD 01045 01046 // Retrieve the key's ACE_TSS_Info and increment its thread_count_. 01047 ACE_KEY_INDEX (key_index, key); 01048 ACE_TSS_Info &key_info = this->table_ [key_index]; 01049 01050 ACE_ASSERT (key_info.key_in_use ()); 01051 ++key_info.thread_count_; 01052 } 01053 } |
|
Accessor for this threads ACE_TSS_Keys instance. Creates the keys if necessary. Definition at line 1084 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().
01085 { 01086 if (this->in_use_ == ACE_OS::NULL_key) 01087 { 01088 ACE_TSS_CLEANUP_GUARD 01089 // Double-check; 01090 if (in_use_ == ACE_OS::NULL_key) 01091 { 01092 // Initialize in_use_ with a new key. 01093 if (ACE_OS::thr_keycreate (&in_use_, 01094 &ACE_TSS_Cleanup_keys_destroyer)) 01095 { 01096 ACE_ASSERT (false); 01097 return 0; // Major problems, this should *never* happen! 01098 } 01099 } 01100 } 01101 01102 ACE_TSS_Keys *ts_keys = 0; 01103 if (ACE_OS::thr_getspecific (in_use_, 01104 reinterpret_cast <void **> (&ts_keys)) == -1) 01105 { 01106 ACE_ASSERT (false); 01107 return 0; // This should not happen! 01108 } 01109 01110 if (ts_keys == 0) 01111 { 01112 ACE_NEW_RETURN (ts_keys, 01113 ACE_TSS_Keys, 01114 0); 01115 // Store the dynamically allocated pointer in thread-specific 01116 // storage. 01117 if (ACE_OS::thr_setspecific (in_use_, 01118 reinterpret_cast <void *> (ts_keys)) == -1) 01119 { 01120 ACE_ASSERT (false); 01121 delete ts_keys; 01122 return 0; // Major problems, this should *never* happen! 01123 } 01124 } 01125 01126 return ts_keys; 01127 } |
|
ACE_TSS_Cleanup access only via TSS_Cleanup_Instance.
Definition at line 640 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 654 of file OS_NS_Thread.cpp. Referenced by find_tss_keys(), remove_key(), thread_exit(), and tss_keys(). |
|
Table of 's.
Definition at line 648 of file OS_NS_Thread.cpp. |