1 karl 1.53 //%2005////////////////////////////////////////////////////////////////////////
|
2 mday 1.1 //
|
3 karl 1.51 // 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.49 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.51 // 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.53 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 mday 1.1 //
12 // Permission is hereby granted, free of charge, to any person obtaining a copy
13 // of this software and associated documentation files (the "Software"), to
14 // deal in the Software without restriction, including without limitation the
15 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16 // sell copies of the Software, and to permit persons to whom the Software is
17 // furnished to do so, subject to the following conditions:
|
18 kumpf 1.41 //
|
19 mday 1.1 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
20 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
21 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
22 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
23 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 //==============================================================================
29 //
30 // Author: Mike Day (mdday@us.ibm.com)
31 //
|
32 joyce.j 1.52 // Modified By: Josephine Eskaline Joyce (jojustin@in.ibm.com) for PEP#101
|
33 mday 1.1 //
34 //%/////////////////////////////////////////////////////////////////////////////
35
36 #include "Cimom.h"
37
|
38 chip 1.6 #include <iostream>
|
39 kumpf 1.33 #include <Pegasus/Common/Constants.h>
|
40 kumpf 1.31 #include <Pegasus/Common/Tracer.h>
|
41 joyce.j 1.52 #include <Pegasus/Common/AutoPtr.h>
|
42 mday 1.1
43 PEGASUS_NAMESPACE_BEGIN
44
|
45 chip 1.6 PEGASUS_USING_STD;
46
|
47 mday 1.15 const Uint32 CIMOM_Q_ID = 1;
48
|
49 mday 1.26 Uint32 module_capabilities::async = 0x00000001;
50 Uint32 module_capabilities::remote = 0x00000002;
51 Uint32 module_capabilities::trusted = 0x00000004;
52 Uint32 module_capabilities::paused = 0x00000008;
53 Uint32 module_capabilities::stopped = 0x00000010;
54 Uint32 module_capabilities::module_controller = 0x00000020;
|
55 mday 1.12
|
56 mday 1.1
57
58 const String & message_module::get_name(void) const { return _name ; }
59 Uint32 message_module::get_capabilities(void) const { return _capabilities ; }
60 Uint32 message_module::get_mask(void) const { return _mask ; }
61 Uint32 message_module::get_queue(void) const { return _q_id ; }
62 void message_module::put_name(String & name) { _name.clear(); _name = name; }
63 void message_module::put_capabilities(Uint32 capabilities) { _capabilities = capabilities; }
64 void message_module::put_mask(Uint32 mask) { _mask = mask; }
65 void message_module::put_queue(Uint32 queue) { _q_id = queue; }
66
67
68 Boolean message_module::operator ==(Uint32 q) const
69 {
70 if(this->_q_id == q)
71 return true;
72 return false;
73 }
74
|
75 chip 1.6 Boolean message_module::operator == (const message_module *mm) const
|
76 mday 1.1 {
77 if(this == mm)
78 return true;
79 return false;
80 }
81
82
|
83 chip 1.6 Boolean message_module::operator == (const String & name ) const
|
84 mday 1.1 {
85 if(name == this->_name)
86 return true;
87 return false;
|
88 chip 1.6
|
89 mday 1.1 }
90
91 Boolean message_module::operator == (const message_module & mm) const
92 {
|
93 kumpf 1.46 if(this == &mm)
|
94 mday 1.1 return true;
95 if( _name == mm._name )
96 if ( _capabilities == mm._capabilities)
97 if(_mask == mm._mask)
98 if(_q_id == mm._q_id)
99 return true;
|
100 chip 1.6
|
101 mday 1.1 return false;
|
102 chip 1.6
|
103 mday 1.1 }
104
105 Boolean message_module::operator == (const void *key) const
106 {
107 return operator == ( (*(reinterpret_cast<const message_module *>(key) ) ) );
108 }
109
110 AtomicInt cimom::_xid(0);
111
|
112 mday 1.5 Boolean cimom::route_async(AsyncOpNode *op)
113 {
114
|
115 mday 1.11
116 if( _die.value()> 0 )
117 return false;
118
119 if( _routed_queue_shutdown.value() > 0 )
|
120 mday 1.5 return false;
|
121 mday 1.11
|
122 mday 1.9 _routed_ops.insert_last_wait(op);
|
123 mday 1.7
|
124 mday 1.5 return true;
|
125 chip 1.6
|
126 mday 1.5 }
127
|
128 mday 1.10 void cimom::_shutdown_routed_queue(void)
129 {
|
130 mday 1.11
131 if (_routed_queue_shutdown.value() > 0 )
132 return ;
133
|
134 joyce.j 1.52 AutoPtr<AsyncIoctl> msg(new AsyncIoctl(get_xid(),
|
135 mday 1.11 0,
136 CIMOM_Q_ID,
137 CIMOM_Q_ID,
138 true,
139 AsyncIoctl::IO_CLOSE,
140 0,
|
141 joyce.j 1.52 0));
|
142 mday 1.11 msg->op = get_cached_op();
|
143 mday 1.35
144 msg->op->_flags |= ASYNC_OPFLAGS_FIRE_AND_FORGET;
145 msg->op->_flags &= ~(ASYNC_OPFLAGS_CALLBACK | ASYNC_OPFLAGS_SAFE_CALLBACK
146 | ASYNC_OPFLAGS_SIMPLE_STATUS);
147 msg->op->_state &= ~ASYNC_OPSTATE_COMPLETE;
148 msg->op->_op_dest = _global_this;
|
149 joyce.j 1.52 msg->op->_request.insert_first(msg.get());
|
150 mday 1.35
|
151 mday 1.11 _routed_ops.insert_last_wait(msg->op);
|
152 mday 1.35 _routing_thread.join();
|
153 joyce.j 1.52 msg.release();
|
154 mday 1.10
155 }
156
|
157 mday 1.5
158 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL cimom::_routing_proc(void *parm)
159 {
160
161 Thread *myself = reinterpret_cast<Thread *>(parm);
162 cimom *dispatcher = reinterpret_cast<cimom *>(myself->get_parm());
|
163 mday 1.10 AsyncOpNode *op = 0;
164
|
165 mday 1.9 while( dispatcher->_die.value() == 0 )
|
166 mday 1.5 {
|
167 mday 1.10 try
168 {
|
169 mday 1.11 op = dispatcher->_routed_ops.remove_first_wait();
|
170 mday 1.10 }
171 catch(ListClosed & )
172 {
|
173 mday 1.9 break;
|
174 mday 1.10 }
|
175 mday 1.7
|
176 mday 1.10 if (op == 0 )
|
177 mday 1.5 {
|
178 mday 1.11 break;
|
179 mday 1.5 }
|
180 mday 1.10 else
|
181 mday 1.5 {
|
182 mday 1.12 Uint32 capabilities = 0;
183 Uint32 code = 0;
184
|
185 mday 1.16
186 // ATTN: optimization
187 // <<< Sun Feb 17 18:26:39 2002 mdd >>>
188 // once the opnode is enqueued on the cimom's list, the cimom owns it
189 // and no one is allowed to write to it but the cimom.
190 // services are only allowed to read status bits
191 // this can eliminate the need for the lock/unlock
192 // unles reading/writing status bits
193
|
194 mday 1.10 op->lock();
|
195 mday 1.18 MessageQueue *dest_q = op->_op_dest;
196 Uint32 dest_qid = dest_q->getQueueId();
|
197 mday 1.10 op->unlock();
198
199 Boolean accepted = false;
200
|
201 mday 1.18 if(dest_qid == CIMOM_Q_ID )
|
202 mday 1.10 {
|
203 mday 1.11 dispatcher->_handle_cimom_op(op, myself, dispatcher);
|
204 mday 1.10 accepted = true;
205 }
206 else
207 {
|
208 mday 1.16 // ATTN: optimization
209 // <<< Sun Feb 17 18:29:26 2002 mdd >>>
210 // this lock/loop/unlock is really just a safety check to ensure
211 // the service is registered with the meta dispatcher.
212 // if speed is an issue we can remove this lookup
213 // because we have converted to MessageQueueService from
|
214 mday 1.21 // MessageQueue, and because we register in the constructor,
|
215 mday 1.16 // the safety check is unecessary
|
216 mday 1.18 //
217 // << Tue Feb 19 11:40:37 2002 mdd >>
|
218 mday 1.21 // moved the lookup to sendwait/nowait/forget/forward functions.
|
219 mday 1.16
|
220 mday 1.19 MessageQueueService *dest_svc = 0;
221
222 if ( dest_q->get_capabilities() & module_capabilities::async)
223 {
224 dest_svc= static_cast<MessageQueueService *>(dest_q);
225 }
|
226 mday 1.12
|
227 mday 1.18 if(dest_svc != 0)
|
228 mday 1.5 {
|
229 mday 1.19 if( dest_svc->get_capabilities() & module_capabilities::paused ||
230 dest_svc->get_capabilities() & module_capabilities::stopped )
|
231 mday 1.12 {
232 // the target is stopped or paused
233 // unless the message is a start or resume
|
234 mday 1.16 // just handle it from here.
|
235 mday 1.18 op->lock();
236 AsyncRequest *request = static_cast<AsyncRequest *>(op->_request.next(0));
237 op->unlock();
238 code = request->getType();
239
240 if (code != async_messages::CIMSERVICE_START &&
241 code != async_messages::CIMSERVICE_RESUME )
|
242 mday 1.12 {
|
243 mday 1.19 if ( dest_svc->get_capabilities() & module_capabilities::paused )
|
244 mday 1.18 dispatcher->_make_response(request, async_results::CIM_PAUSED);
245 else
246 dispatcher->_make_response(request, async_results::CIM_STOPPED);
247 accepted = true;
|
248 mday 1.12 }
|
249 mday 1.18 else // deliver the start or resume message
250 accepted = dest_svc->accept_async(op);
|
251 mday 1.12 }
|
252 mday 1.14 else
|
253 mday 1.18 accepted = dest_svc->accept_async(op);
|
254 mday 1.5 }
|
255 mday 1.10 if ( accepted == false )
256 {
|
257 mday 1.18 // set completion code to NAK and flag completed
258 _complete_op_node(op, ASYNC_OPSTATE_COMPLETE,
259 ASYNC_OPFLAGS_SIMPLE_STATUS,
260 async_results::CIM_NAK);
|
261 mday 1.10 }
|
262 mday 1.7 }
|
263 mday 1.42
|
264 mday 1.5 }
|
265 mday 1.7 } // loop
|
266 mday 1.5 myself->exit_self( (PEGASUS_THREAD_RETURN) 1 );
267 return(0);
268 }
269
270
|
271 mday 1.1
272 cimom::cimom(void)
|
273 kumpf 1.33 : MessageQueue(PEGASUS_QUEUENAME_METADISPATCHER, true, CIMOM_Q_ID ),
|
274 chip 1.6 _modules(true),
|
275 mday 1.1 _recycle(true),
|
276 mday 1.24 _routed_ops(true, 0),
|
277 mday 1.7 _internal_ops(true),
|
278 mday 1.5 _routing_thread( _routing_proc, this, false),
|
279 mday 1.10 _die(0), _routed_queue_shutdown(0)
|
280 chip 1.6 {
|
281 mday 1.19 _capabilities |= module_capabilities::async;
282
|
283 mday 1.18 _global_this = static_cast<cimom *>(MessageQueue::lookup(CIMOM_Q_ID));
284
|
285 mday 1.1 pegasus_gettimeofday(&_last_module_change);
286 _default_op_timeout.tv_sec = 30;
287 _default_op_timeout.tv_usec = 100;
|
288 kumpf 1.50 while (!_routing_thread.run())
289 {
290 pegasus_yield();
291 }
|
292 chip 1.6
|
293 mday 1.1 }
294
295
296 Uint32 cimom::get_xid(void)
297 {
298 _xid++;
299 return _xid.value();
300 }
301
302 cimom::~cimom(void)
303 {
|
304 mday 1.2
305 // send STOP messages to all modules
306 // shutdown legacy queues; e.g., cim operation dispatcher etc.
|
307 mday 1.1 _die++;
|
308 mday 1.10 if (_routed_queue_shutdown.value() == 0 )
309 _routed_ops.shutdown_queue();
|
310 mday 1.5 _routing_thread.join();
|
311 kumpf 1.45
312 while (_modules.count())
313 {
314 delete _modules.remove_first();
315 }
|
316 mday 1.7 _modules.empty_list();
317
|
318 mday 1.1 return;
319 }
|
320 mday 1.12
|
321 mday 1.16 void cimom::_make_response(Message *req, Uint32 code)
|
322 mday 1.12 {
|
323 mday 1.16
324 if ( ! (req->getMask() & message_mask::ha_async) )
325 {
326 // legacy message, just delete
327
328 delete req;
329 return;
330 }
331
332 if( (static_cast<AsyncRequest *>(req))->op->_flags & ASYNC_OPFLAGS_FIRE_AND_FORGET )
333 {
334 // destructor empties request list
335 delete (static_cast<AsyncRequest *>(req))->op;
336 return;
337 }
338
|
339 joyce.j 1.52 AutoPtr<AsyncReply> reply ;
|
340 mday 1.16 if ( ! ((static_cast<AsyncRequest *>(req))->op->_flags & ASYNC_OPFLAGS_SIMPLE_STATUS) )
341 {
|
342 mday 1.27
|
343 joyce.j 1.52 reply.reset(new AsyncReply(async_messages::REPLY,
|
344 mday 1.16 req->getKey(),
345 req->getRouting(),
346 0,
347 (static_cast<AsyncRequest *>(req))->op,
348 code,
349 (static_cast<AsyncRequest *>(req))->resp,
|
350 joyce.j 1.52 false));
|
351 mday 1.16 }
|
352 mday 1.27 else
|
353 mday 1.16 (static_cast<AsyncRequest *>(req))->op->_completion_code = code;
|
354 mday 1.27 // sender does not want a reply message, just the
355 // _completion_code field in the AsyncOpNode.
356
|
357 mday 1.16
|
358 joyce.j 1.52 _completeAsyncResponse(static_cast<AsyncRequest *>(req), reply.get(), ASYNC_OPSTATE_COMPLETE, 0 );
359 reply.release();
|
360 mday 1.12 }
|
361 mday 1.5
|
362 chip 1.6 void cimom::_completeAsyncResponse(AsyncRequest *request,
363 AsyncReply *reply,
364 Uint32 state,
|
365 mday 1.5 Uint32 flag)
|
366 mday 1.1 {
|
367 kumpf 1.31 PEG_METHOD_ENTER(TRC_MESSAGEQUEUESERVICE,
368 "cimom::_completeAsyncResponse");
369
|
370 mday 1.16 PEGASUS_ASSERT(request != 0);
|
371 chip 1.6
|
372 kumpf 1.32 Boolean haveLock = false;
373
|
374 mday 1.5 AsyncOpNode *op = request->op;
|
375 mday 1.1 op->lock();
|
376 kumpf 1.32 haveLock = true;
|
377 mday 1.19
|
378 mday 1.34 if ( (op->_flags & ASYNC_OPFLAGS_CALLBACK ||
379 op->_flags & ASYNC_OPFLAGS_SAFE_CALLBACK ) &&
380 (! (op->_flags & ASYNC_OPFLAGS_PSEUDO_CALLBACK)) )
|
381 mday 1.27 {
382 op->unlock();
|
383 kumpf 1.32 haveLock = false;
|
384 mday 1.27 if ( (reply != 0) && (false == op->_response.exists(reinterpret_cast<void *>(reply))) )
385 op->_response.insert_last(reply);
386 _complete_op_node(op, state, flag, (reply ? reply->result : 0 ));
|
387 mday 1.44 return;
|
388 mday 1.27 }
389
390
|
391 mday 1.19 if( op->_flags & ASYNC_OPFLAGS_FIRE_AND_FORGET )
392 {
393
394 // destructor empties request list
395 op->unlock();
|
396 kumpf 1.32 haveLock = false;
|
397 mday 1.19
|
398 mday 1.37 op->release();
|
399 mday 1.43 _global_this->cache_op(op);
|
400 mday 1.37
|
401 kumpf 1.31 PEG_METHOD_EXIT();
|
402 mday 1.19 return;
403 }
404
|
405 mday 1.17 op->_state |= (state | ASYNC_OPSTATE_COMPLETE);
|
406 mday 1.5 op->_flags |= flag;
407 gettimeofday(&(op->_updated), NULL);
|
408 mday 1.19 if ( op->_flags & ASYNC_OPFLAGS_SIMPLE_STATUS )
409 {
|
410 mday 1.20 PEGASUS_ASSERT(reply != 0 );
411
|
412 mday 1.19 op->_completion_code = reply->result;
|
413 kumpf 1.31 PEG_METHOD_EXIT();
|
414 mday 1.19 delete reply;
415 }
416 else
417 {
418 if ( (reply != 0) && (false == op->_response.exists(reinterpret_cast<void *>(reply))) )
419 op->_response.insert_last(reply);
420 }
421
|
422 kumpf 1.32 if (haveLock)
423 {
424 op->unlock();
425 haveLock = false;
426 }
|
427 mday 1.7 op->_client_sem.signal();
|
428 kumpf 1.31 PEG_METHOD_EXIT();
|
429 mday 1.1 }
430
|
431 mday 1.18 cimom *cimom::_global_this;
432
433
434 void cimom::_default_callback(AsyncOpNode *op, MessageQueue *q, void *ptr)
435 {
436 PEGASUS_ASSERT(op != 0 && q != 0);
|
437 mday 1.22 return;
|
438 mday 1.18 }
439
440
441 void cimom::_complete_op_node(AsyncOpNode *op, Uint32 state, Uint32 flag, Uint32 code)
442 {
443
444 Uint32 flags;
445
446 op->lock();
447
448 op->_completion_code = code;
449 op->_state |= (state | ASYNC_OPSTATE_COMPLETE);
450 flags = (op->_flags |= flag);
451 op->unlock();
452 if ( flags & ASYNC_OPFLAGS_FIRE_AND_FORGET )
453 {
454 delete op;
455 return;
456 }
457
|
458 mday 1.34 if ( (flags & ASYNC_OPFLAGS_CALLBACK) && (! (flags & ASYNC_OPFLAGS_PSEUDO_CALLBACK)))
|
459 mday 1.18 {
|
460 mday 1.47
461 // << Wed Oct 8 12:29:32 2003 mdd >>
462 // check to see if the response queue is stopped or paused
463 if( op->_callback_response_q == 0 ||
464 op->_callback_response_q->get_capabilities() & module_capabilities::paused ||
465 op->_callback_response_q->get_capabilities() & module_capabilities::stopped )
466 {
467 // delete, respondent is paused or stopped
468 delete op;
469 return;
470 }
471
|
472 mday 1.22 // send this node to the response queue
473 op->_op_dest = op->_callback_response_q;
474 _global_this->route_async(op);
|
475 mday 1.18 return;
476 }
|
477 mday 1.34 if((flags & ASYNC_OPFLAGS_SAFE_CALLBACK ) && (! (flags & ASYNC_OPFLAGS_PSEUDO_CALLBACK)))
478 {
479 return;
480 }
|
481 mday 1.18 op->_client_sem.signal();
482 return;
483 }
484
|
485 mday 1.1
486 void cimom::handleEnqueue(void)
487 {
488
489 Message* msg = dequeue();
|
490 chip 1.6
|
491 mday 1.1 if (!msg)
492 return;
|
493 chip 1.6
|
494 mday 1.1 return;
495 }
496
|
497 chip 1.6
|
498 mday 1.11 void cimom::_handle_cimom_op(AsyncOpNode *op, Thread *thread, MessageQueue *queue)
|
499 mday 1.1 {
|
500 mday 1.5 if(op == 0)
|
501 mday 1.1 return;
|
502 mday 1.18
503 // ATTN: optimization << Tue Feb 19 11:33:21 2002 mdd >>
504 // do away with the lock/unlock
|
505 mday 1.9 op->lock();
506 Message *msg = op->_request.next(0);
507 op->unlock();
508
|
509 mday 1.5 if ( msg == 0 )
510 return;
|
511 chip 1.6
|
512 mday 1.5 Boolean accepted = false;
|
513 chip 1.6
|
514 mday 1.1 Uint32 mask = msg->getMask();
515 Uint32 type = msg->getType();
|
516 mday 1.18 if ( ! (mask & message_mask::ha_async) )
517 {
518 _make_response(msg, async_results::CIM_NAK);
519 }
|
520 mday 1.25 op->_thread_ptr = thread;
521 op->_service_ptr = queue;
|
522 mday 1.18
|
523 mday 1.5 if( mask & message_mask::ha_request)
|
524 mday 1.1 {
|
525 mday 1.11 op->processing();
|
526 mday 1.5 accepted = true;
|
527 chip 1.6
|
528 mday 1.5 if( type == async_messages::REGISTER_CIM_SERVICE )
529 register_module(static_cast<RegisterCimService *>(msg));
530 else if ( type == async_messages::UPDATE_CIM_SERVICE )
531 update_module(static_cast<UpdateCimService *>(msg ));
532 else if ( type == async_messages::IOCTL )
533 ioctl(static_cast<AsyncIoctl *>(msg));
534 else if ( type == async_messages::FIND_SERVICE_Q )
535 find_service_q(static_cast<FindServiceQueue *>(msg));
536 else if (type == async_messages::ENUMERATE_SERVICE)
537 enumerate_service(static_cast<EnumerateService *>(msg));
|
538 mday 1.28 else if (type == async_messages::FIND_MODULE_IN_SERVICE)
539 _find_module_in_service(static_cast<FindModuleInService *>(msg));
540 else if (type == async_messages::REGISTERED_MODULE)
541 _registered_module_in_service(static_cast<RegisteredModule *>(msg));
542 else if (type == async_messages::DEREGISTERED_MODULE)
543 _deregistered_module_in_service(static_cast<DeRegisteredModule *>(msg));
|
544 mday 1.5 }
545 if ( accepted == false )
546 {
|
547 mday 1.17 _make_response(msg, async_results::CIM_NAK);
|
548 mday 1.1 }
|
549 chip 1.6
|
550 mday 1.1 }
551
552
553 void cimom::register_module(RegisterCimService *msg)
554 {
555 // first see if the module is already registered
556 Uint32 result = async_results::OK;
557
|
558 chip 1.6
|
559 mday 1.1 if( 0 != get_module_q(msg->name))
560 result = async_results::MODULE_ALREADY_REGISTERED;
|
561 chip 1.6 else
|
562 mday 1.1 {
|
563 chip 1.6
|
564 joyce.j 1.52 AutoPtr<message_module> new_mod(new message_module(msg->name,
|
565 chip 1.6 msg->capabilities,
566 msg->mask,
|
567 joyce.j 1.52 msg->queue));
568 if(new_mod.get() == 0 )
|
569 mday 1.1 result = async_results::INTERNAL_ERROR;
570 else
571 {
572 try
573 {
|
574 joyce.j 1.52 _modules.insert_first(new_mod.get());
|
575 mday 1.1 }
576 catch(IPCException&)
577 {
578 result = async_results::INTERNAL_ERROR;
|
579 joyce.j 1.52 new_mod.reset();
|
580 mday 1.1 }
581 }
|
582 joyce.j 1.52 new_mod.release();
|
583 mday 1.1 }
|
584 chip 1.6
|
585 joyce.j 1.52 AutoPtr<AsyncReply> reply(new AsyncReply(async_messages::REPLY,
|
586 mday 1.1 msg->getKey(),
587 msg->getRouting(),
|
588 chip 1.6 0,
|
589 mday 1.1 msg->op,
|
590 chip 1.6 result,
591 msg->resp,
|
592 joyce.j 1.52 msg->block));
|
593 chip 1.6
594 _completeAsyncResponse(static_cast<AsyncRequest *>(msg),
|
595 joyce.j 1.52 reply.get(),
|
596 chip 1.6 ASYNC_OPSTATE_COMPLETE,
|
597 mday 1.5 0);
|
598 joyce.j 1.52 reply.release();
|
599 mday 1.1 return;
600 }
601
602
|
603 mday 1.3 void cimom::deregister_module(Uint32 quid)
604 {
605
606 _modules.lock();
|
607 chip 1.6
|
608 mday 1.3 message_module *temp = _modules.next(0);
609 while( temp != 0 )
610 {
611 if (temp->_q_id == quid)
612 {
613 _modules.remove_no_lock(temp);
614 break;
615 }
616 temp = _modules.next(temp);
617 }
618 _modules.unlock();
|
619 mday 1.1 }
620
621
622 void cimom::update_module(UpdateCimService *msg )
623 {
624 Uint32 result = async_results::MODULE_NOT_FOUND;
|
625 chip 1.6
|
626 mday 1.1 _modules.lock();
627 message_module *temp = _modules.next(0);
628 while( temp != 0 )
629 {
630 if(temp->_q_id == msg->queue )
631 {
632 temp->_capabilities = msg->capabilities;
633 temp->_mask = msg->mask;
634 gettimeofday(&(temp->_heartbeat), NULL);
635 result = async_results::OK;
636 break;
637 }
638 temp = _modules.next(temp);
639 }
|
640 mday 1.14 _modules.unlock();
|
641 mday 1.1
|
642 joyce.j 1.52 AutoPtr<AsyncReply> reply(new AsyncReply(async_messages::REPLY,
|
643 chip 1.6 msg->getKey(),
|
644 mday 1.1 msg->getRouting(),
|
645 chip 1.6 0,
646 msg->op,
647 result,
|
648 mday 1.1 msg->resp,
|
649 joyce.j 1.52 msg->block));
|
650 chip 1.6 _completeAsyncResponse(static_cast<AsyncRequest *>(msg),
|
651 joyce.j 1.52 reply.get(),
|
652 chip 1.6 ASYNC_OPSTATE_COMPLETE,
|
653 mday 1.5 0);
|
654 joyce.j 1.52 reply.release();
|
655 mday 1.3 return;
|
656 mday 1.1 }
657
658
659 void cimom::ioctl(AsyncIoctl *msg)
660 {
661
|
662 mday 1.11 switch(msg->ctl)
663 {
664 case AsyncIoctl::IO_CLOSE:
665 {
666 // save my bearings
|
667 mday 1.25 Thread *myself = msg->op->_thread_ptr;
668 cimom *service = static_cast<cimom *>(msg->op->_service_ptr);
|
669 mday 1.11
670 // respond to this message.
|
671 joyce.j 1.52 AutoPtr<AsyncReply> reply(new AsyncReply( async_messages::REPLY,
|
672 mday 1.11 msg->getKey(),
673 msg->getRouting(),
674 0,
675 msg->op,
676 async_results::OK,
677 msg->resp,
|
678 joyce.j 1.52 msg->block));
|
679 mday 1.11 _completeAsyncResponse(static_cast<AsyncRequest *>(msg),
|
680 joyce.j 1.52 reply.get(),
|
681 mday 1.11 ASYNC_OPSTATE_COMPLETE,
682 0);
|
683 joyce.j 1.52 reply.release();
|
684 mday 1.11 // ensure we do not accept any further messages
685
686 // ensure we don't recurse on IO_CLOSE
687 if( _routed_queue_shutdown.value() > 0 )
688 break;
689
690 // set the closing flag
691 service->_routed_queue_shutdown = 1;
692 // empty out the queue
693 while( 1 )
694 {
695 AsyncOpNode *operation;
696 try
697 {
698 operation = service->_routed_ops.remove_first();
699 }
700 catch(IPCException & )
701 {
702 break;
703 }
704 if( operation )
705 mday 1.11 {
706 service->_handle_cimom_op(operation, myself, service);
707 }
708 else
709 break;
710 } // message processing loop
|
711 chip 1.6
|
712 mday 1.11 // shutdown the AsyncDQueue
713 service->_routed_ops.shutdown_queue();
714 // exit the thread !
715 myself->exit_self( (PEGASUS_THREAD_RETURN) 1 );
716 return;
717 }
718
719 default:
720 {
721 Uint32 result = _ioctl(msg->ctl, msg->intp, msg->voidp);
|
722 joyce.j 1.52 AutoPtr<AsyncReply> reply(new AsyncReply( async_messages::REPLY,
|
723 mday 1.11 msg->getKey(),
724 msg->getRouting(),
725 0,
726 msg->op,
727 result,
728 msg->resp,
|
729 joyce.j 1.52 msg->block));
|
730 mday 1.11 _completeAsyncResponse(static_cast<AsyncRequest *>(msg),
|
731 joyce.j 1.52 reply.get(),
|
732 mday 1.11 ASYNC_OPSTATE_COMPLETE,
733 0);
|
734 joyce.j 1.52 reply.release();
|
735 mday 1.11 }
736 }
|
737 mday 1.1 }
738
739
740 Uint32 cimom::_ioctl(Uint32 code, Uint32 int_param, void *pointer_param)
741 {
742 return async_results::OK;
743 }
744
745 // fill an array with queue IDs of as many registered services
746 // as match the request message parameters
747 void cimom::find_service_q(FindServiceQueue *msg)
748 {
749
|
750 chip 1.6
|
751 mday 1.1 Array<Uint32> found;
|
752 chip 1.6
|
753 mday 1.1 _modules.lock();
754 message_module *ret = _modules.next( 0 );
755 while( ret != 0 )
756 {
757 if( msg->name.size() > 0 )
758 {
759 if( msg->name != ret->_name )
760 {
761 ret = _modules.next(ret);
762 continue;
763 }
764 }
765
766 if(msg->capabilities != 0 )
767 {
768 if (! msg->capabilities & ret->_capabilities)
769 {
770 ret = _modules.next(ret);
771 continue;
772 }
773 }
774 mday 1.1 if(msg->mask != 0 )
775 {
776 if ( ! msg->mask & ret->_mask )
777 {
778 ret = _modules.next(ret);
779 continue;
780 }
781 }
|
782 chip 1.6
783 // if we get to here, we "found" this service
|
784 mday 1.1
785 found.append(ret->_q_id);
786 ret = _modules.next(ret);
787 }
788 _modules.unlock();
789
|
790 joyce.j 1.52 AutoPtr<FindServiceQueueResult> reply(
|
791 chip 1.6 new FindServiceQueueResult( msg->getKey(),
792 msg->getRouting(),
793 msg->op,
794 async_results::OK,
795 msg->resp,
796 msg->block,
|
797 joyce.j 1.52 found));
|
798 mday 1.5
|
799 chip 1.6 _completeAsyncResponse(static_cast<AsyncRequest *>(msg),
|
800 joyce.j 1.52 reply.get(),
|
801 chip 1.6 ASYNC_OPSTATE_COMPLETE,
|
802 mday 1.5 0);
|
803 joyce.j 1.52 reply.release();
|
804 mday 1.1 return;
805 }
806
807
|
808 chip 1.6 // given a service Queue ID, return all registation data for
809 // that service
|
810 mday 1.1 void cimom::enumerate_service(EnumerateService *msg)
811 {
812
|
813 joyce.j 1.52 AutoPtr<EnumerateServiceResponse> reply;
|
814 mday 1.1 _modules.lock();
815 message_module *ret = _modules.next( 0 );
|
816 chip 1.6
|
817 mday 1.1 while( ret != 0 )
818 {
819 if( ret->_q_id == msg->qid )
820 {
|
821 joyce.j 1.52 reply.reset(new EnumerateServiceResponse(msg->getKey(),
|
822 chip 1.6 msg->getRouting(),
823 msg->op,
824 async_results::OK,
825 msg->resp,
826 msg->block,
827 ret->_name,
828 ret->_capabilities,
829 ret->_mask,
|
830 joyce.j 1.52 ret->_q_id));
|
831 mday 1.1 break;
832 }
833 ret = _modules.next(ret);
834 }
835 _modules.unlock();
|
836 chip 1.6
|
837 joyce.j 1.52 if(reply.get() == 0 )
|
838 mday 1.1 {
|
839 joyce.j 1.52 reply.reset(new EnumerateServiceResponse(msg->getKey(),
|
840 chip 1.6 msg->getRouting(),
841 msg->op,
842 async_results::MODULE_NOT_FOUND,
843 msg->resp,
844 msg->block,
845 String(),
|
846 joyce.j 1.52 0, 0, 0));
|
847 mday 1.1 }
|
848 chip 1.6
849 _completeAsyncResponse(static_cast<AsyncRequest *>(msg),
|
850 joyce.j 1.52 reply.get(),
|
851 chip 1.6 ASYNC_OPSTATE_COMPLETE,
|
852 mday 1.5 0);
|
853 joyce.j 1.52 reply.release();
|
854 mday 1.5
|
855 mday 1.1 return;
856 }
857
858 Uint32 cimom::get_module_q(const String & name)
859 {
860 _modules.lock();
861 message_module *ret = _modules.next( 0 );
862 while( ret != 0 )
863 {
864 if (ret->_name == name)
865 break;
866 ret = _modules.next(ret);
867 }
868
869 _modules.unlock();
870 if(ret != 0 )
871 return ret->_q_id;
872 else
873 return 0 ;
874 }
875
876 mday 1.1
877
878 // returns true if the list of registered modules changes since the parameter
879 Boolean cimom::moduleChange(struct timeval last)
880 {
|
881 chip 1.6 if( (last.tv_sec >= _last_module_change.tv_sec))
|
882 mday 1.1 if(last.tv_usec >= _last_module_change.tv_usec )
883 return false;
884 return true;
885 }
886
887
|
888 chip 1.6 Uint32 cimom::getModuleCount(void)
|
889 mday 1.1 {
890 return _modules.count();
891 }
892
893 Uint32 cimom::getModuleIDs(Uint32 *ids, Uint32 count) throw(IPCException)
894 {
895
896 if(ids == 0)
897 return 0;
|
898 chip 1.6
|
899 mday 1.1 message_module *temp = 0;
900 _modules.lock();
901 temp = _modules.next(temp);
902 while( temp != 0 && count > 0 )
903 {
904 *ids = temp->_q_id;
905 ids++;
906 count--;
907 temp = _modules.next(temp);
908 }
909 _modules.unlock();
910
911 while( count > 0 )
912 {
913 *ids = 0;
914 ids++;
915 count--;
916 }
|
917 chip 1.6
|
918 mday 1.1 return _modules.count();
919 }
920
921 AsyncOpNode *cimom::get_cached_op(void) throw(IPCException)
922 {
|
923 mday 1.11
|
924 joyce.j 1.52 AutoPtr<AsyncOpNode> op(new AsyncOpNode());
|
925 mday 1.11
926 op->_state = ASYNC_OPSTATE_UNKNOWN;
927 op->_flags = ASYNC_OPFLAGS_SINGLE | ASYNC_OPFLAGS_NORMAL | ASYNC_OPFLAGS_META_DISPATCHER;
928
|
929 joyce.j 1.52 return op.release();
|
930 mday 1.1 }
931
932 void cimom::cache_op(AsyncOpNode *op) throw(IPCException)
933 {
934 PEGASUS_ASSERT(op->read_state() & ASYNC_OPSTATE_RELEASED );
|
935 mday 1.3 delete op;
|
936 mday 1.1 }
937
938 void cimom::set_default_op_timeout(const struct timeval *buffer)
939 {
940 if (buffer != 0)
941 {
942 _default_op_timeout.tv_sec = buffer->tv_sec;
943 _default_op_timeout.tv_usec = buffer->tv_usec;
944 }
945 return;
946 }
947
|
948 chip 1.6 void cimom::get_default_op_timeout(struct timeval *timeout) const
|
949 mday 1.1 {
950 if (timeout != 0)
951 {
952 timeout->tv_sec = _default_op_timeout.tv_sec;
953 timeout->tv_usec = _default_op_timeout.tv_usec;
954 }
955 return;
956 }
|
957 mday 1.27
958 void cimom::_registered_module_in_service(RegisteredModule *msg)
959 {
960 Uint32 result = async_results::MODULE_NOT_FOUND;
961
962 _modules.lock();
963 message_module *ret = _modules.next( 0 );
964 while( ret != 0 )
965 {
966 if (ret->_q_id == msg->resp)
967 {
968 // see if the module is already registered
969 Uint32 i = 0;
970 for( ; i < ret->_modules.size() ; i++ )
971 {
|
972 mday 1.28 if( ret->_modules[i] == msg->_module )
|
973 mday 1.27 {
974 result = async_results::MODULE_ALREADY_REGISTERED;;
975 break;
976 }
977 }
978 if ( result != async_results::MODULE_ALREADY_REGISTERED)
979 {
980 ret->_modules.append(msg->_module);
981 result = async_results::OK;
982 }
983 break;
984 }
985 ret = _modules.next(ret);
986 }
987 _modules.unlock();
988 _make_response(msg, result);
989 }
990
991 void cimom::_deregistered_module_in_service(DeRegisteredModule *msg)
992 {
993 Uint32 result = async_results::MODULE_NOT_FOUND;
994 mday 1.27
995 _modules.lock();
996 message_module *ret = _modules.next( 0 );
997 while( ret != 0 )
998 {
999 if (ret->_q_id == msg->resp)
1000 {
1001 Uint32 i = 0;
1002 for( ; i < ret->_modules.size() ; i++ )
1003 {
1004 if( ret->_modules[i] == msg->_module )
1005 {
1006 ret->_modules.remove(i);
1007 result = async_results::OK;
1008 break;
1009 }
1010 }
1011 }
1012 ret = _modules.next(ret);
1013 }
1014 _modules.unlock();
1015 mday 1.27 _make_response(msg, result);
1016 }
1017
1018 void cimom::_find_module_in_service(FindModuleInService *msg)
1019 {
1020 Uint32 result = async_results::MODULE_NOT_FOUND;
1021 Uint32 q_id = 0;
1022
1023 _modules.lock();
1024 message_module *ret = _modules.next( 0 );
1025 while( ret != 0 )
1026 {
|
1027 mday 1.28 if ( ret->get_capabilities() & module_capabilities::module_controller)
|
1028 mday 1.27 {
|
1029 mday 1.28 // see if the module is in this service
1030 Uint32 i = 0;
1031 for( ; i < ret->_modules.size() ; i++ )
|
1032 mday 1.27 {
|
1033 mday 1.28 if( ret->_modules[i] == msg->_module )
1034 {
1035 result = async_results::OK;
1036 q_id = ret->_q_id;
|
1037 mday 1.27 break;
|
1038 mday 1.28 }
|
1039 mday 1.27 }
1040 }
1041 ret = _modules.next(ret);
1042 }
1043 _modules.unlock();
1044
1045 FindModuleInServiceResponse *response =
1046 new FindModuleInServiceResponse(msg->getRouting(),
1047 msg->getKey(),
1048 msg->op,
1049 result,
1050 msg->resp,
1051 msg->block,
1052 q_id);
1053
1054 _complete_op_node(msg->op,
1055 ASYNC_OPSTATE_COMPLETE,
1056 0,
1057 result);
1058 }
1059
1060 mday 1.27
|
1061 mday 1.1
1062 PEGASUS_NAMESPACE_END
1063
1064
1065
|