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. |
1.3.6