summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornw1 <nw1@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1997-10-20 19:19:34 +0000
committernw1 <nw1@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1997-10-20 19:19:34 +0000
commit79c2cc2cde3626ae71b26d4a4226dcfa8691c487 (patch)
tree6f9298b4fa6810a3f6f57f35252b9e27195e4b04
parent5a99875cf459e5cf8baa1e79f1c8a0af200bddc3 (diff)
downloadATCD-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.cpp203
-rw-r--r--ace/Containers.h221
-rw-r--r--ace/Containers.i99
-rw-r--r--ace/Log_Msg.cpp32
-rw-r--r--ace/Log_Msg.h28
-rw-r--r--ace/Thread_Manager.cpp750
-rw-r--r--ace/Thread_Manager.h322
-rw-r--r--ace/Thread_Manager.i95
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 ();
}