diff options
author | nw1 <nw1@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-10-20 19:19:34 +0000 |
---|---|---|
committer | nw1 <nw1@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-10-20 19:19:34 +0000 |
commit | 79c2cc2cde3626ae71b26d4a4226dcfa8691c487 (patch) | |
tree | 6f9298b4fa6810a3f6f57f35252b9e27195e4b04 | |
parent | 5a99875cf459e5cf8baa1e79f1c8a0af200bddc3 (diff) | |
download | ATCD-79c2cc2cde3626ae71b26d4a4226dcfa8691c487.tar.gz |
Changed to use double-linked list to hold the thread descriptor.
Changed to cache the pointer to thread descriptor in TSS instead
of caching some individual values.
-rw-r--r-- | ace/Containers.cpp | 203 | ||||
-rw-r--r-- | ace/Containers.h | 221 | ||||
-rw-r--r-- | ace/Containers.i | 99 | ||||
-rw-r--r-- | ace/Log_Msg.cpp | 32 | ||||
-rw-r--r-- | ace/Log_Msg.h | 28 | ||||
-rw-r--r-- | ace/Thread_Manager.cpp | 750 | ||||
-rw-r--r-- | ace/Thread_Manager.h | 322 | ||||
-rw-r--r-- | ace/Thread_Manager.i | 95 |
8 files changed, 690 insertions, 1060 deletions
diff --git a/ace/Containers.cpp b/ace/Containers.cpp index d77dc18511f..69e27ed76ea 100644 --- a/ace/Containers.cpp +++ b/ace/Containers.cpp @@ -631,34 +631,41 @@ ACE_Unbounded_Queue_Iterator<T>::next (T *&item) } //-------------------------------------------------- -#if defined (NANBOR_EXP_CODES) ACE_ALLOC_HOOK_DEFINE(ACE_Double_Linked_List_Iterator) template <class T> ACE_Double_Linked_List_Iterator<T>::ACE_Double_Linked_List_Iterator (ACE_Double_Linked_List<T> &dll) - : ACE_Double_Linked_List_Iterator_Base (dll) + : dllist_ (dll) { + this->current_ = dll.head_->next_; // Initialize head ptr. } -template <class T> ACE_DNode<T> * -ACE_Double_Linked_List_Iterator<T>::next (void) +template <class T> T * +ACE_Double_Linked_List_Iterator<T>::not_done (void) const { - return this->not_done (); + if (this->current_ != this->dllist_.head_) + return this->current_; + else + return 0; } -template <class T> int -ACE_Double_Linked_List_Iterator<T>::next (T *&item) +template <class T> T * +ACE_Double_Linked_List_Iterator<T>::do_advance (void) { - ACE_DNode<T> *ptr = this->not_done (); - - if (ptr != 0) + if (this->not_done ()) { - item = &ptr->item_; - return 1; + this->current_ = this->current_->next_; + return this->not_done (); } else - return 0; + return 0; +} + +template <class T> T * +ACE_Double_Linked_List_Iterator<T>::next (void) const +{ + return this->not_done (); } template <class T> int @@ -683,35 +690,34 @@ ACE_ALLOC_HOOK_DEFINE(ACE_Double_Linked_List) template <class T> ACE_Double_Linked_List<T>:: ACE_Double_Linked_List (ACE_Allocator *alloc) - : allocator_ (alloc) + : size_ (0), allocator_ (alloc) { if (this->allocator_ == 0) this->allocator_ = ACE_Allocator::instance (); - delete this->head_; ACE_NEW_MALLOC (this->head_, - (ACE_DNode<T>*) this->allocator_->malloc (sizeof (ACE_DNode<T>)), - ACE_DNode<T>); + (T *) this->allocator_->malloc (sizeof (T)), + T); this->init_head (); } template <class T> -ACE_Double_Linked_List<T>::ACE_Double_Linked_List (const ACE_Double_Linked_List<T> &cx) +ACE_Double_Linked_List<T>::ACE_Double_Linked_List (ACE_Double_Linked_List<T> &cx) : allocator_ (cx.allocator_) { if (this->allocator_ == 0) this->allocator_ = ACE_Allocator::instance (); ACE_NEW_MALLOC (this->head_, - (ACE_DNode<T>*) this->allocator_->malloc (sizeof (ACE_DNode<T>)), - ACE_DNode<T>); + (T *) this->allocator_->malloc (sizeof (T)), + T); this->init_head (); this->copy_nodes (cx); } template <class T> void -ACE_Double_Linked_List<T>::operator= (const ACE_Double_Linked_List<T> &cx) +ACE_Double_Linked_List<T>::operator= (ACE_Double_Linked_List<T> &cx) { if (this != &cx) { @@ -724,8 +730,8 @@ template <class T> ACE_Double_Linked_List<T>::~ACE_Double_Linked_List (void) { this->delete_nodes (); - ACE_DES_FREE_TEMPLATE (this->head_, this->allocator_->free, - ACE_DNode, <T>); + ACE_DES_FREE (this->head_, this->allocator_->free, + T); this->head_ = 0; } @@ -741,64 +747,45 @@ ACE_Double_Linked_List<T>::is_full (void) const return 0; // We have no bound. } -template <class T> ACE_DNode<T> * -ACE_Double_Linked_List<T>::insert_tail (const T &new_item) +template <class T> T * +ACE_Double_Linked_List<T>::insert_tail (T *new_item) { - ACE_DNode<T> *temp; - - // Create a new dummy node. - ACE_NEW_MALLOC_RETURN (temp, - (ACE_DNode<T>*) this->allocator_->malloc (sizeof (ACE_DNode<T>)), - ACE_DNode<T> (new_item), -1); - - this->insert_element (temp, 1); // Insert it before <head_>, i.e., at tail. - return 0; + // Insert it before <head_>, i.e., at tail. + this->insert_element (new_item, 1); + return new_item; } -template <class T> ACE_DNode<T> * -ACE_Double_Linked_List<T>::insert_head (const T &new_item) +template <class T> T * +ACE_Double_Linked_List<T>::insert_head (T *new_item) { - ACE_DNode<T> *temp; - - // Create a new dummy node. - ACE_NEW_MALLOC_RETURN (temp, - (ACE_DNode<T>*) this->allocator_->malloc (sizeof (ACE_DNode<T>)), - ACE_DNode<T> (new_item), -1); - - this->insert_element (temp); // Insert it after <head_>, i.e., at head. - return 0; + this->insert_element (new_item); // Insert it after <head_>, i.e., at head. + return new_item; } -template <class T> int -ACE_Double_Linked_List<T>::delete_head (T &item) +template <class T> T * +ACE_Double_Linked_List<T>::delete_head (void) { - ACE_DNode<T> *temp; + T *temp; if (this->is_empty ()) - return -1; + return 0; temp = this->head_->next_; - item = temp->item_; this->remove_element (temp); // Detach it from the list. - ACE_DES_FREE_TEMPLATE (temp, this->allocator_->free, - ACE_DNode, <T>); - return 0; + return temp; } -template <class T> int -ACE_Double_Linked_List<T>::delete_tail (T &item) +template <class T> T * +ACE_Double_Linked_List<T>::delete_tail (void) { - ACE_DNode<T> *temp; + T *temp; if (this->is_empty ()) - return -1; + return 0; temp = this->head_->prev_; - item = temp->item_; this->remove_element (temp); // Detach it from the list. - ACE_DES_FREE_TEMPLATE (temp, this->allocator_->free, - ACE_DNode, <T>); - return 0; + return temp; } template <class T> void @@ -808,33 +795,14 @@ ACE_Double_Linked_List<T>::reset (void) } template <class T> int -ACE_Double_Linked_List<T>::get (T *&item, size_t index = 0) const +ACE_Double_Linked_List<T>::get (T *&item, size_t index) { ACE_Double_Linked_List_Iterator<T> iter (*this); for (size_t i = 0; i < index && !iter.done (); i++, iter.advance ()) ; - if (iter.next (item)) - return 0; - else - return -1; -} -template <class T> int -ACE_Double_Linked_List<T>::set (const T &item, size_t index) -{ - ACE_Double_Linked_List_Iterator<T> iter (*this); - - for (size_t i = 0; i < index && !iter.done (); i++, iter.advance ()) - ; - ACE_DNode<T> *temp = iter.next (); - if (temp) - { - temp->item_ = item; - return 0; - } - else - return -1; + return ((item = iter.next ()) ? 0 : 1); } template <class T> size_t @@ -849,15 +817,16 @@ ACE_Double_Linked_List<T>::dump (void) const // Dump the state of an object. } -template <class T> ACE_DNode<T> * +#if 0 +template <class T> T * ACE_Double_Linked_List<T>::find (const T &item) { ACE_Double_Linked_List_Iterator<T> iter (*this); for (;!iter.done (); iter.advance ()) { - ACE_DNode<T> *temp = iter.next (); - if (temp->item_ == item) + T *temp = iter.next (); + if (*temp == item) return temp; } return 0; @@ -866,15 +835,16 @@ ACE_Double_Linked_List<T>::find (const T &item) template <class T> int ACE_Double_Linked_List<T>::remove (const T &item) { - ACE_DNode<T> *temp = this->find (item); + T *temp = this->find (item); if (temp != 0) return this->remove (temp); else return -1; } +#endif /* 0 */ template <class T> int -ACE_Double_Linked_List<T>::remove (ACE_DNode<T> *n) +ACE_Double_Linked_List<T>::remove (T *n) { return this->remove_element (n); } @@ -883,19 +853,56 @@ template <class T> void ACE_Double_Linked_List<T>::delete_nodes (void) { while (! this->is_empty ()) - this->remove_element (this->head_->next_); + { + T * temp = this->head_->next_; + this->remove_element (temp); + delete temp; + } } template <class T> void -ACE_Double_Linked_List<T>::copy_nodes (const ACE_Double_Linked_List<T> &c) +ACE_Double_Linked_List<T>::copy_nodes (ACE_Double_Linked_List<T> &c) { ACE_Double_Linked_List_Iterator<T> iter (c); for (; !iter.done (); iter.advance ()) - this->insert_head (iter.next ()->item_); + this->insert_head (new T (*iter.next ())); +} + +template <class T> void +ACE_Double_Linked_List<T>::init_head (void) +{ + this->head_->next_ = this->head_->prev_ = this->head_; +} + +template <class T> int +ACE_Double_Linked_List<T>::insert_element (T *new_item, + int before, + T *old_item) +{ + if (old_item == 0) + old_item = this->head_; + if (before) + old_item = old_item->prev_; + + (new_item->next_ = old_item->next_)->prev_ = new_item; + (new_item->prev_ = old_item)->next_ = new_item; + this->size_++; + return 0; // Well, what will cause errors here? } -#endif /* NANBOR_EXP_CODE */ +template <class T> int +ACE_Double_Linked_List<T>::remove_element (T *item) +{ + // Notice that you have to ensure that item is an element of this + // list. We can't do much checking here. + if (item == this->head_ || this->size () == 0) // Can't remove head + return -1; + (item->prev_->next_ = item->next_)->prev_ = item->prev_; + this->size_--; + return 0; +} + //-------------------------------------------------- ACE_ALLOC_HOOK_DEFINE(ACE_Fixed_Set) @@ -1337,24 +1344,30 @@ ACE_Node<T>::ACE_Node (const ACE_Node<T> &s) // ACE_TRACE ("ACE_Node<T>::ACE_Node"); } -#if defined (NANBOT_EXP_CODES) +#if 0 template <class T> ACE_DNode<T>::ACE_DNode (const T &i, ACE_DNode<T> *n, ACE_DNode<T> *p) - : ACE_DNode_Base (n, p), item_ (i) + : item_ (i), next_ (n), prev_ (p) { } template <class T> ACE_DNode<T>::ACE_DNode (const ACE_DNode<T> &i) - : ACE_DNode_Base (i.next_, i.prev_), item_ (i.item_) + : item_ (i.item_), next_ (i.next_), prev_ (i.prev_) +{ +} + +template <class T> T* +ACE_DNode<T>::item (void) { + return &this->item_; } template <class T> ACE_DNode<T>::~ACE_DNode (void) { } -#endif /* NANBOR_EXP_CODES */ +#endif /* 0 */ ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Set) diff --git a/ace/Containers.h b/ace/Containers.h index f065d07f754..72ecf381c04 100644 --- a/ace/Containers.h +++ b/ace/Containers.h @@ -197,127 +197,20 @@ private: // Current value of the item in this node. }; -#if defined (NANBOR_EXP_CODES) -class ACE_DNode_Base - // = TITLE - // Implement the minimum stuff a node in a double - // linked list should have. - // - // = DESCRIPTION - // Basic functionalities an element in double-linked - // lists. This is an abstract class and can't be - // instantiated. -{ - friend class ACE_Double_Linked_List_Iterator_Base; - friend class ACE_Double_Linked_List_Base; - -public: - ACE_DNode_Base (void); - // Default do nothing ctor. - - // ACE_DNode_Base (ACE_DNode_Base *n, ACE_DNode_Base *p); - // Build and set ctor. - -protected: - ACE_DNode_Base *prev_; - // Pointer to previous element in the list. - - ACE_DNode_Base *next_; - // Pointer to next element in the list. -}; - -class ACE_Double_Linked_List_Base; -// forward declaration - -class ACE_Double_Linked_List_Iterator_Base - // = TITLE - // Basic double-linked list iterator functionalities. - // - // = DESCRIPTION - // -{ -public: - ACE_Double_Linked_List_Iterator_Base - (ACE_Double_Linked_List_Base &dll); - // Constructor. - -protected: - ACE_DNode_Base *not_done (void) ; - // Check if we reach the end of the list. Can also be used to get - // the *current* element in the list. Return the address of the - // current item if there are still elements left , 0 if we run out of element. - - ACE_DNode_Base *do_advance (void); - // Advance to the next element in the list. Return the address of the - // next element if there are more, 0 otherwise. - - // @@ This function seems redundant. -// ACE_DNode_Base *next (void); -// // Get the next unvisit element from the list. Return address if succeed, -// // 0 otherwise. - - ACE_DNode_Base *current_; - // Remember where we are. - - ACE_Double_Linked_List_Base &dllist_; -}; - -class ACE_Double_Linked_List_Base - // = TITLE - // Basic double-linked list implementation. - // - // = DESCRIPTION - // This is a barebone implementation of double-linked lists. - // It only provide a minimum set of functionalities to - // work. You must subclass from it and other related classes - // for them to work correctly. -{ - friend class ACE_Double_Linked_List_Iterator_Base; - -public: - size_t size (void); - // Return current size of the list. - -protected: - // We hide these function here because they are not supposed to - // be used directly. Notice that all these functions have only - // limited error detections. - - ACE_Double_Linked_List_Base (void); - // Default ctor. - - void init_head (void); - // Setup header pointer. Called after we create the head node in ctor. - - int insert_element (ACE_DNode_Base *new_item, - int before = 0, - ACE_DNode_Base *old_item = 0); - // Insert a <new_element> into the list. It will be added before - // or after <old_item>. Default is to insert the new item *after* - // <head_>. Return 0 if succeed, -1 if error occured. - - int remove_element (ACE_DNode_Base *item); - // Remove an <item> from the list. Return 0 if succeed, -1 otherwise. - // Notice that this function only checks if item is <head_>. Users - // must ensure the item is in the list. - - ACE_Double_Linked_List_Iterator_Base *iter (void); - // Iterator factory. - - ACE_DNode_Base *head_; - // Head of the circular double-linked list. - - size_t size_; - // Size of this list. -}; +#if 0 +// Forward declaration. +template <class T> class ACE_Double_Linked_List; +template <class T> class ACE_Double_Linked_List_Iterator; template <class T> -class ACE_DNode : public ACE_DNode_Base +class ACE_DNode // = TITLE // Implementation element in a Double-linked List. { friend class ACE_Double_Linked_List<T>; friend class ACE_Double_Linked_List_Iterator<T>; +public: + T* item (); protected: ACE_DNode (const T &i, ACE_DNode<T> *n = 0, ACE_DNode<T> *p = 0); ACE_DNode (const ACE_DNode<T> &i); @@ -325,8 +218,14 @@ protected: ~ACE_DNode (void); T item_; + + ACE_DNode *prev_; + // Pointer to previous element in the list. + + ACE_DNode *next_; + // Pointer to next element in the list. }; -#endif /* NANBOR_EXP_CODES */ +#endif /* 0 */ template <class T> class ACE_Unbounded_Stack @@ -580,7 +479,6 @@ protected: // Allocation Strategy of the queue. }; -#if defined (NANBOR_EXP_CODES) template <class T> class ACE_Double_Linked_List; @@ -593,7 +491,9 @@ class ACE_Double_Linked_List_Iterator // Iterate thru the double-linked list. This class provide // an interface that let users access the internal element // addresses directly, which (IMHO) seems to break the - // encasulation. + // encasulation. Notice <class T> must delcare + // ACE_Double_Linked_List<T> and + // ACE_Double_Linked_List_Iterator as friend classes. { public: // = Initialization method. @@ -601,14 +501,10 @@ public: // = Iteration methods. - ACE_DNode<T> *next (void); + T *next (void) const; // Return the address of next (current) unvisited ACE_DNode, // 0 if there is no more element available. - int next (T *&next_item); - // Pass back the <next_item> that hasn't been seen in the Stack. - // Returns 0 when all items have been seen, else 1. - int advance (void); // Move forward by one element in the Stack. Returns 0 when all the // items in the Stack have been seen, else 1. @@ -621,6 +517,22 @@ public: ACE_ALLOC_HOOK_DECLARE; // Declare the dynamic allocation hooks. + +protected: + T *not_done (void) const ; + // Check if we reach the end of the list. Can also be used to get + // the *current* element in the list. Return the address of the + // current item if there are still elements left , 0 if we run out + // of element. + + T *do_advance (void); + // Advance to the next element in the list. Return the address of the + // next element if there are more, 0 otherwise. + + T *current_; + // Remember where we are. + + ACE_Double_Linked_List<T> &dllist_; }; @@ -630,9 +542,10 @@ class ACE_Double_Linked_List // A double-linked list implementation. // // = DESCRIPTION - // This implementation of an unbounded double-linked list uses a circular - // linked list with a dummy node. It is pretty much like the ACE_Unbounded_Queue - // except that it allows removing of a specific element from a specific location. + // This implementation of an unbounded double-linked list uses a + // circular linked list with a dummy node. It is pretty much + // like the ACE_Unbounded_Queue except that it allows removing + // of a specific element from a specific location. { friend class ACE_Double_Linked_List_Iterator<T>; public: @@ -641,10 +554,10 @@ public: // construction. Use user specified allocation strategy // if specified. - ACE_Double_Linked_List (const ACE_Double_Linked_List<T> &); + ACE_Double_Linked_List (ACE_Double_Linked_List<T> &); // Copy constructor. - void operator= (const ACE_Double_Linked_List<T> &); + void operator= (ACE_Double_Linked_List<T> &); // Assignment operator. ~ACE_Double_Linked_List (void); @@ -660,56 +573,54 @@ public: // = Classic queue operations. - ACE_DNode<T> *insert_tail (const T &new_item); + T *insert_tail (T *new_item); // Adds <new_item> to the tail of the list. Returns 0 on success, // -1 on failure. - ACE_DNode<T> *insert_head (const T &new_item); + T *insert_head (T *new_item); // Adds <new_item> to the head of the list. Returns 0 on success, // -1 on failure. - int delete_head (T &item); + T* delete_head (void); // Removes and returns the first <item> in the list. Returns 0 on - // success, -1 if the queue was empty. This method will free the + // success, -1 if the queue was empty. This method will *not* free the // internal node. - int delete_tail (T &item); + T *delete_tail (void); // Removes and returns the last <item> in the list. Returns 0 on - // success, -1 if the queue was empty. This method will free the + // success, -1 if the queue was empty. This method will *not* free the // internal node. // = Additional utility methods. void reset (void); // Reset the <ACE_Double_Linked_List> to be empty. + // Notice that since no one is interested in the items within, + // This operation will delete all items. - int get (T *&item, size_t index = 0) const; + int get (T *&item, size_t index = 0); // Get the <index>th element in the set. Returns -1 if the element // isn't in the range <0..size() - 1>, else 0. - int set (const T &item, size_t index); - // Set the <index>th element in the set. Will pad out the set with - // empty nodes if <index> is beyond the range <0..size() - 1>. - // Returns -1 on failure, 0 if <index> isn't initially in range, and - // 0 otherwise. - size_t size (void) const; // The number of items in the queue. void dump (void) const; // Dump the state of an object. - ACE_DNode<T> *find (const T &item); +#if 0 + T *find (const T &item); // Locate the DNode address that contains the item. Return // an address if succeed, 0 otherwise. - int remove (const T &item); + T *remove (const T &item); // This function will iterate thru the double-linked list and remove // it from the list. Return Node address if succeed, 0 otherwise. // Notice that this method will *not* free the internal node. The // node is simple unlinked from the list. +#endif /* 0 */ - int remove (ACE_DNode<T> *n); + int remove (T *n); // Use DNode address directly. ACE_ALLOC_HOOK_DECLARE; @@ -719,13 +630,33 @@ protected: void delete_nodes (void); // Delete all the nodes in the list. - void copy_nodes (const ACE_Double_Linked_List<T> &); + void copy_nodes (ACE_Double_Linked_List<T> &); // Copy nodes into this list. + void init_head (void); + // Setup header pointer. Called after we create the head node in ctor. + + int insert_element (T *new_item, + int before = 0, + T *old_item = 0); + // Insert a <new_element> into the list. It will be added before + // or after <old_item>. Default is to insert the new item *after* + // <head_>. Return 0 if succeed, -1 if error occured. + + int remove_element (T *item); + // Remove an <item> from the list. Return 0 if succeed, -1 otherwise. + // Notice that this function only checks if item is <head_>. Users + // must ensure the item is in the list. + + T *head_; + // Head of the circular double-linked list. + + size_t size_; + // Size of this list. + ACE_Allocator *allocator_; // Allocation Strategy of the queue. }; -#endif /* NANBOR_EXP_CODES */ template <class T> class ACE_Unbounded_Set_Iterator diff --git a/ace/Containers.i b/ace/Containers.i index e352695e692..abc7a7da958 100644 --- a/ace/Containers.i +++ b/ace/Containers.i @@ -123,105 +123,6 @@ ACE_Fixed_Stack<T, SIZE>::size (void) const return this->size_; } -//---------------------------------------- -#if defined (NANBOR_EXP_CODES) -ACE_INLINE -ACE_DNode_Base::ACE_DNode_Base (void) -{ -} - -// ACE_INLINE -// ACE_DNode_Base::ACE_DNode_Base (ACE_DNode_Base *n, ACE_DNode_Base *p) -// : next_ (n), prev_ (p) -// { -// } - -ACE_INLINE -ACE_Double_Linked_List_Iterator_Base::ACE_Double_Linked_List_Iterator_Base -(ACE_Double_Linked_List_Base &dll) - : dllist_ (dll) -{ - this->current_ = dll.head_->next_; // Initialize head ptr. -} - -ACE_INLINE ACE_DNode_Base * -ACE_Double_Linked_List_Iterator_Base::not_done (void) -{ - if (this->current_ != this->dllist_.head_) - return this->current_; - else - return 0; -} - -ACE_INLINE ACE_DNode_Base * -ACE_Double_Linked_List_Iterator_Base::do_advance (void) -{ - if (this->not_done ()) - { - this->current_ = this->current_->next_; - return this->not_done (); - } - else - return 0; -} - -ACE_INLINE -ACE_Double_Linked_List_Base::ACE_Double_Linked_List_Base (void) - : head_ (0), size_ (0) -{ -} - -ACE_INLINE void -ACE_Double_Linked_List_Base::init_head (void) -{ - this->head_->next_ = this->head_->prev_ = this->head_; -} - -ACE_INLINE size_t -ACE_Double_Linked_List_Base::size (void) -{ - return this->size_; -} - -ACE_INLINE int -ACE_Double_Linked_List_Base::insert_element (ACE_DNode_Base *new_item, - int before, - ACE_DNode_Base *old_item) -{ - if (old_item == 0) - old_item = this->head_; - if (before) - old_item = old_item->prev_; - - (new_item->next_ = old_item->next_)->prev_ = new_item; - (new_item->prev_ = old_item)->next_ = new_item; - this->size_++; - return 0; // Well, what will cause errors here? -} - -ACE_INLINE int -ACE_Double_Linked_List_Base::remove_element (ACE_DNode_Base *item) -{ - // Notice that you have to ensure that item is an element of this - // list. We can't do much checking here. - if (item == this->head_ || this->size () == 0) // Can't remove head - return -1; - (item->prev_->next_ = item->next_)->prev_ = item->prev_; - this->size_--; - return 0; -} - -ACE_INLINE ACE_Double_Linked_List_Iterator_Base * -ACE_Double_Linked_List_Base::iter (void) -{ - ACE_Double_Linked_List_Iterator_Base *itr; - ACE_NEW_RETURN (itr, ACE_Double_Linked_List_Iterator_Base (*this), 0); - return itr; -} - -#endif /* NANBOR_EXP_CODES */ -//---------------------------------------- - template <class T> ACE_INLINE int ACE_Unbounded_Stack<T>::is_empty (void) const { diff --git a/ace/Log_Msg.cpp b/ace/Log_Msg.cpp index 7f033aa03c6..3ae3fa9303c 100644 --- a/ace/Log_Msg.cpp +++ b/ace/Log_Msg.cpp @@ -21,7 +21,7 @@ #include "ace/ACE.h" #endif /* !ACE_HAS_INLINED_OSCALLS */ -#include "ace/Thread.h" +#include "ace/Thread_Manager.h" #include "ace/Synch_T.h" #include "ace/Signal.h" #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) @@ -374,10 +374,9 @@ ACE_Log_Msg::ACE_Log_Msg (void) restart_ (1), // Restart by default... ostream_ (0), trace_depth_ (0), - thr_handle_ (0), trace_active_ (0), tracing_enabled_ (1), // On by default? - thr_state_ (0), + thr_desc_ (0), priority_mask_ (LM_SHUTDOWN // By default, all priorities are enabled. | LM_TRACE | LM_DEBUG @@ -986,8 +985,9 @@ ACE_Log_Msg::dump (void) const ACE_DEBUG ((LM_DEBUG, "\trace_active_ = %d\n", this->trace_active_)); ACE_DEBUG ((LM_DEBUG, "\tracing_enabled_ = %d\n", this->tracing_enabled_)); ACE_DEBUG ((LM_DEBUG, "\npriority_mask_ = %d\n", this->priority_mask_)); - if (this->thr_state_ != 0) - ACE_DEBUG ((LM_DEBUG, "\thr_state_ = %d\n", *this->thr_state_)); + if (this->thr_desc ()->state () != 0) + ACE_DEBUG ((LM_DEBUG, "\thr_state_ = %d\n", + this->thr_desc ()->state ())); ACE_DEBUG ((LM_DEBUG, "\nmsg_off_ = %d\n", this->msg_off_)); ACE_Log_Msg_message_queue->dump (); @@ -1081,28 +1081,16 @@ ACE_Log_Msg::trace_active (int value) this->trace_active_ = value; } -ACE_Thread_State * -ACE_Log_Msg::thr_state (void) +ACE_Thread_Descriptor * +ACE_Log_Msg::thr_desc (void) const { - return this->thr_state_; + return this->thr_desc_; } void -ACE_Log_Msg::thr_state (ACE_Thread_State *ts) +ACE_Log_Msg::thr_desc (ACE_Thread_Descriptor *td) { - this->thr_state_ = ts; -} - -ACE_hthread_t * -ACE_Log_Msg::thr_handle (void) -{ - return this->thr_handle_; -} - -void -ACE_Log_Msg::thr_handle (ACE_hthread_t *th) -{ - this->thr_handle_ = th; + this->thr_desc_ = td; } // Enable the tracing facility on a per-thread basis. diff --git a/ace/Log_Msg.h b/ace/Log_Msg.h index b6722b78f6d..81e9e652af7 100644 --- a/ace/Log_Msg.h +++ b/ace/Log_Msg.h @@ -100,6 +100,10 @@ #define ACE_LOG_MSG ACE_Log_Msg::instance () +// Forward declaration + +class ACE_Thread_Descriptor; + class ACE_Export ACE_Log_Msg // = TITLE // Provides a variable length argument message logging @@ -235,13 +239,9 @@ public: int trace_active (void); void trace_active (int value); - // = Get/set the current thread state. - ACE_Thread_State *thr_state (void); - void thr_state (ACE_Thread_State *); - - // = Get/set the current thread ACE_hthread_t. - ACE_hthread_t *thr_handle (void); - void thr_handle (ACE_hthread_t *); + // = Get/set the current thread descriptor. + ACE_Thread_Descriptor *thr_desc (void) const; + void thr_desc (ACE_Thread_Descriptor *); // = Stop/start/query tracing status on a per-thread basis... void stop_tracing (void); @@ -340,23 +340,17 @@ private: int trace_depth_; // Depth of the nesting for printing traces. - ACE_hthread_t *thr_handle_; - // If we're running in the context of an <ACE_Thread_Manager> this - // will point to the <thr_handle_> field in the - // <ACE_Thread_Descriptor>. Threads can use this to rapidly - // determine their real ACE_hthread_t. - int trace_active_; // Are we already within an ACE_Trace constructor call? int tracing_enabled_; // Are we allowing tracing in this thread? - ACE_Thread_State *thr_state_; + ACE_Thread_Descriptor *thr_desc_; // If we're running in the context of an <ACE_Thread_Manager> this - // will point to the <thr_state_> field in the - // <ACE_Thread_Descriptor>. Threads can use this to rapidly - // determine if they've got a cancellation pending. + // will point to the thread descriptor adapter which holds the + // thread descriptor of the thread. This can be used to repidly + // access all thread data kept in <ACE_Thread_Descriptor>. u_long priority_mask_; // Keeps track of all the <ACE_Log_Priority> values that are diff --git a/ace/Thread_Manager.cpp b/ace/Thread_Manager.cpp index 9c03885b962..821ad6e9778 100644 --- a/ace/Thread_Manager.cpp +++ b/ace/Thread_Manager.cpp @@ -22,7 +22,7 @@ ACE_Thread_Manager *ACE_Thread_Manager::thr_mgr_ = 0; int ACE_Thread_Manager::delete_thr_mgr_ = 0; void -ACE_Thread_Manager::dump (void) const +ACE_Thread_Manager::dump (void) { ACE_TRACE ("ACE_Thread_Manager::dump"); // Cast away const-ness of this in order to use its non-const lock_. @@ -32,11 +32,12 @@ ACE_Thread_Manager::dump (void) const ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); ACE_DEBUG ((LM_DEBUG, "\ngrp_id_ = %d", this->grp_id_)); - ACE_DEBUG ((LM_DEBUG, "\nmax_table_size_ = %d", this->max_table_size_)); - ACE_DEBUG ((LM_DEBUG, "\ncurrent_count_ = %d", this->current_count_)); + ACE_DEBUG ((LM_DEBUG, "\ncurrent_count_ = %d", this->thr_list_.size ())); - for (size_t i = 0; i < this->current_count_; i++) - this->thr_table_[i].dump (); + ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> + iter (this->thr_list_); + for (; ! iter.done (); iter.advance ()) + iter.next ()->dump (); ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); } @@ -88,116 +89,79 @@ ACE_Thread_Descriptor::ACE_Thread_Descriptor (void) // The following macro simplifies subsequence code. #define ACE_FIND(OP,INDEX) \ - int INDEX = OP; \ - if (INDEX == -1) return -1 + ACE_Thread_Descriptor *INDEX = OP; \ -int -ACE_Thread_Manager::thread_descriptor (ACE_thread_t thr_id, - ACE_Thread_Descriptor &descriptor) -{ - ACE_TRACE ("ACE_Thread_Manager::thread_descriptor"); - ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); - - ACE_FIND (this->find_thread (thr_id), index); - descriptor = this->thr_table_[index]; - return 0; -} - - -int -ACE_Thread_Manager::hthread_descriptor (ACE_hthread_t thr_handle, - ACE_Thread_Descriptor &descriptor) -{ - // @@ This will probably not work right on Win32 for app. programmers since - // the Thread_Manager now returns a "duplicated handle" and it's not - // the one stored in the thread descriptor table. Therefore, be sure to - // use the thread handle inside thread manager, not the one returned by - // thread manager. - - ACE_TRACE ("ACE_Thread_Manager::hthread_descriptor"); - ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); - - ACE_FIND (this->find_hthread (thr_handle), index); - descriptor = this->thr_table_[index]; - return 0; -} - -// Return the thread descriptor (indexed by ACE_hthread_t). - -int -ACE_Thread_Manager::thr_self (ACE_hthread_t &self) +ACE_Thread_Descriptor * +ACE_Thread_Manager::thread_desc_self (void) { - // @@ We can get this information from TSS directly after my change. + // This method must be called with lock held. - ACE_TRACE ("ACE_Thread_Manager::thr_self"); - ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); - - // Try to get the cached HANDLE out of TSS to avoid lookup. - ACE_hthread_t *handle = ACE_LOG_MSG->thr_handle (); + // Try to get it from cache. + ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc (); // Wasn't in the cache, so we'll have to look it up and cache it. - if (handle == 0) - { + if (desc == 0) + { ACE_thread_t id = ACE_OS::thr_self (); + + desc = this->find_thread (id); - ACE_FIND (this->find_thread (id), index); - handle = &this->thr_table_[index].thr_handle_; - - // Update the TSS cache. - ACE_LOG_MSG->thr_handle (handle); - } - self = *handle; - return 0; + if (desc != 0) // thread descriptor adapter might not have been + // put into the list yet. + // Update the TSS cache. + ACE_LOG_MSG->thr_desc (desc); + } + return desc; } -int -ACE_Thread_Manager::resize (size_t size) +ACE_Thread_Descriptor * +ACE_Thread_Manager::thread_descriptor (ACE_thread_t thr_id) { - // @@ We probably won't need this anymore after changing to use TSS. - - ACE_TRACE ("ACE_Thread_Manager::resize"); - ACE_Thread_Descriptor *temp; - - ACE_NEW_RETURN (temp, ACE_Thread_Descriptor[size], -1); - - for (size_t i = 0; i < this->max_table_size_; i++) - temp[i] = this->thr_table_[i]; // Structure assignment. + ACE_TRACE ("ACE_Thread_Manager::thread_descriptor"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); - this->max_table_size_ = size; + ACE_FIND (this->find_thread (thr_id), ptr); + return ptr; +} - delete [] this->thr_table_; - this->thr_table_ = temp; +ACE_Thread_Descriptor * +ACE_Thread_Manager::hthread_descriptor (ACE_hthread_t thr_handle) +{ + ACE_TRACE ("ACE_Thread_Manager::hthread_descriptor"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); - return 0; + ACE_FIND (this->find_hthread (thr_handle), ptr); + return ptr; } -// Create and initialize the table to keep track of the thread pool. +// Return the thread descriptor (indexed by ACE_hthread_t). -int -ACE_Thread_Manager::open (size_t size) +int +ACE_Thread_Manager::thr_self (ACE_hthread_t &self) { - ACE_TRACE ("ACE_Thread_Manager::open"); + ACE_TRACE ("ACE_Thread_Manager::thr_self"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); - if (this->max_table_size_ < size) - this->resize (size); + ACE_Thread_Descriptor *desc = + this->thread_desc_self (); + + if (desc == 0) + return -1; + else + desc->self (self); + return 0; } // Initialize the synchronization variables. -ACE_Thread_Manager::ACE_Thread_Manager (size_t size) - : thr_table_ (0), - max_table_size_ (0), - current_count_ (0), - grp_id_ (1) +ACE_Thread_Manager::ACE_Thread_Manager (void) + : grp_id_ (1) #if defined (ACE_HAS_THREADS) , zero_cond_ (lock_) #endif /* ACE_HAS_THREADS */ { ACE_TRACE ("ACE_Thread_Manager::ACE_Thread_Manager"); - if (this->open (size) == -1) - ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Thread_Manager")); } ACE_Thread_Manager * @@ -260,13 +224,9 @@ ACE_Thread_Manager::close (void) ACE_TRACE ("ACE_Thread_Manager::close"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); - if (this->thr_table_ != 0) - { - delete [] this->thr_table_; - this->thr_table_ = 0; - this->max_table_size_ = 0; - this->current_count_ = 0; - } + // @@ Clear out thr_list_ here. Have to iterate thru each of + // list entry. + return 0; } @@ -280,7 +240,7 @@ ACE_Thread_Manager::~ACE_Thread_Manager (void) extern "C" void ACE_Thread_Exit_cleanup (void *instance, void *) { - ACE_TRACE ("ACE_Thread_Exit::cleanup"); + ACE_TRACE ("ACE_Thread_Exit_cleanup"); delete (ACE_TSS_TYPE (ACE_Thread_Exit) *) instance; } @@ -311,13 +271,13 @@ ACE_Thread_Exit::instance (void) if (instance_ == 0) { ACE_MT (ACE_Thread_Mutex *lock = - ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object - (ACE_Object_Manager::ACE_THREAD_EXIT_LOCK); - ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *lock, 0)); + ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object + (ACE_Object_Manager::ACE_THREAD_EXIT_LOCK); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *lock, 0)); if (instance_ == 0) { - ACE_NEW_RETURN (instance_, ACE_TSS_TYPE (ACE_Thread_Exit), 0); + ACE_NEW_RETURN (instance_, ACE_TSS_TYPE (ACE_Thread_Exit), 0); // Register for destruction with ACE_Object_Manager. #if defined ACE_HAS_SIG_C_FUNC @@ -421,7 +381,7 @@ ace_thread_manager_adapter (void *args) ACE_Thread_Adapter *thread_args = (ACE_Thread_Adapter *) args; - // NOTE: this preprocessor directive should match the one in above + // NOTE: this preprocessor directive should match the one in above // ACE_Thread_Exit::instance (). With the Xavier Pthreads package, // the exit_hook in TSS causes a seg fault. So, this works around // that by creating exit_hook on the stack. @@ -445,6 +405,12 @@ ace_thread_manager_adapter (void *args) // <exit_hook>. exit_hook.thr_mgr (thread_args->thr_mgr ()); + // @@@@@@@@@@ Try to insert thread descriptor here. Notice we can't guarantee + // whether this thread or the main thread will insert thread descriptor first, + // we'll need to check whether there is already an entry in the list. If it does, + // we'll just bail out without addind anything. Otherwise, add an entry with + // only thread_id field filled. + // Invoke the user-supplied function with the args. void *status = thread_args->invoke (); @@ -462,15 +428,15 @@ ace_thread_manager_adapter (void *args) // @@ Consider duping the handles so that users can have something // to manipulate if they want. -int -ACE_Thread_Manager::spawn_i (ACE_THR_FUNC func, - void *args, - long flags, - ACE_thread_t *t_id, +int +ACE_Thread_Manager::spawn_i (ACE_THR_FUNC func, + void *args, + long flags, + ACE_thread_t *t_id, ACE_hthread_t *t_handle, long priority, int grp_id, - void *stack, + void *stack, size_t stack_size, ACE_Task_Base *task) { @@ -512,20 +478,26 @@ ACE_Thread_Manager::spawn_i (ACE_THR_FUNC func, // @@ How are thread handles implemented on AIX? Do they // also need to be duplicated? if (t_handle != 0) - (void) ::DuplicateHandle (::GetCurrentProcess (), + (void) ::DuplicateHandle (::GetCurrentProcess (), thr_handle, ::GetCurrentProcess (), t_handle, - 0, + 0, TRUE, DUPLICATE_SAME_ACCESS); #else ACE_UNUSED_ARG (t_handle); #endif /* ACE_HAS_WTHREADS */ + + // @@@@@@@@@@ Try to insert thread descriptor here. Notice we can't guarantee + // whether this thread or the main thread will insert thread descriptor first, + // we'll need to check whether there is already an entry in the list. If there + // is, then, the spawned thread has got ahead of us. We'll still need to fill + // in the blanks. return this->append_thr (*t_id, - thr_handle, - ACE_THR_SPAWNED, + thr_handle, + ACE_THR_SPAWNED, grp_id, task, flags); @@ -535,15 +507,15 @@ ACE_Thread_Manager::spawn_i (ACE_THR_FUNC func, // Create a new thread running <func>. *Must* be called with the // <lock_> held... -int -ACE_Thread_Manager::spawn (ACE_THR_FUNC func, - void *args, - long flags, - ACE_thread_t *t_id, +int +ACE_Thread_Manager::spawn (ACE_THR_FUNC func, + void *args, + long flags, + ACE_thread_t *t_id, ACE_hthread_t *t_handle, long priority, int grp_id, - void *stack, + void *stack, size_t stack_size) { ACE_TRACE ("ACE_Thread_Manager::spawn"); @@ -552,7 +524,7 @@ ACE_Thread_Manager::spawn (ACE_THR_FUNC func, if (grp_id == -1) grp_id = this->grp_id_++; // Increment the group id. - if (this->spawn_i (func, args, flags, t_id, t_handle, + if (this->spawn_i (func, args, flags, t_id, t_handle, priority, grp_id, stack, stack_size) == -1) return -1; else @@ -561,10 +533,10 @@ ACE_Thread_Manager::spawn (ACE_THR_FUNC func, // Create N new threads running FUNC. -int -ACE_Thread_Manager::spawn_n (size_t n, - ACE_THR_FUNC func, - void *args, +int +ACE_Thread_Manager::spawn_n (size_t n, + ACE_THR_FUNC func, + void *args, long flags, long priority, int grp_id, @@ -585,9 +557,9 @@ ACE_Thread_Manager::spawn_n (size_t n, args, flags, 0, - thread_handles == 0 ? 0 : &thread_handles[i], + thread_handles == 0 ? 0 : &thread_handles[i], priority, - grp_id, + grp_id, 0, 0, task) == -1) @@ -599,12 +571,12 @@ ACE_Thread_Manager::spawn_n (size_t n, // Create N new threads running FUNC. -int +int ACE_Thread_Manager::spawn_n (ACE_thread_t thread_ids[], - size_t n, - ACE_THR_FUNC func, + size_t n, + ACE_THR_FUNC func, void *args, - long flags, + long flags, long priority, int grp_id, void *stack[], @@ -621,14 +593,14 @@ ACE_Thread_Manager::spawn_n (ACE_thread_t thread_ids[], { // @@ What should happen if this fails?! e.g., should we try to // cancel the other threads that we've already spawned or what? - if (this->spawn_i (func, - args, - flags, - thread_ids == 0 ? 0 : &thread_ids[i], - thread_handles == 0 ? 0 : &thread_handles[i], - priority, - grp_id, - stack == 0 ? 0 : stack[i], + if (this->spawn_i (func, + args, + flags, + thread_ids == 0 ? 0 : &thread_ids[i], + thread_handles == 0 ? 0 : &thread_handles[i], + priority, + grp_id, + stack == 0 ? 0 : stack[i], stack_size == 0 ? 0 : stack_size[i]) == -1) return -1; } @@ -640,12 +612,12 @@ ACE_Thread_Manager::spawn_n (ACE_thread_t thread_ids[], // Must be called with locks held. int -ACE_Thread_Manager::append_thr (ACE_thread_t t_id, +ACE_Thread_Manager::append_thr (ACE_thread_t t_id, ACE_hthread_t t_handle, ACE_Thread_State thr_state, int grp_id, ACE_Task_Base *task, - long flags) + long flags) { ACE_TRACE ("ACE_Thread_Manager::append_thr"); // @@ This code will need to be replaced with a loop that will @@ -655,85 +627,80 @@ ACE_Thread_Manager::append_thr (ACE_thread_t t_id, // Note that at some point we should use an "in situ" free list that // is woven through the table... - // Try to resize the array to twice its existing size if we run out - // of space... - if (this->current_count_ >= this->max_table_size_ - && this->resize (this->max_table_size_ * 2) == -1) - return -1; - else - { - ACE_Thread_Descriptor &thr_desc = - this->thr_table_[this->current_count_]; - - thr_desc.thr_id_ = t_id; - thr_desc.thr_handle_ = t_handle; - thr_desc.grp_id_ = grp_id; - thr_desc.thr_state_ = thr_state; - thr_desc.task_ = task; - thr_desc.cleanup_info_.cleanup_hook_ = 0; - thr_desc.cleanup_info_.object_ = 0; - thr_desc.cleanup_info_.param_ = 0; - thr_desc.flags_ = flags; - - this->current_count_++; - return 0; - } + // Create a new thread descriptor entry. + ACE_Thread_Descriptor *thr_desc; + ACE_NEW_RETURN (thr_desc, ACE_Thread_Descriptor, -1); + + thr_desc->thr_id_ = t_id; + thr_desc->thr_handle_ = t_handle; + thr_desc->grp_id_ = grp_id; + thr_desc->thr_state_ = thr_state; + thr_desc->task_ = task; + thr_desc->cleanup_info_.cleanup_hook_ = 0; + thr_desc->cleanup_info_.object_ = 0; + thr_desc->cleanup_info_.param_ = 0; + thr_desc->flags_ = flags; + + this->thr_list_.insert_head (thr_desc); + return 0; } // Return the thread descriptor (indexed by ACE_hthread_t). -int +ACE_Thread_Descriptor * ACE_Thread_Manager::find_hthread (ACE_hthread_t h_id) { - ACE_TRACE ("ACE_Thread_Descriptor::find_hthread"); - - for (size_t i = 0; i < this->current_count_; i++) - if (ACE_OS::thr_cmp (h_id, this->thr_table_[i].thr_handle_)) - return i; + ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> + iter (this->thr_list_); - return -1; + for ( ; ! iter.done (); iter.advance ()) + if (iter.next ()->thr_handle_ == h_id) + return iter.next (); + return 0; } // Locate the index in the table associated with <t_id>. Must be // called with the lock held. -int +ACE_Thread_Descriptor * ACE_Thread_Manager::find_thread (ACE_thread_t t_id) { ACE_TRACE ("ACE_Thread_Manager::find_thread"); - for (size_t i = 0; i < this->current_count_; i++) - if (ACE_OS::thr_equal (t_id, this->thr_table_[i].thr_id_)) - return i; + ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> + iter (this->thr_list_); - return -1; + for (; ! iter.done (); iter.advance ()) + if (iter.next ()->thr_id_ == t_id) + return iter.next (); + return 0; } // Insert a thread into the pool (checks for duplicates and doesn't // allow them to be inserted twice). int -ACE_Thread_Manager::insert_thr (ACE_thread_t t_id, +ACE_Thread_Manager::insert_thr (ACE_thread_t t_id, ACE_hthread_t t_handle, int grp_id, - long flags) + long flags) { ACE_TRACE ("ACE_Thread_Manager::insert_thr"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); // Check for duplicates and bail out if we're already registered... - if (this->find_thread (t_id) != -1) + if (this->find_thread (t_id) != 0 ) return -1; if (grp_id == -1) grp_id = this->grp_id_++; - + if (this->append_thr (t_id, - t_handle, + t_handle, ACE_THR_SPAWNED, grp_id, - 0, - flags) == -1) + 0, + flags) == -1) return -1; else return grp_id; @@ -750,14 +717,16 @@ ACE_Thread_Manager::run_thread_exit_hooks (int i) // @@ Currently, we have just one hook. This should clearly be // generalized to support an arbitrary number of hooks. - if (this->thr_table_[i].cleanup_info_.cleanup_hook_ != 0) + ACE_Thread_Descriptor *td = this->thread_desc_self (); + if (td != 0 && td->cleanup_info.cleanup_hook_ != 0) { - (*this->thr_table_[i].cleanup_info_.cleanup_hook_) - (this->thr_table_[i].cleanup_info_.object_, - this->thr_table_[i].cleanup_info_.param_); + (*td->cleanup_info_.cleanup_hook_) + (td->cleanup_info_.object_, + td->cleanup_info_.param_); - this->thr_table_[i].cleanup_info_.cleanup_hook_ = 0; + td->cleanup_info_.cleanup_hook_ = 0; } + ACE_UNUSED_ARG (i); #else ACE_UNUSED_ARG (i); #endif // 0 @@ -766,45 +735,41 @@ ACE_Thread_Manager::run_thread_exit_hooks (int i) // Remove a thread from the pool. Must be called with locks held. void -ACE_Thread_Manager::remove_thr (int i) +ACE_Thread_Manager::remove_thr (ACE_Thread_Descriptor *td) { ACE_TRACE ("ACE_Thread_Manager::remove_thr"); - this->current_count_--; - if (this->current_count_ > 0) - // Compact the table by moving the last item into the slot vacated - // by the index being removed (this is a structure assignment). - this->thr_table_[i] = this->thr_table_[this->current_count_]; - + this->thr_list_.remove (td); + delete td; #if defined (ACE_HAS_THREADS) // Tell all waiters when there are no more threads left in the pool. - if (this->current_count_ == 0) + if (this->thr_list_.size () == 0) this->zero_cond_.broadcast (); #endif /* ACE_HAS_THREADS */ } // Factor out some common behavior to simplify the following methods. #define ACE_THR_OP(OP,STATE) \ - int result = OP (this->thr_table_[i].thr_handle_); \ + int result = OP (td->thr_handle_); \ if (result != 0) { \ - this->remove_thr (i); \ + this->remove_thr (td); \ errno = result; \ return -1; \ } \ else { \ - this->thr_table_[i].thr_state_ = STATE; \ + td->thr_state_ = STATE; \ return 0; \ } int -ACE_Thread_Manager::join_thr (int i) +ACE_Thread_Manager::join_thr (ACE_Thread_Descriptor *td) { ACE_TRACE ("ACE_Thread_Manager::join_thr"); - int result = ACE_Thread::join (this->thr_table_[i].thr_handle_); + int result = ACE_Thread::join (td->thr_handle_); if (result != 0) { - this->remove_thr (i); + this->remove_thr (td); errno = result; return -1; } @@ -812,7 +777,7 @@ ACE_Thread_Manager::join_thr (int i) } int -ACE_Thread_Manager::suspend_thr (int i) +ACE_Thread_Manager::suspend_thr (ACE_Thread_Descriptor *td) { ACE_TRACE ("ACE_Thread_Manager::suspend_thr"); @@ -820,7 +785,7 @@ ACE_Thread_Manager::suspend_thr (int i) } int -ACE_Thread_Manager::resume_thr (int i) +ACE_Thread_Manager::resume_thr (ACE_Thread_Descriptor *td) { ACE_TRACE ("ACE_Thread_Manager::resume_thr"); @@ -828,45 +793,46 @@ ACE_Thread_Manager::resume_thr (int i) } int -ACE_Thread_Manager::cancel_thr (int i) +ACE_Thread_Manager::cancel_thr (ACE_Thread_Descriptor *td) { ACE_TRACE ("ACE_Thread_Manager::cancel_thr"); - this->thr_table_[i].thr_state_ = ACE_THR_CANCELLED; + // Don't really know how to handle thread cancel. + td->thr_state_ = ACE_THR_CANCELLED; return 0; } int -ACE_Thread_Manager::kill_thr (int i, int arg) +ACE_Thread_Manager::kill_thr (ACE_Thread_Descriptor *td, int arg) { ACE_TRACE ("ACE_Thread_Manager::kill_thr"); int signum = (int) arg; - int result = ACE_Thread::kill ((ACE_thread_t) this->thr_table_[i].thr_id_, + int result = ACE_Thread::kill ((ACE_thread_t) td->thr_id_, signum); if (result != 0) - { + { // We need to save this across calls to remove_thr() since that // call may reset errno. int error = errno; - this->remove_thr (i); - errno = error; - return -1; - } - else - return 0; + // this->remove_thr (td); + errno = error; + return -1; + } + else + return 0; } #define ACE_EXECUTE_OP(OP) \ ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); \ - ACE_FIND (this->find_thread (t_id), index); \ - return OP (index); + ACE_FIND (this->find_thread (t_id), ptr); \ + return OP (ptr); // Suspend a single thread. -int +int ACE_Thread_Manager::suspend (ACE_thread_t t_id) { ACE_TRACE ("ACE_Thread_Manager::suspend"); @@ -875,7 +841,7 @@ ACE_Thread_Manager::suspend (ACE_thread_t t_id) // Resume a single thread. -int +int ACE_Thread_Manager::resume (ACE_thread_t t_id) { ACE_TRACE ("ACE_Thread_Manager::resume"); @@ -884,7 +850,7 @@ ACE_Thread_Manager::resume (ACE_thread_t t_id) // Cancel a single thread. -int +int ACE_Thread_Manager::cancel (ACE_thread_t t_id) { ACE_TRACE ("ACE_Thread_Manager::cancel"); @@ -893,7 +859,7 @@ ACE_Thread_Manager::cancel (ACE_thread_t t_id) // Send a signal to a single thread. -int +int ACE_Thread_Manager::kill (ACE_thread_t t_id, int signum) { ACE_TRACE ("ACE_Thread_Manager::kill"); @@ -901,42 +867,34 @@ ACE_Thread_Manager::kill (ACE_thread_t t_id, int signum) } int -ACE_Thread_Manager::check_state (ACE_Thread_State state, - ACE_thread_t id) +ACE_Thread_Manager::check_state (ACE_Thread_State state, + ACE_thread_t id) { ACE_TRACE ("ACE_Thread_Manager::check_state"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); - ACE_Thread_State *thr_state = 0; + ACE_Thread_State thr_state; #if 0 int self_check = ACE_OS::thr_equal (id, ACE_OS::thr_self ()); // If we're checking the state of our thread, try to get the cached // value out of TSS to avoid lookup. - if (self_check) - thr_state = ACE_LOG_MSG->thr_state (); - - // Wasn't in the cache, so we'll have to look it up. - if (thr_state == 0) - { - ACE_FIND (this->find_thread (id), index); - thr_state = &this->thr_table_[index].thr_state_; - - if (self_check) // Update the TSS cache. - ACE_LOG_MSG->thr_state (thr_state); - } + if (self_check) + thr_state = this->thread_desc_self ()->thr_state_; #else - // Turn off caching for the time being until we figure out + // Turn off caching for the time being until we figure out // how to do it correctly in the face of deletions... - ACE_FIND (this->find_thread (id), index); - thr_state = &this->thr_table_[index].thr_state_; + ACE_FIND (this->find_thread (id), ptr); + if (ptr == 0) + return 0; + thr_state = ptr->thr_state_; #endif /* 0 */ - return *thr_state == state; + return thr_state == state; } // Test if a single thread is suspended. -int +int ACE_Thread_Manager::testsuspend (ACE_thread_t t_id) { ACE_TRACE ("ACE_Thread_Manager::testsuspend"); @@ -945,7 +903,7 @@ ACE_Thread_Manager::testsuspend (ACE_thread_t t_id) // Test if a single thread is active (i.e., resumed). -int +int ACE_Thread_Manager::testresume (ACE_thread_t t_id) { ACE_TRACE ("ACE_Thread_Manager::testresume"); @@ -954,7 +912,7 @@ ACE_Thread_Manager::testresume (ACE_thread_t t_id) // Test if a single thread is cancelled. -int +int ACE_Thread_Manager::testcancel (ACE_thread_t t_id) { ACE_TRACE ("ACE_Thread_Manager::testcancel"); @@ -963,34 +921,34 @@ ACE_Thread_Manager::testcancel (ACE_thread_t t_id) // Get group ids for a particular thread id. -int +int ACE_Thread_Manager::get_grp (ACE_thread_t t_id, int &grp_id) { ACE_TRACE ("ACE_Thread_Manager::get_grp"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); - ACE_FIND (this->find_thread (t_id), index); - grp_id = this->thr_table_[index].grp_id_; + ACE_FIND (this->find_thread (t_id), ptr); + grp_id = ptr->grp_id_; return 0; } // Set group ids for a particular thread id. -int +int ACE_Thread_Manager::set_grp (ACE_thread_t t_id, int grp_id) { ACE_TRACE ("ACE_Thread_Manager::set_grp"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); - ACE_FIND (this->find_thread (t_id), index); - this->thr_table_[index].grp_id_ = grp_id; + ACE_FIND (this->find_thread (t_id), ptr); + ptr->grp_id_ = grp_id; return 0; } // Suspend a group of threads. int -ACE_Thread_Manager::apply_grp (int grp_id, +ACE_Thread_Manager::apply_grp (int grp_id, THR_FUNC func, int arg) { @@ -998,50 +956,52 @@ ACE_Thread_Manager::apply_grp (int grp_id, ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); int result = 0; - - for (size_t i = 0; i < this->current_count_; i++) - if (this->thr_table_[i].grp_id_ == grp_id - && (this->*func)(i, arg) == -1) + ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> + iter (this->thr_list_); + + for (; ! iter.done (); iter.advance ()) + if (iter.next ()->grp_id_ == grp_id + && (this->*func) (iter.next (), arg) == -1) result = -1; return result; } -int +int ACE_Thread_Manager::suspend_grp (int grp_id) { ACE_TRACE ("ACE_Thread_Manager::suspend_grp"); - return this->apply_grp (grp_id, + return this->apply_grp (grp_id, THR_FUNC (&ACE_Thread_Manager::suspend_thr)); } // Resume a group of threads. -int +int ACE_Thread_Manager::resume_grp (int grp_id) { ACE_TRACE ("ACE_Thread_Manager::resume_grp"); - return this->apply_grp (grp_id, + return this->apply_grp (grp_id, THR_FUNC (&ACE_Thread_Manager::resume_thr)); } // Kill a group of threads. -int +int ACE_Thread_Manager::kill_grp (int grp_id, int signum) { ACE_TRACE ("ACE_Thread_Manager::kill_grp"); - return this->apply_grp (grp_id, + return this->apply_grp (grp_id, THR_FUNC (&ACE_Thread_Manager::kill_thr), signum); } // Cancel a group of threads. -int +int ACE_Thread_Manager::cancel_grp (int grp_id) { ACE_TRACE ("ACE_Thread_Manager::resume_grp"); - return this->apply_grp (grp_id, + return this->apply_grp (grp_id, THR_FUNC (&ACE_Thread_Manager::cancel_thr)); } @@ -1052,9 +1012,11 @@ ACE_Thread_Manager::apply_all (THR_FUNC func, int arg) ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); int result = 0; + ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> + iter (this->thr_list_); - for (size_t i = 0; i < this->current_count_; i++) - if ((this->*func)(i, arg) == -1) + for (; ! iter.done (); iter.advance ()) + if ((this->*func)(iter.next (), arg) == -1) result = -1; return result; @@ -1062,28 +1024,28 @@ ACE_Thread_Manager::apply_all (THR_FUNC func, int arg) // Resume all threads that are suspended. -int +int ACE_Thread_Manager::resume_all (void) { ACE_TRACE ("ACE_Thread_Manager::resume_all"); return this->apply_all (THR_FUNC (&ACE_Thread_Manager::resume_thr)); } -int +int ACE_Thread_Manager::suspend_all (void) { ACE_TRACE ("ACE_Thread_Manager::suspend_all"); return this->apply_all (THR_FUNC (&ACE_Thread_Manager::suspend_thr)); } -int +int ACE_Thread_Manager::kill_all (int sig) { ACE_TRACE ("ACE_Thread_Manager::kill_all"); return this->apply_all (&ACE_Thread_Manager::kill_thr, sig); } -int +int ACE_Thread_Manager::cancel_all (void) { ACE_TRACE ("ACE_Thread_Manager::cancel_all"); @@ -1092,7 +1054,7 @@ ACE_Thread_Manager::cancel_all (void) // Wait for group of threads -int +int ACE_Thread_Manager::wait_grp (int grp_id) { ACE_TRACE ("ACE_Thread_Manager::wait_grp"); @@ -1106,16 +1068,16 @@ ACE_Thread_Manager::wait_grp (int grp_id) { ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); - copy_table = new ACE_Thread_Descriptor [this->current_count_]; + copy_table = new ACE_Thread_Descriptor [this->thr_list_.size ()]; - for (size_t i = 0; i < this->current_count_; i++) - if (this->thr_table_[i].grp_id_ == grp_id) - { - copy_table[copy_count] = this->thr_table_[i]; - copy_count++; - } - } + ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> + iter (this->thr_list_); + for (; ! iter.done (); iter.advance ()) + if (iter.next ()->grp_id_ == grp_id) + copy_table[copy_count++] = *iter.next (); + } + // Now to do the actual work int result = 0; @@ -1124,26 +1086,22 @@ ACE_Thread_Manager::wait_grp (int grp_id) i++) if (ACE_Thread::join (copy_table[i].thr_handle_) == -1) result = -1; - + delete [] copy_table; return result; } -int +int ACE_Thread_Manager::at_exit (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param) { ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); - // Locate thread id. - int i = this->find_thread (ACE_Thread::self ()); - - if (i != -1) - return this->thr_table_[i].at_exit (object, cleanup_hook, param); - else - return -1; + return this->thread_desc_self ()->at_exit (object, + cleanup_hook, + param); } // Must be called when thread goes out of scope to clean up its table @@ -1154,51 +1112,42 @@ ACE_Thread_Manager::exit (void *status, int do_thr_exit) { ACE_TRACE ("ACE_Thread_Manager::exit"); - int i; ACE_Cleanup_Info cleanup_info; // Just hold onto the guard while finding this thread's id and // copying the exit hook. { ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); - + ACE_Thread_Descriptor *td = this->thread_desc_self (); // Locate thread id. - i = this->find_thread (ACE_Thread::self ()); - - if (i != -1) + if (td != 0) { - // @@ Currently, we have just one hook. This should clearly - // be generalized to support an arbitrary number of hooks. - - if (this->thr_table_[i].cleanup_info_.cleanup_hook_ != 0) - { - // Copy the hook so that we can call it after releasing - // the guard. - cleanup_info = this->thr_table_[i].cleanup_info_; - this->thr_table_[i].cleanup_info_.cleanup_hook_ = 0; - } - - // @@ I still don't know how to distinguish threads that - // fall off the end or exit normally from those that are - // joined explicitly by user. Hopefully, after we put - // ACE_Thread_Descriptor addresses into TSS, we can find a - // way to solve this. + // @@ Currently, we have just one hook. This should clearly + // be generalized to support an arbitrary number of hooks. + + if (td->cleanup_info_.cleanup_hook_ != 0) + { + // Copy the hook so that we can call it after releasing + // the guard. + cleanup_info = td->cleanup_info_; + td->cleanup_info_.cleanup_hook_ = 0; + } #if !defined (VXWORKS) - // Threads created with THR_DAEMON shouldn't exist here, - // but just to be safe, let's put it here. - if (((this->thr_table_[i].flags_ & (THR_DETACHED | THR_DAEMON)) == 0) || - (this->thr_table_[i].flags_ & (THR_JOINABLE != 0))) - { - // Mark thread as terminated. - this->thr_table_[i].thr_state_ = ACE_THR_TERMINATED; + // Threads created with THR_DAEMON shouldn't exist here, + // but just to be safe, let's put it here. + if (((td->flags_ & (THR_DETACHED | THR_DAEMON)) == 0) || + (td->flags_ & (THR_JOINABLE != 0))) + { + // Mark thread as terminated. + td->thr_state_ = ACE_THR_TERMINATED; this->terminated_thr_queue_.enqueue_tail - (this->thr_table_[i]); - } -#endif /* VXWORKS */ + (*td); + } +#endif /* VXWORKS */ // Remove thread descriptor from the table. - this->remove_thr (i); + this->remove_thr (td); } // Release the guard. } @@ -1206,7 +1155,7 @@ ACE_Thread_Manager::exit (void *status, int do_thr_exit) // Call the cleanup hook. if (cleanup_info.cleanup_hook_ != 0) (*cleanup_info.cleanup_hook_) (cleanup_info.object_, - cleanup_info.param_); + cleanup_info.param_); if (do_thr_exit) { @@ -1236,9 +1185,9 @@ ACE_Thread_Manager::wait (const ACE_Time_Value *timeout) // Just hold onto the guard while waiting. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); - threads_waited_on = this->current_count_; + threads_waited_on = this->thr_list_.size (); - while (this->current_count_ > 0) + while (this->thr_list_.size () > 0) if (this->zero_cond_.wait (timeout) == -1) return -1; } // Let go of the guard, giving other threads a chance to run. @@ -1264,9 +1213,10 @@ ACE_Thread_Manager::wait (const ACE_Time_Value *timeout) ACE_Thread_Descriptor item; - while (!this->terminated_thr_queue_.dequeue_head (item)) - ACE_Thread::join (item.thr_handle_); + while (! this->terminated_thr_queue_.dequeue_head (item)) + ACE_Thread::join (item.thr_handle_); } + #endif /* VXWORKS */ #else ACE_UNUSED_ARG (timeout); @@ -1276,7 +1226,7 @@ ACE_Thread_Manager::wait (const ACE_Time_Value *timeout) } int -ACE_Thread_Manager::apply_task (ACE_Task_Base *task, +ACE_Thread_Manager::apply_task (ACE_Task_Base *task, THR_FUNC func, int arg) { @@ -1284,17 +1234,19 @@ ACE_Thread_Manager::apply_task (ACE_Task_Base *task, ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); int result = 0; + ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> + iter (this->thr_list_); - for (size_t i = 0; i < this->current_count_; i++) - if (this->thr_table_[i].task_ == task - && (this->*func)(i, arg) == -1) + for (; ! iter.done (); iter.advance ()) + if (iter.next ()->task_ == task + && (this->*func) (iter.next (), arg) == -1) result = -1; return result; } -// Wait for task -int +// Wait for task +int ACE_Thread_Manager::wait_task (ACE_Task_Base *task) { int copy_count = 0; @@ -1307,62 +1259,65 @@ ACE_Thread_Manager::wait_task (ACE_Task_Base *task) ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); ACE_NEW_RETURN (copy_table, - ACE_Thread_Descriptor [this->current_count_], + ACE_Thread_Descriptor [this->thr_list_.size ()], -1); - for (size_t i = 0; i < this->current_count_; i++) - if (this->thr_table_[i].task_ == task) + ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> + iter (this->thr_list_); + + for (; ! iter.done (); iter.advance ()) + if (iter.next ()->task_ == task) { - copy_table[copy_count] = this->thr_table_[i]; + copy_table[copy_count] = *iter.next (); copy_count++; } } - + // Now to do the actual work int result = 0; for (int i = 0; i < copy_count && result != -1; i++) if (ACE_Thread::join (copy_table[i].thr_handle_) == -1) result = -1; - + delete [] copy_table; return result; } // Suspend a task -int +int ACE_Thread_Manager::suspend_task (ACE_Task_Base *task) -{ +{ ACE_TRACE ("ACE_Thread_Manager::suspend_task"); - return this->apply_task (task, + return this->apply_task (task, THR_FUNC (&ACE_Thread_Manager::suspend_thr)); } // Resume a task. -int +int ACE_Thread_Manager::resume_task (ACE_Task_Base *task) { ACE_TRACE ("ACE_Thread_Manager::resume_task"); - return this->apply_task (task, + return this->apply_task (task, THR_FUNC (&ACE_Thread_Manager::resume_thr)); } // Kill a task. -int +int ACE_Thread_Manager::kill_task (ACE_Task_Base *task, int /* signum */) { ACE_TRACE ("ACE_Thread_Manager::kill_task"); - return this->apply_task (task, + return this->apply_task (task, THR_FUNC (&ACE_Thread_Manager::kill_thr)); } // Cancel a task. -int +int ACE_Thread_Manager::cancel_task (ACE_Task_Base *task) { ACE_TRACE ("ACE_Thread_Manager::cancel_task"); - return this->apply_task (task, + return this->apply_task (task, THR_FUNC (&ACE_Thread_Manager::cancel_thr)); } @@ -1370,35 +1325,36 @@ ACE_Thread_Manager::cancel_task (ACE_Task_Base *task) // beginning of the table up to an index. Must be called with the // lock held. -int -ACE_Thread_Manager::find_task (ACE_Task_Base *task, - int index) +ACE_Thread_Descriptor * +ACE_Thread_Manager::find_task (ACE_Task_Base *task, int index) { ACE_TRACE ("ACE_Thread_Manager::find_task"); + ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> + iter (this->thr_list_); - if (index == -1) - index = current_count_; - - for (int i = 0; i < index; i++) - if (task == this->thr_table_[i].task_) - return i; + for (int i = 0; i < index && ! iter.done (); iter.advance (), i++) + if (task == iter.next ()->task_) + return iter.next (); - return -1; + return 0; } -// Returns the number of ACE_Task in a group. +// Returns the number of ACE_Task in a group. -int +int ACE_Thread_Manager::num_tasks_in_group (int grp_id) { ACE_TRACE ("ACE_Thread_Manager::num_tasks_in_group"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); int tasks_count = 0; + ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> + iter (this->thr_list_); - for (size_t i = 0; i < this->current_count_; i++) - if (this->thr_table_[i].grp_id_ == grp_id - && this->find_task (thr_table_[i].task_, i) == -1) + for (size_t i = 0; ! iter.done (); iter.advance (), i++) + if (iter.next ()->grp_id_ == grp_id + && this->find_task (iter.next ()->task_, i) == + 0) tasks_count++; return tasks_count; @@ -1406,16 +1362,18 @@ ACE_Thread_Manager::num_tasks_in_group (int grp_id) // Returns the number of threads in an ACE_Task. -int +int ACE_Thread_Manager::num_threads_in_task (ACE_Task_Base *task) { ACE_TRACE ("ACE_Thread_Manager::num_threads_in_task"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); int threads_count = 0; + ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> + iter (this->thr_list_); - for (size_t i = 0; i < this->current_count_; i++) - if (this->thr_table_[i].task_ == task) + for (; ! iter.done (); iter.advance ()) + if (iter.next ()->task_ == task) threads_count++; return threads_count; @@ -1423,8 +1381,8 @@ ACE_Thread_Manager::num_threads_in_task (ACE_Task_Base *task) // Returns in task_list a list of ACE_Tasks in a group. -int -ACE_Thread_Manager::task_list (int grp_id, +int +ACE_Thread_Manager::task_list (int grp_id, ACE_Task_Base *task_list[], size_t n) { @@ -1433,13 +1391,15 @@ ACE_Thread_Manager::task_list (int grp_id, ACE_Task_Base **task_list_iterator = task_list; size_t task_list_count = 0; + ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> + iter (this->thr_list_); - for (size_t i = 0; i < this->current_count_; i++) - if (task_list_count < n - && this->thr_table_[i].grp_id_ == grp_id - && this->find_task (thr_table_[i].task_, i) == -1) + for (size_t i = 0; task_list_count < n && ! iter.done (); + iter.advance (), i++) + if (iter.next ()->grp_id_ == grp_id + && this->find_task (iter.next ()->task_, i) == 0) { - task_list_iterator[task_list_count] = this->thr_table_[i].task_; + task_list_iterator[task_list_count] = iter.next ()->task_; task_list_count++; } @@ -1448,22 +1408,23 @@ ACE_Thread_Manager::task_list (int grp_id, // Returns in thread_list a list of thread ids in an ACE_Task. -int -ACE_Thread_Manager::thread_list (ACE_Task_Base *task, +int +ACE_Thread_Manager::thread_list (ACE_Task_Base *task, ACE_thread_t thread_list[], size_t n) { ACE_TRACE ("ACE_Thread_Manager::thread_list"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); - ACE_thread_t *thread_list_iterator = thread_list; - size_t thread_list_count = 0; + ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> + iter (this->thr_list_); + size_t thread_count = 0; - for (size_t i = 0; i < this->current_count_; i++) - if (thread_list_count < n && this->thr_table_[i].task_ == task) + for (; thread_count < n && ! iter.done (); iter.advance ()) + if (iter.next ()->task_ == task) { - thread_list_iterator[thread_list_count] = this->thr_table_[i].thr_id_; - thread_list_count++; + thread_list[thread_count] = iter.next ()->thr_id_; + thread_count ++; } return 0; @@ -1471,49 +1432,50 @@ ACE_Thread_Manager::thread_list (ACE_Task_Base *task, // Returns in thread_list a list of thread handles in an ACE_Task. -int -ACE_Thread_Manager::hthread_list (ACE_Task_Base *task, +int +ACE_Thread_Manager::hthread_list (ACE_Task_Base *task, ACE_hthread_t hthread_list[], size_t n) { ACE_TRACE ("ACE_Thread_Manager::thread_list"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); - ACE_hthread_t *hthread_list_iterator = hthread_list; - size_t hthread_list_count = 0; + ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> + iter (this->thr_list_); + size_t hthread_count = 0; - for (size_t i = 0; i < this->current_count_; i++) - if (this->thr_table_[i].task_ == task - && hthread_list_count < n) + for (; hthread_count < n && ! iter.done (); iter.advance ()) + if (iter.next ()->task_ == task) { - hthread_list_iterator[hthread_list_count] = - this->thr_table_[i].thr_handle_; - hthread_list_count++; + hthread_list[hthread_count] = iter.next ()->thr_handle_; + hthread_count ++; } return 0; } -int +int ACE_Thread_Manager::set_grp (ACE_Task_Base *task, int grp_id) { ACE_TRACE ("ACE_Thread_Manager::set_grp"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> + iter (this->thr_list_); - for (size_t i = 0; i < this->current_count_; i++) - if (this->thr_table_[i].task_ == task) - this->thr_table_[i].grp_id_ = grp_id; + for ( ; ! iter.done (); iter.advance ()) + if (iter.next ()->task_ == task) + iter.next ()->grp_id_ = grp_id; return 0; } -int +int ACE_Thread_Manager::get_grp (ACE_Task_Base *task, int &grp_id) { ACE_TRACE ("ACE_Thread_Manager::get_grp"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); - ACE_FIND (this->find_task (task), index); - grp_id = this->thr_table_[index].grp_id_; + ACE_FIND (this->find_task (task), ptr); + grp_id = ptr->grp_id_; return 0; } @@ -1527,17 +1489,17 @@ int ACE_Thread_Control::insert (ACE_Thread_Manager *tm) { ACE_TRACE ("ACE_Thread_Control::insert"); - + ACE_hthread_t t_id; ACE_Thread::self (t_id); this->tm_ = tm; - + return this->tm_->insert_thr (ACE_Thread::self (), t_id); } // Initialize the thread controller. -ACE_Thread_Control::ACE_Thread_Control (ACE_Thread_Manager *t, +ACE_Thread_Control::ACE_Thread_Control (ACE_Thread_Manager *t, int insert) : tm_ (t), status_ (0) @@ -1591,6 +1553,8 @@ template class ACE_Unbounded_Queue<ACE_Thread_Descriptor>; template class ACE_Unbounded_Queue_Iterator<ACE_Thread_Descriptor>; template class ACE_Node<ACE_Thread_Descriptor>; #endif /* VXWORKS */ +template class ACE_Double_Linked_List<ACE_Thread_Descriptor>; +template class ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor>; #if (defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) // This doesn't necessarily belong here, but it's a convenient place for it. template class ACE_TSS<ACE_Dynamic>; @@ -1602,6 +1566,8 @@ template class ACE_Node<ACE_Thread_Descriptor>; #pragma instantiate ACE_Unbounded_Queue_Iterator<ACE_Thread_Descriptor> #pragma instantiate ACE_Node<ACE_Thread_Descriptor> #endif /* VXWORKS */ + #pragma instantiate ACE_Double_Linked_List<ACE_Thread_Descriptor> + $pragma instantiate ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> #if (defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) // This doesn't necessarily belong here, but it's a convenient place for it. #pragma instantiate ACE_TSS<ACE_Dynamic> diff --git a/ace/Thread_Manager.h b/ace/Thread_Manager.h index 400993f1e74..611cc2822f9 100644 --- a/ace/Thread_Manager.h +++ b/ace/Thread_Manager.h @@ -5,13 +5,13 @@ // // = LIBRARY // ace -// +// // = FILENAME -// Thread_Manager.h +// Thread_Manager.h // // = AUTHOR -// Doug Schmidt -// +// Doug Schmidt +// // ============================================================================ #if !defined (ACE_THREAD_MANAGER_H) @@ -31,6 +31,8 @@ class ACE_Export ACE_Thread_Descriptor // of the <Thread_Manager>. { friend class ACE_Thread_Manager; +friend class ACE_Double_Linked_List<ACE_Thread_Descriptor>; +friend class ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor>; public: // = Initialization method. ACE_Thread_Descriptor (void); @@ -56,8 +58,8 @@ public: // Dump the state of an object. int at_exit (void *object, - ACE_CLEANUP_FUNC cleanup_hook, - void *param); + ACE_CLEANUP_FUNC cleanup_hook, + void *param); // Register an object (or array) for cleanup at thread termination. // "cleanup_hook" points to a (global, or static member) function // that is called for the object or array when it to be destroyed. @@ -71,7 +73,7 @@ public: private: ACE_thread_t thr_id_; // Unique thread ID. - + ACE_hthread_t thr_handle_; // Unique handle to thread (used by Win32 and AIX). @@ -82,7 +84,7 @@ private: // Current state of the thread. ACE_Cleanup_Info cleanup_info_; - // Stores the cleanup info for a thread. + // Stores the cleanup info for a thread. // @@ Note, this should be generalized to be a stack of // <ACE_Cleanup_Info>s. @@ -94,86 +96,11 @@ private: ACE_Task_Base *task_; // Pointer to an <ACE_Task_Base> or NULL if there's no <ACE_Task_Base>; -}; - -////////////////////////////////////////////////// - -// @@ Thread handle comparison, how? When we duplicate a handle, (on -// Win32) the returning handle won't have the same value as the -// original handle. Therefore, I don't see a way to distinguish -// whether two handles point to the same theread or not. -// Motto: Always use thread ids to manipulate Thread_Manager. ??? - -#if defined (NANBOR_EXP_CODES) -CLASS ACE_Export ACE_Thread_Descriptor_Adapter - // = TITLE - // Wrap ACE_Thread_Descriptor for putting it into a container. - // - // = DESCRIPTION - // This class contains a pointer to a ACE_Thread_Descriptor. - // It then gets put into a container. This is to avoid extra - // data copying and also expose ACE_Thread_Descriptor's methods - // to the external world. - // - // *I assume no two threads will have the same thread id.* -{ -public: - ACE_Thread_Descriptor_Adapter (); - // Default constructor. Used by container classes. - - ACE_Thread_Descriptor_Adapter (ACE_Thread_Descriptor *thr_desc); - // Construct a adapter containing <thr_desc>. User should call this method. - - ACE_Thread_Descriptor_Adapter (const ACE_Thread_Descriptor_Adapter &td); - // Copy constructor. Required by container classes. - - ACE_Thread_Descriptor_Adatper& operator= (const ACE_Thread_Descriptor_Adapter &td); - // Assignment operation. Required by container classes. - - int operator== (const ACE_Thread_Descriptor_Adapter &td) const; - // Comparison operator. Required by container classes. - - // = Accessing the underlying methods of ACE_Thread_Descriptor. - - ACE_thread_t self (void); - // Unique thread id. - - void self (ACE_hthread_t &); - // Unique handle to thread (used by Win32 and AIX). - - int grp_id (void); - // Group ID. - - ACE_Thread_State state (void); - // Current state of the thread. - ACE_Task_Base *task (void); - // Return the pointer to an <ACE_Task_Base> or NULL if there's no - // <ACE_Task_Base> associated with this thread.; - - void dump (void) const; - // Dump the state of an object. - - int at_exit (void *object, - ACE_CLEANUP_FUNC cleanup_hook, - void *param); - // Register an object (or array) for cleanup at thread termination. - // "cleanup_hook" points to a (global, or static member) function - // that is called for the object or array when it to be destroyed. - // It may perform any necessary cleanup specific for that object or - // its class. "param" is passed as the second parameter to the - // "cleanup_hook" function; the first parameter is the object (or - // array) to be destroyed. Returns 0 on success, non-zero on - // failure: -1 if virtual memory is exhausted or 1 if the object (or - // arrayt) had already been registered. + ACE_Thread_Descriptor *next_; - ACE_Thread_Descriptor *get_thread_descriptor (void); - -private: - ACE_Thread_Descriptor *thr_desc_; - // Underlying thread descriptor location. + ACE_Thread_Descriptor *prev_; }; -#endif /* NANBOR_EXP_CODES */ // Forward declaration. class ACE_Thread_Control; @@ -182,7 +109,7 @@ class ACE_Thread_Control; // declaration. But, it caused compilation problems on g++/VxWorks/i960 // with -g. Note that ACE_Thread_Manager::THR_FUNC is only used // internally in ACE_Thread_Manager, so it's not useful for anyone else. -typedef int (ACE_Thread_Manager::*THR_FUNC)(int, int); +typedef int (ACE_Thread_Manager::*THR_FUNC)(ACE_Thread_Descriptor*, int); class ACE_Export ACE_Thread_Manager // = TITLE @@ -193,13 +120,8 @@ class ACE_Export ACE_Thread_Manager { friend class ACE_Thread_Control; public: - enum - { - DEFAULT_SIZE = 100 - }; - // = Initialization and termination methods. - ACE_Thread_Manager (size_t size = ACE_Thread_Manager::DEFAULT_SIZE); + ACE_Thread_Manager (void); virtual ~ACE_Thread_Manager (void); static ACE_Thread_Manager *instance (void); @@ -212,47 +134,44 @@ public: static void close_singleton (void); // Delete the dynamically allocated Singleton - int open (size_t size = DEFAULT_SIZE); - // Initialize the manager with room for SIZE threads. - - int close (void); + int close (void); // Release all resources. - int spawn (ACE_THR_FUNC func, - void *args = 0, - long flags = THR_NEW_LWP, - ACE_thread_t * = 0, - ACE_hthread_t *t_handle = 0, - long priority = ACE_DEFAULT_THREAD_PRIORITY, - int grp_id = -1, - void *stack = 0, - size_t stack_size = 0); - // Create a new thread, which executes <func>. + int spawn (ACE_THR_FUNC func, + void *args = 0, + long flags = THR_NEW_LWP, + ACE_thread_t * = 0, + ACE_hthread_t *t_handle = 0, + long priority = ACE_DEFAULT_THREAD_PRIORITY, + int grp_id = -1, + void *stack = 0, + size_t stack_size = 0); + // Create a new thread, which executes <func>. // Returns: on success a unique group id that can be used to control // other threads added to the same group. On failure, returns -1. - int spawn_n (size_t n, - ACE_THR_FUNC func, - void *args = 0, - long flags = THR_NEW_LWP, - long priority = ACE_DEFAULT_THREAD_PRIORITY, - int grp_id = -1, - ACE_Task_Base *task = 0, - ACE_hthread_t thread_handles[] = 0); - // Create N new threads, all of which execute <func>. + int spawn_n (size_t n, + ACE_THR_FUNC func, + void *args = 0, + long flags = THR_NEW_LWP, + long priority = ACE_DEFAULT_THREAD_PRIORITY, + int grp_id = -1, + ACE_Task_Base *task = 0, + ACE_hthread_t thread_handles[] = 0); + // Create N new threads, all of which execute <func>. // Returns: on success a unique group id that can be used to control // all of the threads in the same group. On failure, returns -1. - int spawn_n (ACE_thread_t thread_ids[], - size_t n, - ACE_THR_FUNC func, - void *args, - long flags, - long priority = ACE_DEFAULT_THREAD_PRIORITY, - int grp_id = -1, - void *stack[] = 0, - size_t stack_size[] = 0, - ACE_hthread_t thread_handles[] = 0); + int spawn_n (ACE_thread_t thread_ids[], + size_t n, + ACE_THR_FUNC func, + void *args, + long flags, + long priority = ACE_DEFAULT_THREAD_PRIORITY, + int grp_id = -1, + void *stack[] = 0, + size_t stack_size[] = 0, + ACE_hthread_t thread_handles[] = 0); // Spawn N new threads, which execute <func> with argument <arg>. // If <thread_ids> != 0 the thread_ids of successfully spawned // threads will be placed into the <thread_ids> buffer (which must @@ -271,7 +190,7 @@ public: // non-0 then <ACE_Thread::exit> is called to exit the thread, in // which case <status> is passed as the exit value of the thread. - int wait (const ACE_Time_Value *timeout = 0); + int wait (const ACE_Time_Value *timeout = 0); // Block until there are no more threads running in the // <Thread_Manager> or <timeout> expires. Note that <timeout> is // treated as "absolute" time. Returns 0 on success and -1 on @@ -282,21 +201,30 @@ public: // Returns 0 on success and -1 on failure. // = Accessors for ACE_Thread_Descriptors. - int thread_descriptor (ACE_thread_t, ACE_Thread_Descriptor &); - // Return the thread descriptor (indexed by ACE_thread_t). Returns 0 on - // success and -1 if not found. + ACE_Thread_Descriptor *thread_desc_self (void); + // Get a pointer to the calling thread's own thread_descriptor. + // This must be called from a spawn thread. This function will + // try to fetch this info from TSS, if it is not cached, then + // it will look it up and cache it. + // This function must be called with lock held. - int hthread_descriptor (ACE_hthread_t, ACE_Thread_Descriptor &); - // Return the thread descriptor (indexed by ACE_hthread_t). Returns 0 - // on success and -1 if not found. + ACE_Thread_Descriptor *thread_descriptor (ACE_thread_t); + // Return a pointer to the thread's Thread_Descriptor, + // 0 if fail. + + ACE_Thread_Descriptor *hthread_descriptor (ACE_hthread_t); + // Return a pointer to the thread's Thread_Descriptor, + // 0 if fail. int thr_self (ACE_hthread_t &); - // Passes out the "real" handle to the calling thread, caching it if - // necessary in TSS to speed up subsequent lookups. This is + + // Return the "real" handle to the calling thread, caching it if + // necessary in TSS to speed up subsequent lookups. This is // necessary since on some platforms (e.g., Win32) we can't get this // handle via direct method calls. Notice that you should *not* close // the handle passed back from this method. It is used internally - // by Thread Manager. + // by Thread Manager. On the other hand, you *have to* use this internal + // thread handle when working on Thread_Manager. Return -1 if fail. ACE_thread_t thr_self (void); // Return the unique ID of the thread. This is not strictly @@ -310,7 +238,7 @@ public: // = Suspend methods, which isn't supported on POSIX pthreads (will not block). int suspend_all (void); - // Suspend all threads + // Suspend all threads int suspend (ACE_thread_t); // Suspend a single thread. int suspend_grp (int grp_id); @@ -320,7 +248,7 @@ public: // = Resume methods, which isn't supported on POSIX pthreads (will not block). int resume_all (void); - // Resume all stopped threads + // Resume all stopped threads int resume (ACE_thread_t); // Resume a single thread. int resume_grp (int grp_id); @@ -330,7 +258,7 @@ public: // = Kill methods, send signals -- which isn't supported on Win32 (will not block). int kill_all (int signum); - // Send signum to all stopped threads + // Send signum to all stopped threads int kill (ACE_thread_t, int signum); // Kill a single thread. int kill_grp (int grp_id, int signum); @@ -354,7 +282,7 @@ public: // methods in <ACE_Thread Manager>. For example, the <apply_task> // method resembles the <apply_thr> method, and <suspend_task> // resembles <suspend_thr>. - + // = Operations on ACE_Tasks. int wait_task (ACE_Task_Base *task); // Block until there are no more threads running in <task>. Returns @@ -378,22 +306,22 @@ public: int num_threads_in_task (ACE_Task_Base *task); // Returns the number of threads in an <ACE_Task_Base>. - int task_list (int grp_id, - ACE_Task_Base *task_list[], - size_t n); + int task_list (int grp_id, + ACE_Task_Base *task_list[], + size_t n); // Returns in <task_list> a list of up to <n> <ACE_Tasks> in a // group. The caller must allocate the memory for <task_list> - int thread_list (ACE_Task_Base *task, - ACE_thread_t thread_list[], - size_t n); + int thread_list (ACE_Task_Base *task, + ACE_thread_t thread_list[], + size_t n); // Returns in <thread_list> a list of up to <h> thread ids in an // <ACE_Task_Base>. The caller must allocate the memory for // <thread_list>. - int hthread_list (ACE_Task_Base *task, - ACE_hthread_t hthread_list[], - size_t n); + int hthread_list (ACE_Task_Base *task, + ACE_hthread_t hthread_list[], + size_t n); // Returns in <hthread_list> a list of up to <n> thread handles in // an <ACE_Task_Base>. The caller must allocate memory for // <hthread_list>. @@ -403,8 +331,8 @@ public: int get_grp (ACE_Task_Base *task, int &grp_id); int at_exit (void *object, - ACE_CLEANUP_FUNC cleanup_hook, - void *param); + ACE_CLEANUP_FUNC cleanup_hook, + void *param); // Register an object (or array) for cleanup at thread termination. // "cleanup_hook" points to a (global, or static member) function // that is called for the object or array when it to be destroyed. @@ -414,60 +342,62 @@ public: // array) to be destroyed. "cleanup_hook", for example, may delete // the object (or array). - void dump (void) const; + void dump (void); // Dump the state of an object. ACE_ALLOC_HOOK_DECLARE; // Declare the dynamic allocation hooks. protected: - virtual int spawn_i (ACE_THR_FUNC func, - void *args, - long flags, - ACE_thread_t * = 0, - ACE_hthread_t *t_handle = 0, - long priority = ACE_DEFAULT_THREAD_PRIORITY, - int grp_id = -1, - void *stack = 0, - size_t stack_size = 0, - ACE_Task_Base *task = 0); + virtual int spawn_i (ACE_THR_FUNC func, + void *args, + long flags, + ACE_thread_t * = 0, + ACE_hthread_t *t_handle = 0, + long priority = ACE_DEFAULT_THREAD_PRIORITY, + int grp_id = -1, + void *stack = 0, + size_t stack_size = 0, + ACE_Task_Base *task = 0); // Create a new thread (must be called with locks held). void run_thread_exit_hooks (int i); // Run the registered hooks when the thread exits. - int resize (size_t); - // Resize the pool of Thread_Descriptors. - - int find_thread (ACE_thread_t t_id); + ACE_Thread_Descriptor *find_thread (ACE_thread_t t_id); // Locate the index of the table slot occupied by <t_id>. Returns // -1 if <t_id> is not in the table doesn't contain <t_id>. - int find_hthread (ACE_hthread_t h_id); + ACE_Thread_Descriptor *find_hthread (ACE_hthread_t h_id); // Locate the index of the table slot occupied by <h_id>. Returns // -1 if <h_id> is not in the table doesn't contain <h_id>. - int find_task (ACE_Task_Base *task, int index = -1); - // Locate the index of the table slot occupied by <task>. Returns - // -1 if <task> is not in the table doesn't contain <task>. + ACE_Thread_Descriptor *find_task (ACE_Task_Base *task, int index = -1); + // Locate the thread descriptor address of the list occupied by + // <task>. Returns 0 if <task> is not in the table doesn't contain + // <task>. int insert_thr (ACE_thread_t t_id, - ACE_hthread_t, - int grp_id = -1, - long flags = 0); + ACE_hthread_t, + int grp_id = -1, + long flags = 0); // Insert a thread in the table (checks for duplicates). - int append_thr (ACE_thread_t t_id, ACE_hthread_t, - ACE_Thread_State, - int grp_id, - ACE_Task_Base *task = 0, - long flags = 0); + int append_thr (ACE_thread_t t_id, ACE_hthread_t, + ACE_Thread_State, + int grp_id, + ACE_Task_Base *task = 0, + long flags = 0); // Append a thread in the table (adds at the end, growing the table // if necessary). - void remove_thr (int i); + void remove_thr (ACE_Thread_Descriptor *tda); // Remove thread from the table. + void remove_thr_self(void); + // Same as above but must be called from the context of the thread + // that is to be removed. + // = The following four methods implement a simple scheme for // operating on a collection of threads atomically. @@ -485,36 +415,29 @@ protected: int apply_all (THR_FUNC, int = 0); // Apply <func> to all members of the table. - int join_thr (int i); - // Join the thread at index <i>. + int join_thr (ACE_Thread_Descriptor *tda); + // Join the thread described in <tda>. - int resume_thr (int i); - // Resume the thread at index <i>. + int resume_thr (ACE_Thread_Descriptor *tda); + // Resume the thread described in <tda>. - int suspend_thr (int i); - // Suspend the thread at index <i>. + int suspend_thr (ACE_Thread_Descriptor *tda); + // Suspend the thread described in <tda>. - int kill_thr (int i, int signum); - // Send signal <signum> to the thread at index <i>. + int kill_thr (ACE_Thread_Descriptor *tda, int signum); + // Send signal <signum> to the thread described in <tda>. - int cancel_thr (int i); - // Set the cancellation flag for the thread at index <i>. + int cancel_thr (ACE_Thread_Descriptor *tda); + // Set the cancellation flag for the thread described in <tda>. - ACE_Thread_Descriptor *thr_table_; - // Vector that describes thread state within the Thread_Manager. + ACE_Double_Linked_List<ACE_Thread_Descriptor> thr_list_; + // Keeping a list of threads within the thread manager. #if !defined (VXWORKS) ACE_Unbounded_Queue<ACE_Thread_Descriptor> terminated_thr_queue_; // Collect terminated but not yet joined thread entries. #endif /* VXWORKS */ - size_t max_table_size_; - // Maximum number of threads we can manage (should be dynamically - // allocated). - - size_t current_count_; - // Current number of threads we are managing. - int grp_id_; // Keeps track of the next group id to assign. @@ -552,8 +475,8 @@ class ACE_Export ACE_Thread_Control // <ACE_Thread_Manager>. { public: - ACE_Thread_Control (ACE_Thread_Manager *tm = 0, - int insert = 0); + ACE_Thread_Control (ACE_Thread_Manager *tm = 0, + int insert = 0); // Initialize the thread control object. If <insert> != 0, then // register the thread with the Thread_Manager. @@ -648,3 +571,4 @@ private: #endif /* __ACE_INLINE__ */ #endif /* ACE_THREAD_MANAGER_H */ + diff --git a/ace/Thread_Manager.i b/ace/Thread_Manager.i index 8391b50b4cf..dcbd14d2a60 100644 --- a/ace/Thread_Manager.i +++ b/ace/Thread_Manager.i @@ -44,94 +44,6 @@ ACE_Thread_Descriptor::state (void) return thr_state_; } -////////////////////////////////////////////////// -#if defined (NANBOR_EXP_CODES) -ACE_INLINE -ACE_Thread_Descriptor_Adapter::ACE_Thread_Descriptor_Adapter (void) - : thr_desc_ (0) -{ -} - -ACE_INLINE -ACE_Thread_Descriptor_Adapter::ACE_Thread_Descriptor_Adapter - (ACE_Thread_Descriptor *thr_desc) - : thr_desc_ (thr_desc) -{ -} - -ACE_INLINE -ACE_Thread_Descriptor_Adapter::ACE_Thread_Descriptor_Adapter - (const ACE_Thread_Descriptor_Adapter &td) - : thr_desc_ (td.thr_desc_) -{ -} - -ACE_INLINE ACE_Thread_Descriptor_Adatper& -ACE_Thread_Descriptor_Adapter::operator= (const ACE_Thread_Descriptor_Adapter &td) -{ - this->thr_desc_ = td.thr_desc_; -} - -ACE_INLINE int -ACE_Thread_Descriptor_Adapter::operator== (const ACE_Thread_Descriptor_Adapter &td) const -{ - return (this->self () == td.self ()); -} - -// = Accessing the underlying methods of ACE_Thread_Descriptor. - -ACE_INLINE ACE_thread_t -ACE_Thread_Descriptor_Adapter::self (void) -{ - return this->thr_desc_->self (); -} - -ACE_INLINE void -ACE_Thread_Descriptor_Adapter::self (ACE_hthread_t &handle) -{ - this->thr_desc_->self (handle); -} - -ACE_INLINE int -ACE_Thread_Descriptor_Adapter::grp_id (void) -{ - return this->thr_desc_->grp_id (); -} - -ACE_INLINE ACE_Thread_State -ACE_Thread_Descriptor_Adapter::state (void) -{ - return this->thr_desc_->state (); -} - -ACE_INLINE ACE_Task_Base * -ACE_Thread_Descriptor_Adapter::task (void) -{ - return this->thr_desc_->task (); -} - -ACE_INLINE void -ACE_Thread_Descriptor_Adapter::dump (void) const -{ - this->thr_desc_->dump (); -} - -ACE_INLINE int -ACE_Thread_Descriptor_Adapter::at_exit (void *object, - ACE_CLEANUP_FUNC cleanup_hook, - void *param) -{ - return this->thr_desc_->at_exit (object, cleanup_hook, param); -} - -ACE_INLINE ACE_Thread_Descriptor * -ACE_Thread_Descriptor_Adapter::get_thread_descriptor (void) -{ - return this->thr_desc_; -} -#endif /* NANBOR_EXP_CODES */ -////////////////////////////////////////////////// - // Set the exit status. ACE_INLINE void * @@ -184,10 +96,11 @@ ACE_INLINE ACE_Task_Base * ACE_Thread_Manager::task (void) { ACE_TRACE ("ACE_Thread_Manager::task"); - ACE_Thread_Descriptor td; - if (this->thread_descriptor (ACE_Thread::self (), td) == -1) + ACE_Thread_Descriptor *td = this->thread_desc_self () ; + + if (td == 0) return 0; else - return td.task (); + return td->task (); } |