(file) Return to Cimom.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

   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            

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2