Collaboration diagram for ACE_TSS_Cleanup:

Public Methods | |
| ~ACE_TSS_Cleanup (void) | |
| void | exit (void *status) |
| Cleanup the thread-specific objects. Does _NOT_ exit the thread. More... | |
| int | insert (ACE_thread_key_t key, void(*destructor)(void *), void *inst) |
| Insert a <key, destructor> tuple into the table. More... | |
| int | remove (ACE_thread_key_t key) |
| Remove a <key, destructor> tuple from the table. More... | |
| int | detach (void *inst) |
| Detaches a tss_instance from its key. More... | |
| void | key_used (ACE_thread_key_t key) |
| Mark a key as being used by this thread. More... | |
| int | free_all_keys_left (void) |
| Free all keys left in the table before destruction. More... | |
Static Public Methods | |
| ACE_TSS_Cleanup * | instance (void) |
| int | lockable () |
| Indication of whether the ACE_TSS_CLEANUP_LOCK is usable, and therefore whether we are in static constructor/destructor phase or not. More... | |
Protected Methods | |
| void | dump (void) |
| ACE_TSS_Cleanup (void) | |
| Ensure singleton. More... | |
Private Types | |
| typedef ACE_TSS_Info | ACE_TSS_TABLE [ACE_DEFAULT_THREAD_KEYS] |
| typedef ACE_TSS_Info * | ACE_TSS_TABLE_ITERATOR |
Private Methods | |
| ACE_TSS_Keys * | tss_keys () |
| Accessor for this threads ACE_TSS_Keys instance. More... | |
Private Attributes | |
| ACE_TSS_TABLE | table_ |
| Table of <ACE_TSS_Info>'s. More... | |
| ACE_thread_key_t | in_use_ |
| Key for the thread-specific array of whether each TSS key is in use. More... | |
Static Private Attributes | |
| ACE_TSS_Cleanup * | instance_ = 0 |
| Pointer to the singleton instance. More... | |
All this nonsense is required since Win32 doesn't automatically cleanup thread-specific storage on thread exit, unlike real operating systems... ;-)
Definition at line 1789 of file OS.cpp.
|
|
|
|
|
|
|
|
Definition at line 1855 of file OS.cpp. References instance_.
01856 {
01857 // Zero out the instance pointer to support lockable () accessor.
01858 ACE_TSS_Cleanup::instance_ = 0;
01859 }
|
|
|
Ensure singleton.
Definition at line 2001 of file OS.cpp. References ACE_OS_TRACE.
02002 : in_use_ (ACE_OS::NULL_key) 02003 #if defined (ACE_HAS_TSS_EMULATION) 02004 // ACE_TSS_Emulation::total_keys () provides the value of the next 02005 // key to be created. 02006 , in_use_key_ (ACE_TSS_Emulation::total_keys ()) 02007 #endif /* ACE_HAS_TSS_EMULATION */ 02008 { 02009 ACE_OS_TRACE ("ACE_TSS_Cleanup::ACE_TSS_Cleanup"); 02010 } |
|
|
Detaches a tss_instance from its key.
Definition at line 2083 of file OS.cpp. References ACE_thread_key_t, ACE_TSS_CLEANUP_GUARD, remove, table_, and ACE_TSS_Info::tss_obj_. Referenced by ACE_OS::thr_key_detach.
02084 {
02085 ACE_TSS_CLEANUP_GUARD
02086
02087 ACE_TSS_TABLE_ITERATOR key_info = table_;
02088 int success = 0;
02089 int ref_cnt = 0;
02090
02091 // Mark the key as detached in the TSS_Info table.
02092 // It only works for the first key that "inst" owns.
02093 // I don't know why.
02094 for (unsigned int i = 0;
02095 i < ACE_DEFAULT_THREAD_KEYS;
02096 ++key_info, ++i)
02097 {
02098 if (key_info->tss_obj_ == inst)
02099 {
02100 key_info->tss_obj_ = 0;
02101 ref_cnt = --key_info->thread_count_;
02102 success = 1;
02103 break;
02104 }
02105 }
02106
02107 if (success == 0)
02108 return -1;
02109 else if (ref_cnt == 0)
02110 {
02111 // Mark the key as no longer being used.
02112 key_info->key_in_use (0);
02113 # if defined (ACE_WIN32) || (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS))
02114 ACE_thread_key_t temp_key = key_info->key_;
02115 # endif /* ACE_WIN32 */
02116 int retv = this->remove (key_info->key_);
02117
02118 # if defined (ACE_WIN32)
02119 ::TlsFree (temp_key);
02120 # elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)
02121 ::tsd_delete (temp_key);
02122 # endif /* ACE_WIN32 */
02123 return retv;
02124 }
02125
02126 return 0;
02127 }
|
|
|
Definition at line 2149 of file OS.cpp. References ACE_TSS_Info::dump, and table_.
02150 {
02151 // Iterate through all the thread-specific items and dump them all.
02152
02153 ACE_TSS_TABLE_ITERATOR key_info = table_;
02154 for (unsigned int i = 0;
02155 i < ACE_DEFAULT_THREAD_KEYS;
02156 ++key_info, ++i)
02157 key_info->dump ();
02158 }
|
|
|
Cleanup the thread-specific objects. Does _NOT_ exit the thread.
Definition at line 1862 of file OS.cpp. References ACE_OS_TRACE, ACE_TSS_CLEANUP_GUARD, ACE_TSS_Info::destructor_, ACE_TSS_Info::key_, ACE_TSS_Info::key_in_use, ACE_OS::NULL_key, remove, table_, ACE_TSS_Keys::test_and_clear, ACE_OS::thr_getspecific, ACE_OS::thr_keyfree, ACE_TSS_Info::thread_count_, tss_keys, and ACE_TSS_Info::tss_obj_. Referenced by ACE_OS::cleanup_tss.
01863 {
01864 ACE_OS_TRACE ("ACE_TSS_Cleanup::exit");
01865
01866 ACE_TSS_TABLE_ITERATOR key_info = table_;
01867 ACE_TSS_Info info_arr[ACE_DEFAULT_THREAD_KEYS];
01868 int info_ix = 0;
01869
01870 // While holding the lock, we only collect the ACE_TSS_Info objects
01871 // in an array without invoking the according destructors.
01872 {
01873 ACE_TSS_CLEANUP_GUARD
01874
01875 // Iterate through all the thread-specific items and free them all
01876 // up.
01877
01878 for (unsigned int i = 0;
01879 i < ACE_DEFAULT_THREAD_KEYS;
01880 ++key_info, ++i)
01881 {
01882 if (key_info->key_ == ACE_OS::NULL_key ||
01883 ! key_info->key_in_use ()) continue;
01884
01885 // If the key's ACE_TSS_Info in-use bit for this thread was set,
01886 // unset it and decrement the key's thread_count_.
01887 if (! tss_keys ()->test_and_clear (key_info->key_))
01888 {
01889 --key_info->thread_count_;
01890 }
01891
01892 void *tss_info = 0;
01893
01894 if (key_info->destructor_
01895 && ACE_OS::thr_getspecific (key_info->key_, &tss_info) == 0
01896 && tss_info)
01897 {
01898 info_arr[info_ix].key_ = key_info->key_;
01899 info_arr[info_ix].destructor_ = key_info->destructor_;
01900 info_arr[info_ix++].tss_obj_ = key_info->tss_obj_;
01901 }
01902 }
01903 }
01904
01905 // Now we have given up the ACE_TSS_Cleanup::lock_ and we start
01906 // invoking destructors, in the reverse order of creation.
01907 for (int i = info_ix - 1; i >= 0; --i)
01908 {
01909 void *tss_info = 0;
01910
01911 ACE_OS::thr_getspecific (info_arr[i].key_, &tss_info);
01912
01913 if (tss_info != 0)
01914 {
01915 // Only call the destructor if the value is non-zero for this
01916 // thread.
01917 (*info_arr[i].destructor_)(tss_info);
01918 }
01919 }
01920
01921 // Acquire the ACE_TSS_CLEANUP_LOCK, then free TLS keys and remove
01922 // entries from ACE_TSS_Info table.
01923 {
01924 ACE_TSS_CLEANUP_GUARD
01925
01926 # if 0
01927 // We shouldn't free the key and remove it from the table here
01928 // because if we do and some thread ends before other threads
01929 // even get started (or their TSS object haven't been created yet,)
01930 // it's entry will be removed from the table and we are in big chaos.
01931 // For TSS object, these have been done in ACE_TSS_Cleanup::detach.
01932 // Two other use cases will be user managed TSS'es and system wide
01933 // TSS, ones are users responsibilities and the others should be
01934 // persistant system wide.
01935 for (int i = 0; i < index; i++)
01936 {
01937 # if defined (ACE_WIN32) || (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS))
01938 // Calling thr_keyfree here ensure the key
01939 // gets removed appropriately. Notice that
01940 // a key should be removed before freeing it.
01941 ACE_OS::thr_keyfree (key_info->key_);
01942 # else
01943 // don't bother to free the key
01944 this->remove (key_info->key_);
01945 # endif /* ACE_WIN32 */
01946 }
01947 # endif /* 0 */
01948 }
01949 }
|
|
|
Free all keys left in the table before destruction.
Definition at line 1952 of file OS.cpp. References ACE_thread_key_t, ACE_TSS_Info::key_, ACE_OS::NULL_key, and ACE_OS::thr_keyfree. Referenced by ACE_OS::cleanup_tss.
01957 {
01958 ACE_thread_key_t key_arr[ACE_DEFAULT_THREAD_KEYS];
01959 ACE_TSS_TABLE_ITERATOR key_info = table_;
01960 unsigned int idx = 0;
01961 unsigned int i;
01962
01963 for (i = 0;
01964 i < ACE_DEFAULT_THREAD_KEYS;
01965 ++key_info, ++i)
01966 #if defined (ACE_HAS_TSS_EMULATION)
01967 if (key_info->key_ != in_use_key_)
01968 #endif /* ACE_HAS_TSS_EMULATION */
01969 // Don't call ACE_OS::thr_keyfree () on ACE_TSS_Cleanup's own
01970 // key. See the comments in ACE_OS::thr_key_detach (): the key
01971 // doesn't get detached, so it will be in the table here.
01972 // However, there's no resource associated with it, so we don't
01973 // need to keyfree it. The dynamic memory associated with it
01974 // was already deleted by ACE_TSS_Cleanup::exit (), so we don't
01975 // want to access it again.
01976 key_arr [idx++] = key_info->key_;
01977
01978 for (i = 0; i < idx; i++)
01979 if (key_arr[i] != ACE_OS::NULL_key)
01980 #if defined (ACE_HAS_TSS_EMULATION)
01981 ACE_OS::thr_keyfree (key_arr[i]);
01982 #elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)
01983 // Don't call ACE_OS::thr_keyfree here. It will try to use
01984 // <in_use_> which has already been cleaned up here.
01985 ::tsd_delete (key_arr[i]);
01986 #else /* ACE_WIN32 */
01987 // Don't call ACE_OS::thr_keyfree here. It will try to use
01988 // <in_use_> which has already been cleaned up here.
01989 TlsFree (key_arr[i]);
01990 #endif /* ACE_HAS_TSS_EMULATION */
01991
01992 return 0;
01993 }
|
|
||||||||||||||||
|
Insert a <key, destructor> tuple into the table.
Definition at line 2035 of file OS.cpp. References ACE_KEY_INDEX, ACE_OS_TRACE, ACE_thread_key_t, ACE_TSS_CLEANUP_GUARD, and table_. Referenced by ACE_OS::thr_keycreate.
02038 {
02039 ACE_OS_TRACE ("ACE_TSS_Cleanup::insert");
02040 ACE_TSS_CLEANUP_GUARD
02041
02042 ACE_KEY_INDEX (key_index, key);
02043 if (key_index < ACE_DEFAULT_THREAD_KEYS)
02044 {
02045 table_[key_index] = ACE_TSS_Info (key, destructor, inst);
02046 return 0;
02047 }
02048 else
02049 {
02050 return -1;
02051 }
02052 }
|
|
|
Definition at line 2013 of file OS.cpp. References ACE_NEW_RETURN, ACE_OS_TRACE, ACE_TSS_CLEANUP_GUARD, and instance_. Referenced by ACE_OS::cleanup_tss, ACE_OS::thr_key_detach, ACE_OS::thr_key_used, ACE_OS::thr_keycreate, ACE_OS::thr_keyfree, and ACE_OS::thr_setspecific.
02014 {
02015 ACE_OS_TRACE ("ACE_TSS_Cleanup::instance");
02016
02017 // Create and initialize thread-specific key.
02018 if (ACE_TSS_Cleanup::instance_ == 0)
02019 {
02020 // Insure that we are serialized!
02021 ACE_TSS_CLEANUP_GUARD
02022
02023 // Now, use the Double-Checked Locking pattern to make sure we
02024 // only create the ACE_TSS_Cleanup instance once.
02025 if (ACE_TSS_Cleanup::instance_ == 0)
02026 ACE_NEW_RETURN (ACE_TSS_Cleanup::instance_,
02027 ACE_TSS_Cleanup,
02028 0);
02029 }
02030
02031 return ACE_TSS_Cleanup::instance_;
02032 }
|
|
|
Mark a key as being used by this thread.
Definition at line 2130 of file OS.cpp. References ACE_KEY_INDEX, ACE_thread_key_t, ACE_TSS_CLEANUP_GUARD, ACE_TSS_Info::key_in_use, table_, ACE_TSS_Keys::test_and_set, ACE_TSS_Info::thread_count_, and tss_keys. Referenced by ACE_OS::thr_key_used, and ACE_OS::thr_setspecific.
02131 {
02132 // If the key's ACE_TSS_Info in-use bit for this thread is not set,
02133 // set it and increment the key's thread_count_.
02134 if (! tss_keys ()->test_and_set (key))
02135 {
02136 ACE_TSS_CLEANUP_GUARD
02137
02138 // Retrieve the key's ACE_TSS_Info and increment its thread_count_.
02139 ACE_KEY_INDEX (key_index, key);
02140 ACE_TSS_Info &key_info = this->table_ [key_index];
02141 if (!key_info.key_in_use ())
02142 key_info.key_in_use (1);
02143 else
02144 ++key_info.thread_count_;
02145 }
02146 }
|
|
|
Indication of whether the ACE_TSS_CLEANUP_LOCK is usable, and therefore whether we are in static constructor/destructor phase or not.
Definition at line 1817 of file OS.cpp. References instance_. Referenced by ACE_OS::thr_key_detach.
01817 { return instance_ != 0; }
|
|
|
Remove a <key, destructor> tuple from the table.
Definition at line 2055 of file OS.cpp. References ACE_KEY_INDEX, ACE_OS_TRACE, ACE_thread_key_t, ACE_TSS_CLEANUP_GUARD, ACE_TSS_Info::destructor_, ACE_TSS_Info::key_, ACE_TSS_Info::key_in_use, ACE_OS::NULL_key, ACE_OS_Object_Manager::shutting_down, table_, ACE_TSS_Keys::test_and_clear, and tss_keys. Referenced by detach, exit, and ACE_OS::thr_keyfree.
02056 {
02057 ACE_OS_TRACE ("ACE_TSS_Cleanup::remove");
02058 ACE_TSS_CLEANUP_GUARD
02059
02060 ACE_KEY_INDEX (key_index, key);
02061 if (key_index < ACE_DEFAULT_THREAD_KEYS)
02062 {
02063 // "Remove" the TSS_Info table entry by zeroing out its key_ and
02064 // destructor_ fields. Also, keep track of the number threads
02065 // using the key.
02066 ACE_TSS_Info &info = this->table_ [key_index];
02067
02068 // Don't bother to test/clear the in "use bit" if the program is
02069 // shutting down. Doing so will cause a new ACE_TSS object to be
02070 // created again.
02071 if (!ACE_OS_Object_Manager::shutting_down ())
02072 tss_keys ()->test_and_clear (info.key_);
02073 info.key_in_use (0);
02074 info.key_ = ACE_OS::NULL_key;
02075 info.destructor_ = 0;
02076 return 0;
02077 }
02078 else
02079 return -1;
02080 }
|
|
|
Accessor for this threads ACE_TSS_Keys instance.
Definition at line 2161 of file OS.cpp. References ACE_NEW_RETURN, ACE_TSS_CLEANUP_GUARD, ACE_TSS_Cleanup_keys_destroyer, in_use_, ACE_OS::NULL_key, ACE_OS::thr_getspecific, ACE_OS::thr_keycreate, and ACE_OS::thr_setspecific. Referenced by exit, key_used, and remove.
02162 {
02163 if (in_use_ == ACE_OS::NULL_key)
02164 {
02165 ACE_TSS_CLEANUP_GUARD
02166 // Double-check;
02167 if (in_use_ == ACE_OS::NULL_key)
02168 {
02169 // Initialize in_use_ with a new key.
02170 if (ACE_OS::thr_keycreate (&in_use_,
02171 &ACE_TSS_Cleanup_keys_destroyer))
02172 return 0; // Major problems, this should *never* happen!
02173 }
02174 }
02175
02176 ACE_TSS_Keys *ts_keys = 0;
02177 if (ACE_OS::thr_getspecific (in_use_,
02178 ACE_reinterpret_cast (void **, &ts_keys)) == -1)
02179 return 0; // This should not happen!
02180
02181 if (ts_keys == 0)
02182 {
02183 ACE_NEW_RETURN (ts_keys,
02184 ACE_TSS_Keys,
02185 0);
02186 // Store the dynamically allocated pointer in thread-specific
02187 // storage.
02188 if (ACE_OS::thr_setspecific (in_use_,
02189 ACE_reinterpret_cast (void *,
02190 ts_keys)) == -1)
02191 {
02192 delete ts_keys;
02193 return 0; // Major problems, this should *never* happen!
02194 }
02195 }
02196
02197 return ts_keys;
02198 }
|
|
|
Key for the thread-specific array of whether each TSS key is in use.
Definition at line 1834 of file OS.cpp. Referenced by tss_keys. |
|
|
Pointer to the singleton instance.
Definition at line 1853 of file OS.cpp. Referenced by instance, lockable, and ~ACE_TSS_Cleanup. |
|
|
Table of <ACE_TSS_Info>'s.
Definition at line 1831 of file OS.cpp. Referenced by detach, dump, exit, insert, key_used, and remove. |
1.2.14 written by Dimitri van Heesch,
© 1997-2002