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.47.12.1 #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.47.12.1 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.47.12.1 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.47.12.1 if (queueId != CIMOM_Q_ID)
75 return _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 david.dillard 1.43 "Message: [%s, %d]",
156 MessageTypeToString(message->getType()),
|
157 kumpf 1.31 message->getKey() );
|
158 david.dillard 1.43
|
159 a.arora 1.38 {
160 AutoMutex autoMut(_mut);
|
161 mike 1.4 if (_back)
162 {
|
163 david.dillard 1.43 _back->_next = message;
164 message->_prev = _back;
165 message->_next = 0;
166 _back = message;
|
167 mike 1.4 }
168 else
169 {
|
170 david.dillard 1.43 _front = message;
171 _back = message;
172 message->_prev = 0;
173 message->_next = 0;
|
174 mike 1.4 }
175 message->_owner = this;
|
176 david.dillard 1.43
|
177 mike 1.4 _count++;
|
178 kumpf 1.25 Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL4,
|
179 david.dillard 1.43 "MessageQueue::enqueue _queueId = %d, _count = %d", _queueId, _count);
180
|
181 a.arora 1.38 } // mutex unlocks here
|
182 david.dillard 1.43
|
183 mday 1.22 handleEnqueue();
|
184 kumpf 1.25 PEG_METHOD_EXIT();
|
185 mday 1.15 }
186
|
187 david.dillard 1.43 Message* MessageQueue::dequeue()
|
188 mike 1.4 {
|
189 kumpf 1.25 PEG_METHOD_ENTER(TRC_MESSAGEQUEUESERVICE,"MessageQueue::dequeue()");
190
|
191 a.arora 1.38 AutoMutex autoMut(_mut);
|
192 mike 1.4 if (_front)
193 {
|
194 david.dillard 1.43 Message* message = _front;
195 _front = _front->_next;
196 if (_front)
197 _front->_prev = 0;
|
198 mike 1.4
|
199 david.dillard 1.43 if (_back == message)
200 _back = 0;
|
201 kumpf 1.25
|
202 david.dillard 1.43 _count--;
|
203 kumpf 1.25 Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL4,
|
204 david.dillard 1.43 "MessageQueue::dequeue _queueId = %d, _count = %d",
|
205 kumpf 1.26 _queueId, _count);
|
206 kumpf 1.25
|
207 david.dillard 1.43 message->_next = 0;
208 message->_prev = 0;
209 message->_owner = 0;
|
210 kumpf 1.25
211 PEG_METHOD_EXIT();
|
212 david.dillard 1.43 return message;
|
213 mike 1.4 }
|
214 kumpf 1.25
215 PEG_METHOD_EXIT();
|
216 mike 1.4 return 0;
217 }
|
218 mday 1.23
|
219 mike 1.4
|
220 david.dillard 1.43
221 void MessageQueue::remove(Message* message)
|
222 mike 1.4 {
|
223 kumpf 1.25 PEG_METHOD_ENTER(TRC_MESSAGEQUEUESERVICE,"MessageQueue::remove()");
224
|
225 mike 1.4 if (!message)
|
226 kumpf 1.25 {
227 PEG_METHOD_EXIT();
|
228 david.dillard 1.43 throw NullPointer();
|
229 kumpf 1.25 }
|
230 mike 1.4
231 if (message->_owner != this)
|
232 kumpf 1.25 {
233 PEG_METHOD_EXIT();
|
234 david.dillard 1.43 throw NoSuchMessageOnQueue();
|
235 kumpf 1.25 }
|
236 mike 1.4
|
237 a.arora 1.38 {
238 AutoMutex autoMut(_mut);
|
239 chip 1.8
|
240 mike 1.4 if (message->_next)
|
241 david.dillard 1.43 message->_next->_prev = message->_prev;
|
242 mike 1.4 else
|
243 david.dillard 1.43 _back = message->_prev;
|
244 mike 1.4
245 if (message->_prev)
|
246 david.dillard 1.43 message->_prev->_next = message->_next;
|
247 mike 1.4 else
|
248 david.dillard 1.43 _front = message->_next;
|
249 mike 1.4
|
250 mike 1.7 _count--;
|
251 kumpf 1.25 Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL4,
252 "MessageQueue::remove _count = %d", _count);
253
|
254 a.arora 1.38 } // mutex unlocks here
|
255 chip 1.8
|
256 mike 1.4 message->_prev = 0;
257 message->_next = 0;
258 message->_owner = 0;
|
259 kumpf 1.25
260 PEG_METHOD_EXIT();
|
261 mike 1.4 }
262
|
263 david.dillard 1.43 Message* MessageQueue::findByType(Uint32 type)
|
264 mike 1.4 {
|
265 david.dillard 1.43 AutoMutex autoMut(_mut);
|
266 chip 1.8
|
267 mike 1.4 for (Message* m = front(); m; m = m->getNext())
268 {
|
269 david.dillard 1.43 if (m->getType() == type)
270 {
271 return m;
272 }
|
273 mike 1.4 }
|
274 david.dillard 1.43
|
275 mike 1.4 return 0;
276 }
277
|
278 david.dillard 1.43 Message* MessageQueue::findByKey(Uint32 key)
|
279 mike 1.4 {
|
280 david.dillard 1.43 AutoMutex autoMut(_mut);
|
281 chip 1.8
|
282 mike 1.4 for (Message* m = front(); m; m = m->getNext())
283 {
|
284 mike 1.7 if (m->getKey() == key)
285 {
|
286 a.arora 1.38 return m;
|
287 mike 1.7 }
|
288 chip 1.8
|
289 mike 1.4 }
|
290 david.dillard 1.43
|
291 mike 1.4 return 0;
292 }
293
|
294 joyce.j 1.44 #ifdef PEGASUS_DEBUG
|
295 david.dillard 1.43 void MessageQueue::print(ostream& os) const
|
296 mike 1.4 {
|
297 david.dillard 1.43 AutoMutex autoMut(const_cast<MessageQueue *>(this)->_mut);
|
298 chip 1.8
|
299 david.dillard 1.43 for (const Message* m = front(); m; m = m->getNext())
300 m->print(os);
|
301 mike 1.4 }
|
302 joyce.j 1.44 #endif
|
303 mike 1.4
|
304 david.dillard 1.43 Message* MessageQueue::find(Uint32 type, Uint32 key)
|
305 mike 1.4 {
|
306 david.dillard 1.43 AutoMutex autoMut(_mut);
|
307 chip 1.8
|
308 mike 1.4 for (Message* m = front(); m; m = m->getNext())
309 {
|
310 david.dillard 1.43 if (m->getType() == type && m->getKey() == key)
311 {
312 return m;
313 }
|
314 mike 1.4 }
315
|
316 mike 1.5 return 0;
317 }
318
|
319 mike 1.7 const char* MessageQueue::getQueueName() const
|
320 mike 1.5 {
|
321 david.dillard 1.43 return _name;
|
322 mike 1.5 }
323
|
324 david.dillard 1.43 MessageQueue* MessageQueue::lookup(Uint32 queueId)
|
325 mike 1.5 {
|
326 kumpf 1.19
|
327 mike 1.5 MessageQueue* queue = 0;
|
328 a.arora 1.38 AutoMutex autoMut(q_table_mut);
|
329 chip 1.8
|
330 mike 1.5 if (_queueTable.lookup(queueId, queue))
|
331 mike 1.7 {
|
332 david.dillard 1.43 return queue;
|
333 mike 1.7 }
|
334 chip 1.8
|
335 mike 1.7 // Not found!
|
336 mike 1.5
|
337 kumpf 1.25 Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL3,
|
338 kumpf 1.42 "MessageQueue::lookup failure queueId = %u", queueId);
|
339 kumpf 1.19
|
340 mike 1.4 return 0;
|
341 mike 1.6 }
|
342 mike 1.7
343
|
344 david.dillard 1.43 MessageQueue* MessageQueue::lookup(const char *name)
|
345 mike 1.7 {
|
346 kumpf 1.19
|
347 david.dillard 1.43 if(name == NULL)
348 throw NullPointer();
|
349 chip 1.8
|
350 david.dillard 1.43 AutoMutex autoMut(q_table_mut);
|
351 mike 1.7 for(QueueTable::Iterator i = _queueTable.start(); i; i++)
352 {
353 // ATTN: Need to decide how many characters to compare in queue names
|
354 david.dillard 1.43 if(! strcmp( ((MessageQueue *)i.value())->getQueueName(), name) )
355 {
356 return( (MessageQueue *)i.value());
357 }
358 }
|
359 chip 1.8
|
360 david.dillard 1.43 Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL3,
361 "MessageQueue::lookup failure - name = %s", name);
|
362 kumpf 1.19
|
363 david.dillard 1.43 return 0;
|
364 mike 1.7 }
365
|
366 mike 1.6
367 void MessageQueue::handleEnqueue()
368 {
369
|
370 mike 1.4 }
371
372 PEGASUS_NAMESPACE_END
|