1 karl 1.47 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.4 //
|
3 karl 1.39 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 karl 1.36 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.39 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.40 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.47 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.4 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 chip 1.8 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
18 mike 1.4 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
|
20 karl 1.47 //
|
21 chip 1.8 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
22 mike 1.4 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
24 chip 1.8 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
27 mike 1.4 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 // Author: Mike Brasher (mbrasher@bmc.com)
33 //
|
34 a.arora 1.38 // Modified By: Amit K Arora, IBM (amita@in.ibm.com) for Bug#1090
|
35 joyce.j 1.41 // Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) for Bug#2076
|
36 david.dillard 1.43 // David Dillard, VERITAS Software Corp.
37 // (david.dillard@veritas.com)
|
38 aruran.ms 1.46 // Aruran, IBM (ashanmug@in.ibm.com) for Bug# 3475
|
39 mike 1.4 //
40 //%/////////////////////////////////////////////////////////////////////////////
41
|
42 mike 1.5 #include <Pegasus/Common/HashTable.h>
|
43 mike 1.7 #include <Pegasus/Common/IPC.h>
|
44 kumpf 1.19 #include <Pegasus/Common/Tracer.h>
|
45 mike 1.4 #include "MessageQueue.h"
|
46 mday 1.24 #include "MessageQueueService.h"
|
47 mike 1.48 #include "IDFactory.h"
48
|
49 mike 1.4 PEGASUS_USING_STD;
50
51 PEGASUS_NAMESPACE_BEGIN
52
|
53 mike 1.5 typedef HashTable<Uint32, MessageQueue*, EqualFunc<Uint32>, HashFunc<Uint32> >
54 QueueTable;
55
|
56 mday 1.33 static QueueTable _queueTable(256);
|
57 mday 1.28 static Mutex q_table_mut ;
|
58 mike 1.5
|
59 mday 1.35 void MessageQueue::remove_myself(Uint32 qid)
60 {
|
61 david.dillard 1.43 AutoMutex autoMut(q_table_mut);
62 _queueTable.remove(qid);
|
63 mday 1.35 }
64
|
65 mike 1.48 static IDFactory _qidFactory(CIMOM_Q_ID + 1);
|
66 mday 1.35
|
67 david.dillard 1.43 Uint32 MessageQueue::getNextQueueId()
|
68 mike 1.5 {
|
69 mike 1.48 return _qidFactory.getID();
|
70 aruran.ms 1.46 }
|
71 chip 1.8
|
72 aruran.ms 1.46 void MessageQueue::putQueueId(Uint32 queueId)
73 {
|
74 mike 1.48 if (queueId != CIMOM_Q_ID)
75 _qidFactory.putID(queueId);
|
76 aruran.ms 1.46 }
|
77 mday 1.24
|
78 mike 1.16 MessageQueue::MessageQueue(
|
79 david.dillard 1.43 const char* name,
|
80 mike 1.16 Boolean async,
81 Uint32 queueId)
|
82 mday 1.24 : _queueId(queueId), _capabilities(0), _count(0), _front(0), _back(0), _async(async)
|
83 mike 1.5 {
|
84 mike 1.16 //
85 // Copy the name:
86 //
87
|
88 david.dillard 1.43 PEG_METHOD_ENTER(TRC_MESSAGEQUEUESERVICE,"MessageQueue::MessageQueue()");
|
89 kumpf 1.19
|
90 mike 1.16 if (!name)
|
91 david.dillard 1.43 name = "";
|
92 mike 1.16
93 _name = new char[strlen(name) + 1];
94 strcpy(_name, name);
95
|
96 kumpf 1.25 Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL3,
|
97 kumpf 1.42 "MessageQueue::MessageQueue name = %s, queueId = %u", name, queueId);
|
98 kumpf 1.19
|
99 mike 1.16 //
100 // Insert into queue table:
101 //
|
102 a.arora 1.38 AutoMutex autoMut(q_table_mut);
|
103 david.dillard 1.43 while (!_queueTable.insert(_queueId, this))
104 ;
|
105 chip 1.8
|
106 david.dillard 1.43 PEG_METHOD_EXIT();
|
107 mike 1.5 }
108
109 MessageQueue::~MessageQueue()
110 {
111 // ATTN-A: thread safety!
|
112 kumpf 1.25 PEG_METHOD_ENTER(TRC_MESSAGEQUEUESERVICE,"MessageQueue::~MessageQueue()");
113 Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL3,
|
114 kumpf 1.19 "MessageQueue::~MessageQueue queueId = %i, name = %s", _queueId, _name);
115
|
116 a.arora 1.38 {
|
117 david.dillard 1.43 AutoMutex autoMut(q_table_mut);
118 _queueTable.remove(_queueId);
|
119 a.arora 1.38 } // mutex unlocks here
|
120 david.dillard 1.43
|
121 mike 1.16 // Free the name:
|
122 david.dillard 1.43
|
123 mike 1.16 delete [] _name;
|
124 kumpf 1.19
|
125 david.dillard 1.43 while(_front)
|
126 joyce.j 1.41 {
127 Message* tmp = _front;
128 _front = _front->_next;
129 delete tmp;
130 }
|
131 aruran.ms 1.46
132 // Return the queue id.
133
134 putQueueId(_queueId);
|
135 joyce.j 1.41
|
136 kumpf 1.25 PEG_METHOD_EXIT();
|
137 chip 1.8 }
138
|
139 kumpf 1.37 void MessageQueue::enqueue(Message* message)
|
140 mike 1.4 {
|
141 kumpf 1.25 PEG_METHOD_ENTER(TRC_MESSAGEQUEUESERVICE,"MessageQueue::enqueue()");
|
142 kumpf 1.19
|
143 david.dillard 1.43 if (!message)
|
144 kumpf 1.19 {
|
145 david.dillard 1.43 Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL3,
146 "MessageQueue::enqueue failure");
147 PEG_METHOD_EXIT();
148 throw NullPointer();
|
149 kumpf 1.19 }
|
150 mike 1.7
|
151 david.dillard 1.43 PEG_TRACE_STRING( TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL3,
|
152 kumpf 1.31 String("Queue name: ") + getQueueName() ) ;
|
153 david.dillard 1.43 Tracer::trace ( TRC_MESSAGEQUEUESERVICE,
|
154 kumpf 1.31 Tracer::LEVEL3,
|
155 kumpf 1.49 "Message: [%s]",
156 MessageTypeToString(message->getType()));
|
157 david.dillard 1.43
|
158 a.arora 1.38 {
159 AutoMutex autoMut(_mut);
|
160 mike 1.4 if (_back)
161 {
|
162 david.dillard 1.43 _back->_next = message;
163 message->_prev = _back;
164 message->_next = 0;
165 _back = message;
|
166 mike 1.4 }
167 else
168 {
|
169 david.dillard 1.43 _front = message;
170 _back = message;
171 message->_prev = 0;
172 message->_next = 0;
|
173 mike 1.4 }
174 message->_owner = this;
|
175 david.dillard 1.43
|
176 mike 1.4 _count++;
|
177 kumpf 1.25 Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL4,
|
178 david.dillard 1.43 "MessageQueue::enqueue _queueId = %d, _count = %d", _queueId, _count);
179
|
180 a.arora 1.38 } // mutex unlocks here
|
181 david.dillard 1.43
|
182 mday 1.22 handleEnqueue();
|
183 kumpf 1.25 PEG_METHOD_EXIT();
|
184 mday 1.15 }
185
|
186 david.dillard 1.43 Message* MessageQueue::dequeue()
|
187 mike 1.4 {
|
188 kumpf 1.25 PEG_METHOD_ENTER(TRC_MESSAGEQUEUESERVICE,"MessageQueue::dequeue()");
189
|
190 a.arora 1.38 AutoMutex autoMut(_mut);
|
191 mike 1.4 if (_front)
192 {
|
193 david.dillard 1.43 Message* message = _front;
194 _front = _front->_next;
195 if (_front)
196 _front->_prev = 0;
|
197 mike 1.4
|
198 david.dillard 1.43 if (_back == message)
199 _back = 0;
|
200 kumpf 1.25
|
201 david.dillard 1.43 _count--;
|
202 kumpf 1.25 Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL4,
|
203 david.dillard 1.43 "MessageQueue::dequeue _queueId = %d, _count = %d",
|
204 kumpf 1.26 _queueId, _count);
|
205 kumpf 1.25
|
206 david.dillard 1.43 message->_next = 0;
207 message->_prev = 0;
208 message->_owner = 0;
|
209 kumpf 1.25
210 PEG_METHOD_EXIT();
|
211 david.dillard 1.43 return message;
|
212 mike 1.4 }
|
213 kumpf 1.25
214 PEG_METHOD_EXIT();
|
215 mike 1.4 return 0;
216 }
|
217 mday 1.23
|
218 mike 1.4
|
219 david.dillard 1.43
220 void MessageQueue::remove(Message* message)
|
221 mike 1.4 {
|
222 kumpf 1.25 PEG_METHOD_ENTER(TRC_MESSAGEQUEUESERVICE,"MessageQueue::remove()");
223
|
224 mike 1.4 if (!message)
|
225 kumpf 1.25 {
226 PEG_METHOD_EXIT();
|
227 david.dillard 1.43 throw NullPointer();
|
228 kumpf 1.25 }
|
229 mike 1.4
230 if (message->_owner != this)
|
231 kumpf 1.25 {
232 PEG_METHOD_EXIT();
|
233 david.dillard 1.43 throw NoSuchMessageOnQueue();
|
234 kumpf 1.25 }
|
235 mike 1.4
|
236 a.arora 1.38 {
237 AutoMutex autoMut(_mut);
|
238 chip 1.8
|
239 mike 1.4 if (message->_next)
|
240 david.dillard 1.43 message->_next->_prev = message->_prev;
|
241 mike 1.4 else
|
242 david.dillard 1.43 _back = message->_prev;
|
243 mike 1.4
244 if (message->_prev)
|
245 david.dillard 1.43 message->_prev->_next = message->_next;
|
246 mike 1.4 else
|
247 david.dillard 1.43 _front = message->_next;
|
248 mike 1.4
|
249 mike 1.7 _count--;
|
250 kumpf 1.25 Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL4,
251 "MessageQueue::remove _count = %d", _count);
252
|
253 a.arora 1.38 } // mutex unlocks here
|
254 chip 1.8
|
255 mike 1.4 message->_prev = 0;
256 message->_next = 0;
257 message->_owner = 0;
|
258 kumpf 1.25
259 PEG_METHOD_EXIT();
|
260 mike 1.4 }
261
|
262 david.dillard 1.43 Message* MessageQueue::findByType(Uint32 type)
|
263 mike 1.4 {
|
264 david.dillard 1.43 AutoMutex autoMut(_mut);
|
265 chip 1.8
|
266 mike 1.4 for (Message* m = front(); m; m = m->getNext())
267 {
|
268 david.dillard 1.43 if (m->getType() == type)
269 {
270 return m;
271 }
|
272 mike 1.4 }
|
273 david.dillard 1.43
|
274 mike 1.4 return 0;
275 }
276
|
277 joyce.j 1.44 #ifdef PEGASUS_DEBUG
|
278 david.dillard 1.43 void MessageQueue::print(ostream& os) const
|
279 mike 1.4 {
|
280 david.dillard 1.43 AutoMutex autoMut(const_cast<MessageQueue *>(this)->_mut);
|
281 chip 1.8
|
282 david.dillard 1.43 for (const Message* m = front(); m; m = m->getNext())
283 m->print(os);
|
284 mike 1.4 }
|
285 joyce.j 1.44 #endif
|
286 mike 1.4
|
287 mike 1.7 const char* MessageQueue::getQueueName() const
|
288 mike 1.5 {
|
289 david.dillard 1.43 return _name;
|
290 mike 1.5 }
291
|
292 david.dillard 1.43 MessageQueue* MessageQueue::lookup(Uint32 queueId)
|
293 mike 1.5 {
|
294 kumpf 1.19
|
295 mike 1.5 MessageQueue* queue = 0;
|
296 a.arora 1.38 AutoMutex autoMut(q_table_mut);
|
297 chip 1.8
|
298 mike 1.5 if (_queueTable.lookup(queueId, queue))
|
299 mike 1.7 {
|
300 david.dillard 1.43 return queue;
|
301 mike 1.7 }
|
302 chip 1.8
|
303 mike 1.7 // Not found!
|
304 mike 1.5
|
305 kumpf 1.25 Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL3,
|
306 kumpf 1.42 "MessageQueue::lookup failure queueId = %u", queueId);
|
307 kumpf 1.19
|
308 mike 1.4 return 0;
|
309 mike 1.6 }
|
310 mike 1.7
311
|
312 david.dillard 1.43 MessageQueue* MessageQueue::lookup(const char *name)
|
313 mike 1.7 {
|
314 kumpf 1.19
|
315 david.dillard 1.43 if(name == NULL)
316 throw NullPointer();
|
317 chip 1.8
|
318 david.dillard 1.43 AutoMutex autoMut(q_table_mut);
|
319 mike 1.7 for(QueueTable::Iterator i = _queueTable.start(); i; i++)
320 {
321 // ATTN: Need to decide how many characters to compare in queue names
|
322 david.dillard 1.43 if(! strcmp( ((MessageQueue *)i.value())->getQueueName(), name) )
323 {
324 return( (MessageQueue *)i.value());
325 }
326 }
|
327 chip 1.8
|
328 david.dillard 1.43 Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL3,
329 "MessageQueue::lookup failure - name = %s", name);
|
330 kumpf 1.19
|
331 david.dillard 1.43 return 0;
|
332 mike 1.7 }
333
|
334 mike 1.6
335 void MessageQueue::handleEnqueue()
336 {
337
|
338 mike 1.4 }
339
340 PEGASUS_NAMESPACE_END
|