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