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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2