blob: 7253794cf0bcee7a90ac827abd4b2acb89c80c78 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
// $Id$
#include "CSD_TP_Queue.h"
#include "CSD_TP_Request.h"
#include "CSD_TP_Queue_Visitor.h"
ACE_RCSID (CSD_ThreadPool,
TP_Queue,
"$Id$")
#if !defined (__ACE_INLINE__)
# include "CSD_TP_Queue.inl"
#endif /* ! __ACE_INLINE__ */
void
TAO::CSD::TP_Queue::put(TP_Request* request)
{
// The request is passed in as an "in" argument, and we would like to
// hold on to a "copy" within the queue (the linked list). We will
// perform an _add_ref() on the request now to make the queue's "copy".
request->_add_ref();
if (this->tail_ == 0)
{
// The tail_ is a NULL pointer only when the queue is empty.
// Make the request be the only element in the queue.
this->head_ = this->tail_ = request;
// Make sure the request's prev_ and next_ pointers are set to NULL.
request->prev_ = request->next_ = 0;
}
else
{
// There is at least one request already in the queue. "Append" the
// supplied request object to the end of the queue.
request->prev_ = this->tail_;
request->next_ = 0;
this->tail_->next_ = request;
this->tail_ = request;
}
}
void
TAO::CSD::TP_Queue::accept_visitor(TP_Queue_Visitor& visitor)
{
TP_Request* cur = this->head_;
while (cur != 0)
{
TP_Request* prev = cur->prev_;
TP_Request* next = cur->next_;
// Pass the current request to the visitor. Also pass-in a reference
// to the remove_from_queue flag. The visitor may decide that it
// wants to keep the current request for itself, and desires that the
// request be (surgically) removed from the queue. The visitor also
// gets to decide, via its return value, whether or not visitation
// should continue (or cease to continue).
bool remove_from_queue = false;
bool continue_visitation = visitor.visit_request(cur,remove_from_queue);
if (remove_from_queue)
{
// Create a local handle to release the current request once
// the handle falls out of scope. We need to do this because the
// queue "owns" a "copy" of each request in the queue.
TP_Request_Handle handle = cur;
if (this->head_ == cur)
{
// The current request is at the front (the head_) of the queue.
// Move the head_ to the next request in the queue.
this->head_ = next;
if (this->head_ == 0)
{
// Not only was the current request at the front of the
// queue - it was the *only* request in the queue.
// Update the tail_ pointer now that the queue is empty.
this->tail_ = 0;
}
else
{
// Set the (new) head_ request's prev_ pointer to be NULL.
this->head_->prev_ = 0;
}
}
else if (this->tail_ == cur)
{
// The current request is not at the front of the queue,
// but it is at the back of the queue. This implies that
// the queue currently contains at least two requests -
// the current request (cur), and the previous request (prev).
// The point is that we can now assume that the 'prev' pointer
// is never NULL in this case.
this->tail_ = prev;
this->tail_->next_ = 0;
}
else
{
// The current request is not at the front or at the back.
// This implies that there are at least three requests in
// the queue. We can assume that the 'next' and 'prev'
// pointers are never NULL in this case.
prev->next_ = next;
next->prev_ = prev;
}
}
if (!continue_visitation)
{
// The visitor doesn't want to procede with any further visitation.
// Break out of the visitation loop now.
break;
}
// Move on to the next request in the queue.
cur = next;
}
}
|