00001 // $Id: CSD_TP_Queue.cpp 71473 2006-03-10 07:19:20Z jtc $ 00002 00003 #include "tao/CSD_ThreadPool/CSD_TP_Queue.h" 00004 #include "tao/CSD_ThreadPool/CSD_TP_Request.h" 00005 #include "tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.h" 00006 00007 ACE_RCSID (CSD_ThreadPool, 00008 TP_Queue, 00009 "$Id: CSD_TP_Queue.cpp 71473 2006-03-10 07:19:20Z jtc $") 00010 00011 #if !defined (__ACE_INLINE__) 00012 # include "tao/CSD_ThreadPool/CSD_TP_Queue.inl" 00013 #endif /* ! __ACE_INLINE__ */ 00014 00015 TAO_BEGIN_VERSIONED_NAMESPACE_DECL 00016 00017 void 00018 TAO::CSD::TP_Queue::put(TP_Request* request) 00019 { 00020 // The request is passed in as an "in" argument, and we would like to 00021 // hold on to a "copy" within the queue (the linked list). We will 00022 // perform an _add_ref() on the request now to make the queue's "copy". 00023 request->_add_ref(); 00024 00025 if (this->tail_ == 0) 00026 { 00027 // The tail_ is a NULL pointer only when the queue is empty. 00028 // Make the request be the only element in the queue. 00029 this->head_ = this->tail_ = request; 00030 00031 // Make sure the request's prev_ and next_ pointers are set to NULL. 00032 request->prev_ = request->next_ = 0; 00033 } 00034 else 00035 { 00036 // There is at least one request already in the queue. "Append" the 00037 // supplied request object to the end of the queue. 00038 request->prev_ = this->tail_; 00039 request->next_ = 0; 00040 this->tail_->next_ = request; 00041 this->tail_ = request; 00042 } 00043 } 00044 00045 00046 void 00047 TAO::CSD::TP_Queue::accept_visitor(TP_Queue_Visitor& visitor) 00048 { 00049 TP_Request* cur = this->head_; 00050 00051 while (cur != 0) 00052 { 00053 TP_Request* prev = cur->prev_; 00054 TP_Request* next = cur->next_; 00055 00056 // Pass the current request to the visitor. Also pass-in a reference 00057 // to the remove_from_queue flag. The visitor may decide that it 00058 // wants to keep the current request for itself, and desires that the 00059 // request be (surgically) removed from the queue. The visitor also 00060 // gets to decide, via its return value, whether or not visitation 00061 // should continue (or cease to continue). 00062 bool remove_from_queue = false; 00063 00064 bool continue_visitation = visitor.visit_request(cur,remove_from_queue); 00065 00066 if (remove_from_queue) 00067 { 00068 // Create a local handle to release the current request once 00069 // the handle falls out of scope. We need to do this because the 00070 // queue "owns" a "copy" of each request in the queue. 00071 TP_Request_Handle handle = cur; 00072 00073 if (this->head_ == cur) 00074 { 00075 // The current request is at the front (the head_) of the queue. 00076 00077 // Move the head_ to the next request in the queue. 00078 this->head_ = next; 00079 00080 if (this->head_ == 0) 00081 { 00082 // Not only was the current request at the front of the 00083 // queue - it was the *only* request in the queue. 00084 // Update the tail_ pointer now that the queue is empty. 00085 this->tail_ = 0; 00086 } 00087 else 00088 { 00089 // Set the (new) head_ request's prev_ pointer to be NULL. 00090 this->head_->prev_ = 0; 00091 } 00092 } 00093 else if (this->tail_ == cur) 00094 { 00095 // The current request is not at the front of the queue, 00096 // but it is at the back of the queue. This implies that 00097 // the queue currently contains at least two requests - 00098 // the current request (cur), and the previous request (prev). 00099 // The point is that we can now assume that the 'prev' pointer 00100 // is never NULL in this case. 00101 this->tail_ = prev; 00102 this->tail_->next_ = 0; 00103 } 00104 else 00105 { 00106 // The current request is not at the front or at the back. 00107 // This implies that there are at least three requests in 00108 // the queue. We can assume that the 'next' and 'prev' 00109 // pointers are never NULL in this case. 00110 prev->next_ = next; 00111 next->prev_ = prev; 00112 } 00113 } 00114 00115 if (!continue_visitation) 00116 { 00117 // The visitor doesn't want to procede with any further visitation. 00118 // Break out of the visitation loop now. 00119 break; 00120 } 00121 00122 // Move on to the next request in the queue. 00123 cur = next; 00124 } 00125 } 00126 00127 TAO_END_VERSIONED_NAMESPACE_DECL