(file) Return to CMPILocalProviderManager.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / ProviderManager2 / CMPI

   1 karl  1.33 //%2006////////////////////////////////////////////////////////////////////////
   2 schuur 1.1  //
   3 karl   1.12 // 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             // IBM Corp.; EMC Corporation, The Open Group.
   7             // 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.16 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
  10             // EMC Corporation; VERITAS Software Corporation; The Open Group.
  11 karl   1.33 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
  12             // EMC Corporation; Symantec Corporation; The Open Group.
  13 schuur 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 karl   1.16 // 
  21 schuur 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: Chip Vincent (cvincent@us.ibm.com)
  33             //
  34             // Modified By: Yi Zhou, Hewlett-Packard Company(yi_zhou@hp.com)
  35             //              Mike Day IBM Corporation (mdday@us.ibm.com)
  36             //              Adrian Schuur, schuur@de.ibm.com
  37 dj.gorey 1.6  //              Dan Gorey, IBM djgorey@us.ibm.com
  38 r.kieninger 1.15 //              Robert Kieninger, IBM kieningr@de.ibm.com
  39 schuur      1.1  //
  40                  //%/////////////////////////////////////////////////////////////////////////////
  41                  
  42 schuur      1.10 #include "CMPI_Version.h"
  43                  
  44 schuur      1.1  #include <Pegasus/Common/Constants.h>
  45                  #include <Pegasus/Common/Tracer.h>
  46                  #include <Pegasus/Common/PegasusVersion.h>
  47                  
  48 konrad.r    1.26 #include <Pegasus/Common/MessageLoader.h>
  49                  
  50 schuur      1.1  #include <Pegasus/ProviderManager2/CMPI/CMPIProvider.h>
  51                  #include <Pegasus/ProviderManager2/CMPI/CMPIProviderModule.h>
  52                  #include <Pegasus/ProviderManager2/ProviderManagerService.h>
  53                  
  54 konrad.r    1.30 #include <Pegasus/ProviderManager2/CMPI/CMPILocalProviderManager.h>
  55 kumpf       1.9  
  56 schuur      1.3  PEGASUS_USING_STD;
  57 schuur      1.1  PEGASUS_NAMESPACE_BEGIN
  58 konrad.r    1.27 #define DDD(X)   if (_cmpi_trace) X;
  59                  
  60                  extern int _cmpi_trace;
  61                  
  62 schuur      1.8  #undef IDLE_LIMIT
  63                  #define IDLE_LIMIT 50
  64 konrad.r    1.30 
  65                  /* Thread deletion specific */
  66                  Semaphore CMPILocalProviderManager::_pollingSem(0);
  67                  AtomicInt CMPILocalProviderManager::_stopPolling(0);
  68                  Thread *CMPILocalProviderManager::_reaperThread = 0;
  69                  DQueue <CMPILocalProviderManager::cleanupThreadRecord> CMPILocalProviderManager::_finishedThreadList(true);
  70                  Mutex CMPILocalProviderManager::_reaperMutex(0);
  71                  
  72 konrad.r    1.24   CMPILocalProviderManager::CMPILocalProviderManager (void):
  73                  _idle_timeout (IDLE_LIMIT)
  74 r.kieninger 1.14 {
  75 schuur      1.1  }
  76                  
  77 konrad.r    1.24 CMPILocalProviderManager::~CMPILocalProviderManager (void)
  78 r.kieninger 1.14 {
  79 konrad.r    1.24   Uint32 ccode;
  80 dj.gorey    1.6  
  81 konrad.r    1.24   _provider_ctrl (UNLOAD_ALL_PROVIDERS, this, &ccode);
  82                    // Since all of the providers are deleted we can delete the 
  83                    //  modules too.
  84                    for (ModuleTable::Iterator j = _modules.start (); j != 0; j++)
  85                      {
  86                        CMPIProviderModule *module = j.value ();
  87                        delete module;
  88                      }
  89 konrad.r    1.30 
  90                    if (_reaperThread) 
  91                      {
  92                  		AutoMutex lock(_reaperMutex);
  93                    		_stopPolling++;
  94                    		_pollingSem.signal();
  95                    		// Wait until it finishes itself.
  96                   		_reaperThread->join(); 
  97                    		delete _reaperThread; 
  98                  		_reaperThread = 0;
  99                    	}
 100                   PEGASUS_ASSERT(_finishedThreadList.size() == 0);
 101                  
 102 schuur      1.1  }
 103                  
 104 konrad.r    1.24 Sint32
 105                  CMPILocalProviderManager::_provider_ctrl (CTRL code, void *parm, void *ret)
 106 r.kieninger 1.14 {
 107 r.kieninger 1.13 
 108 konrad.r    1.24   static Uint32 quantum;
 109                    PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "_provider_ctrl");
 110 r.kieninger 1.13 
 111 konrad.r    1.24   Sint32 ccode = 0;
 112                    CTRL_STRINGS *parms = reinterpret_cast < CTRL_STRINGS * >(parm);
 113 r.kieninger 1.13 
 114 konrad.r    1.24   switch (code)
 115 r.kieninger 1.14     {
 116                  
 117                      case GET_PROVIDER:
 118 konrad.r    1.24       {
 119 r.kieninger 1.14 
 120 konrad.r    1.24         PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
 121                                            "_provider_ctrl::GET_PROVIDER");
 122 r.kieninger 1.14 
 123 konrad.r    1.24         String providerName = *(parms->providerName);
 124                          String moduleFileName = *(parms->fileName);
 125                          String location = *(parms->location);
 126 r.kieninger 1.14 
 127 konrad.r    1.24         CMPIProvider *pr = 0;
 128                          CMPIProvider::OpProviderHolder * ph =
 129                            reinterpret_cast < CMPIProvider::OpProviderHolder * >(ret);
 130 r.kieninger 1.14 
 131 konrad.r    1.24         pr = _lookupProvider (providerName);
 132 r.kieninger 1.15 
 133 konrad.r    1.24         if (pr->getStatus () != CMPIProvider::INITIALIZED)
 134                            {
 135                              pr->setLocation (location);
 136                              _initProvider (pr, moduleFileName);
 137 r.kieninger 1.13 
 138 konrad.r    1.24             if (pr->getStatus () != CMPIProvider::INITIALIZED)
 139                                {
 140                                  PEG_METHOD_EXIT ();
 141                                  throw PEGASUS_CIM_EXCEPTION (CIM_ERR_FAILED,
 142                                                               "provider initialization failed");
 143                                }
 144                            }
 145 r.kieninger 1.13 
 146                  
 147 konrad.r    1.24         PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 148                                            "Returning Provider" + providerName);
 149 schuur      1.1  
 150 r.kieninger 1.15 
 151 konrad.r    1.24         ph->SetProvider (pr);
 152                          ph->GetProvider ().update_idle_timer ();
 153                          break;
 154                        }
 155 r.kieninger 1.14 
 156                      case UNLOAD_PROVIDER:
 157 konrad.r    1.24       {
 158                  
 159                          PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
 160                                            "_provider_ctrl::UNLOAD_PROVIDER");
 161 konrad.r    1.30         CMPIProvider *pr = 0;
 162                  	pr = _lookupProvider (*(parms->providerName));
 163 konrad.r    1.24         if ((pr->getStatus () == CMPIProvider::INITIALIZED))
 164                            {
 165 r.kieninger 1.14 
 166 konrad.r    1.24             PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 167 konrad.r    1.26                               "Unloading CMPIProvider: " + pr->getName());
 168 r.kieninger 1.14 
 169 konrad.r    1.24             AutoMutex lock (_providerTableMutex);
 170                              // The provider table must be locked before unloading. 
 171                              _providers.remove (pr->_name);
 172                              _unloadProvider (pr);
 173                              delete pr;
 174 r.kieninger 1.14 
 175 konrad.r    1.24           }
 176 konrad.r    1.25 	    else {
 177                  			// No need to have a memory leak.
 178 konrad.r    1.29 			_providers.remove(pr->_name);
 179 konrad.r    1.25 			delete pr;
 180                  		}
 181 konrad.r    1.24         break;
 182                        }
 183 schuur      1.1  
 184 r.kieninger 1.14     case LOOKUP_PROVIDER:
 185 konrad.r    1.24       {
 186                  
 187                          PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
 188                                            "_provider_ctrl::LOOKUP_PROVIDER");
 189 schuur      1.1  
 190 konrad.r    1.24         AutoMutex lock (_providerTableMutex);
 191 schuur      1.1  
 192 konrad.r    1.24         if (true == _providers.lookup (*(parms->providerName),
 193                                                         *(reinterpret_cast <
 194                                                           CMPIProvider * *>(ret))))
 195                            {
 196                              PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 197                                                "Found CMPIProvider in cache: " +
 198                                                *(parms->providerName));
 199                  
 200                              (*(reinterpret_cast < CMPIProvider * *>(ret)))->
 201                                update_idle_timer ();
 202                            }
 203                          else
 204                            {
 205                  
 206                              PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 207                                                "Could not find  CMPIProvider in cache: " +
 208                                                *(parms->providerName));
 209                              ccode = -1;
 210                            }
 211 dj.gorey    1.6  
 212 konrad.r    1.24         break;
 213                        }
 214 schuur      1.1  
 215 konrad.r    1.24     case LOOKUP_MODULE:
 216                        {
 217 schuur      1.1  
 218 konrad.r    1.24         PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
 219                                            "_provider_ctrl::LOOKUP_MODULE");
 220 schuur      1.1  
 221 konrad.r    1.24         AutoMutex lock (_providerTableMutex);
 222 schuur      1.1  
 223 konrad.r    1.24         if (false == _modules.lookup (*(parms->fileName),
 224                                                        *(reinterpret_cast <
 225                                                          CMPIProviderModule * *>(ret))))
 226                            {
 227                              PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 228                                                "Could not find  CMPIProvider Module in cache: "
 229                                                + *(parms->fileName));
 230                              ccode = -1;
 231                            }
 232 schuur      1.1  
 233 konrad.r    1.24         break;
 234                        }
 235 schuur      1.1  
 236 konrad.r    1.24     case INSERT_PROVIDER:
 237                        {
 238 r.kieninger 1.14 
 239 konrad.r    1.24         PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
 240                                            "_provider_ctrl::INSERT_PROVIDER");
 241 schuur      1.1  
 242 konrad.r    1.24         AutoMutex lock (_providerTableMutex);
 243 konrad.r    1.26 	
 244 konrad.r    1.24         if (false == _providers.insert (*(parms->providerName),
 245                                                          *reinterpret_cast <
 246                                                          CMPIProvider * *>(parm)))
 247                            ccode = -1;
 248                          break;
 249                        }
 250                      case INSERT_MODULE:
 251                        {
 252                          PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
 253                                            "_provider_ctrl::INSERT_MODULE");
 254                          AutoMutex lock (_providerTableMutex);
 255                          if (false == _modules.insert (*(parms->fileName),
 256                                                        *reinterpret_cast <
 257                                                        CMPIProviderModule * *>(parm)))
 258                            ccode = -1;
 259                          break;
 260                        }
 261 schuur      1.1  
 262 konrad.r    1.24     case UNLOAD_ALL_PROVIDERS:
 263                        {
 264                          PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
 265                                            "_provider_ctrl::UNLOAD_ALL_PROVIDERS");
 266                          CMPILocalProviderManager *myself =
 267                            reinterpret_cast < CMPILocalProviderManager * >(parm);
 268                          CMPIProvider *provider = 0;
 269                          // Locked provider mutex.
 270                          AutoMutex lock (_providerTableMutex);
 271 dj.gorey    1.6  
 272 konrad.r    1.24         Tracer::trace (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 273                                         "providers in cache = %d", myself->_providers.size ());
 274                          ProviderTable::Iterator i = myself->_providers.start ();
 275                          try
 276                          {
 277                            for (; i != 0; i++)
 278                              {
 279 r.kieninger 1.15 
 280 konrad.r    1.24               provider = i.value ();
 281                                PEGASUS_ASSERT (provider != 0);
 282                                if (provider->getStatus () == CMPIProvider::UNINITIALIZED)
 283                                  {
 284                                    // Delete the skeleton.
 285 konrad.r    1.30 		delete provider;
 286 konrad.r    1.24                   continue;
 287                                  }
 288                                else
 289                                  {
 290                                    _unloadProvider (provider);
 291                                    delete provider;
 292                                  }
 293                              }
 294                            // All the providers are removed. Clear the hash-table
 295                            _providers.clear ();
 296 r.kieninger 1.14         }
 297 konrad.r    1.24         catch (...)
 298 r.kieninger 1.14         {
 299 konrad.r    1.24           PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 300                                              "Unexpected Exception in UNLOAD_ALL_PROVIDERS.");
 301 r.kieninger 1.14         }
 302 konrad.r    1.24         break;
 303                        }
 304                      case UNLOAD_IDLE_PROVIDERS:
 305                        {
 306                          PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
 307                                            "_provider_ctrl::UNLOAD_IDLE_PROVIDERS");
 308                          AutoMutex lock (_providerTableMutex);
 309                  
 310                          quantum++;
 311                          CMPILocalProviderManager *myself =
 312                            reinterpret_cast < CMPILocalProviderManager * >(parm);
 313 kumpf       1.32         CMPIProvider *provider = 0;
 314 konrad.r    1.24         Uint32 numProviders = myself->_providers.size ();
 315                  
 316                          if (numProviders)
 317                            {
 318                              // Rather than removing the provider immediately while
 319                              // iterating through the list we remember all candidates
 320                              // for unload in a simple array.
 321                              CMPIProvider **unloadProviderArray =
 322                                new CMPIProvider *[numProviders];
 323                              Uint32 upaIndex = 0;
 324 r.kieninger 1.15 
 325 r.kieninger 1.14             try
 326                              {
 327 konrad.r    1.24               struct timeval now;
 328                                gettimeofday (&now, NULL);
 329                                ProviderTable::Iterator i = myself->_providers.start ();
 330                  
 331                                for (; i != 0; i++)
 332 r.kieninger 1.14                 {
 333 konrad.r    1.24                   provider = i.value ();
 334                                    PEGASUS_ASSERT (provider != 0);
 335                  
 336                                    if (provider->getStatus () == CMPIProvider::UNINITIALIZED)
 337 r.kieninger 1.14                     {
 338 konrad.r    1.24                       continue;
 339 r.kieninger 1.14                     }
 340 konrad.r    1.24 
 341                                    if (provider->_quantum == quantum)
 342 r.kieninger 1.14                     {
 343 konrad.r    1.24                       continue;
 344 r.kieninger 1.14                     }
 345 r.kieninger 1.15 
 346 konrad.r    1.24                   provider->_quantum = quantum;
 347                  
 348 mike        1.31                   if (provider->_current_operations.get ())
 349 konrad.r    1.24                     {
 350                                        PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 351                                                          "CMPIProvider has pending operations: "
 352                                                          + provider->getName ());
 353 r.kieninger 1.14 
 354 konrad.r    1.24                       continue;
 355 r.kieninger 1.15                     }
 356 r.kieninger 1.14 
 357 konrad.r    1.24                   PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 358                                                      "Checking timeout data for CMPIProvider: "
 359                                                      + provider->getName ());
 360                                    struct timeval timeout = { 0, 0 };
 361                                    provider->get_idle_timer (&timeout);
 362                  
 363                                    PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 364                                                      " provider->unload_ok() returns: " +
 365                                                      provider->unload_ok ()? "true" : "false");
 366                  
 367                                    if (provider->unload_ok () == true &&
 368                                        (now.tv_sec - timeout.tv_sec) >
 369                                        ((Sint32) myself->_idle_timeout))
 370                                      {
 371                                        // Remember this provider to be unloaded
 372                                        unloadProviderArray[upaIndex] = provider;
 373                                        upaIndex++;
 374 r.kieninger 1.14                     }
 375 konrad.r    1.24                   //else cout<<"--- NOT unloaded: "+ provider->getName()<<endl;
 376 r.kieninger 1.14                 }
 377 konrad.r    1.24 
 378                                // Now finally we unload all providers that we identified as
 379                                // candidates above.
 380                                for (Uint32 index = 0; index < upaIndex; index++)
 381                                  {
 382                                    PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 383                                                      "Now trying to unload CMPIProvider " +
 384                                                      provider->getName ());
 385                                    CMPIProvider *provider = unloadProviderArray[index];
 386                  
 387                                    // lock the provider mutex
 388                  
 389                                    AutoMutex pr_lock (provider->_statusMutex);
 390                  
 391                                    if (provider->tryTerminate () == false)
 392                                      {
 393                                        // provider not unloaded -- we are respecting this!
 394                                        PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 395                                                          "Provider refused to unload: " +
 396 konrad.r    1.26                                         unloadProviderArray[index]->getName());
 397 konrad.r    1.24                       continue;
 398                                      }
 399                  
 400 mark.hamzy  1.28                   // delete from _provider table
 401                                    if (!_providers.remove (provider->_name))
 402                                    {
 403                                       PEGASUS_ASSERT (0);
 404                                    }
 405                  
 406 konrad.r    1.24                   // delete the cimom handle
 407                                    PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 408                                                      "Destroying CMPIProvider's CIMOM Handle "
 409 konrad.r    1.26                                     + provider->getName());
 410 konrad.r    1.24                   delete provider->_cimom_handle;
 411                  
 412                                    PEGASUS_ASSERT (provider->_module != 0);
 413                  
 414                                    // unload provider module
 415                                    provider->_module->unloadModule ();
 416                                    Logger::put (Logger::STANDARD_LOG, System::CIMSERVER,
 417                                                 Logger::TRACE,
 418                                                 "CMPILocalProviderManager::_provider_crtl -  Unload provider $0",
 419                                                 provider->getName ());
 420                  
 421                                    // set provider status to UNINITIALIZED
 422                                    provider->reset ();
 423                  
 424                                    delete provider;
 425 r.kieninger 1.14                 }
 426 konrad.r    1.24             }
 427                              catch (...)
 428                              {
 429                                PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 430                                                  "Unexpected Exception in UNLOAD_IDLE_PROVIDERS.");
 431                              }
 432 r.kieninger 1.15             delete unloadProviderArray;
 433 konrad.r    1.24           }                     // if there are any providers
 434                          break;
 435                        }
 436 r.kieninger 1.14 
 437                      default:
 438 konrad.r    1.24       ccode = -1;
 439                        break;
 440 r.kieninger 1.14     }
 441 konrad.r    1.24   PEG_METHOD_EXIT ();
 442                    return (ccode);
 443 schuur      1.1  }
 444                  
 445 konrad.r    1.30 
 446                  
 447                  /*
 448                   * The reaper function polls out the threads from the global list (_finishedThreadList), 
 449                   * joins them deletes them, and removes them from the CMPIProvider specific list.
 450                   */
 451                  PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL CMPILocalProviderManager::_reaper(void *parm)
 452                  {
 453                    Thread *myself = reinterpret_cast<Thread *>(parm);
 454                    do { 
 455                        	_pollingSem.wait();
 456                  	    // All of the threads are finished working. We just need to reap 'em
 457                  		cleanupThreadRecord *rec = 0;
 458                  
 459                  		while (_finishedThreadList.size() >0 )
 460                  		{
 461                  		    // Pull of the the threads from the global list.
 462                  			rec = _finishedThreadList.remove_first();
 463                  			DDD(cerr << "Reaping the thread " << rec->thread << " from " << rec->provider->getName() << endl);
 464                  			rec->thread->join();
 465                  			// Delete the thread, and 
 466 konrad.r    1.30 			delete rec->thread;
 467                  			// remove the thread for the CMPIProvider  
 468                  	 		rec->provider->threadDelete(rec->thread);
 469                  			delete rec;
 470                  		}
 471                      }
 472 mike        1.31   while (_stopPolling.get() == 0);
 473 konrad.r    1.30   myself->exit_self( (PEGASUS_THREAD_RETURN) 0);
 474                    return (0);
 475                  }
 476                   /*
 477                    // Cleanup the thread and upon deletion of it, call the CMPIProvider' "threadDeleted".
 478                    // to not, all the CMPIProvider '
 479                    // Note that this function is called from the thread that finished with
 480                    // running the providers function, and returns immediately while scheduling the
 481                    // a cleanup procedure. If you want to wait until the thread is truly deleted,
 482                    // call 'waitUntilThreadsDone' - but DO NOT do it in the the thread that
 483                    // the Thread owns - you will wait forever.
 484                    //
 485                    // @argument t Thread that is not NULL and finished with running the provider function.
 486                    // @argument p CMPIProvider in which the 't' Thread was running.
 487                    */
 488                  void 
 489                  CMPILocalProviderManager::cleanupThread(Thread *t, CMPIProvider *p)
 490                  {
 491                  	PEGASUS_ASSERT( t != 0 && p != 0 );
 492                  
 493                  	PEGASUS_ASSERT ( p->isThreadOwner(t) );
 494 konrad.r    1.30   	// The mutex guards against a race condition for _reaperThread creation.
 495                    	AutoMutex lock(_reaperMutex);
 496                  
 497                      // Put the Thread and the CMPIProvider on the global list.
 498                  	cleanupThreadRecord *record = new cleanupThreadRecord(t, p);
 499                  	_finishedThreadList.insert_last (record);
 500                  
 501                    	if (_reaperThread == 0)
 502                      {
 503                        _reaperThread = new Thread(_reaper, NULL, false);
 504                        ThreadStatus rtn = PEGASUS_THREAD_OK;
 505                        while ( (rtn = _reaperThread->run()) != PEGASUS_THREAD_OK)
 506                        {
 507                  		if (rtn == PEGASUS_THREAD_INSUFFICIENT_RESOURCES)
 508                  	 		pegasus_yield();
 509                  		else
 510                  	    {
 511                  			PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2, \
 512                                  "Could not allocate thread to take care of deleting user threads. ");
 513                  			delete _reaperThread; _reaperThread = 0;
 514                  			return;
 515 konrad.r    1.30 	    }		
 516                        }
 517                      }/*
 518                    Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL2, \
 519                  			"Cleaning up provider thread (%p) from provider %s.", 
 520                  			t, (const char *)p->getName().getCString());*/
 521                    // Wake up the reaper.
 522                    _pollingSem.signal();
 523                  
 524                  }
 525                  
 526 konrad.r    1.24 CMPIProvider::OpProviderHolder CMPILocalProviderManager::
 527                  getRemoteProvider (const String & location, const String & providerName)
 528                  {
 529                    CMPIProvider::OpProviderHolder ph;
 530                    CTRL_STRINGS
 531                      strings;
 532                    Sint32
 533                      ccode;
 534                    const String
 535                    proxy ("CMPIRProxyProvider");
 536                  
 537                    String
 538                    rproviderName ("R");
 539                    PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
 540                                      "ProvidertManager::getRemoteProvider");
 541                  
 542                    rproviderName.append (providerName);
 543                  
 544                    strings.fileName = &proxy;
 545                    strings.providerName = &rproviderName;
 546                    strings.location = &location;
 547 konrad.r    1.24 
 548                    try
 549                    {
 550                      ccode = _provider_ctrl (GET_PROVIDER, &strings, &ph);
 551                    }
 552                    catch (const Exception & e)
 553                    {
 554 konrad.r    1.27     DDD(cerr << "--- loading proxy: " << e.getMessage () << endl);
 555 konrad.r    1.24     PEG_METHOD_EXIT ();
 556                      throw;
 557                    }
 558                    catch (...)
 559                    {
 560                      PEG_METHOD_EXIT ();
 561                      throw;
 562                    } CMPIProvider & prov = ph.GetProvider ();
 563 schuur      1.10 
 564 konrad.r    1.24   PEG_METHOD_EXIT ();
 565                    return (ph);
 566 schuur      1.1  
 567                  }
 568                  
 569 konrad.r    1.24 CMPIProvider::OpProviderHolder CMPILocalProviderManager::
 570                  getProvider (const String & fileName, const String & providerName)
 571 r.kieninger 1.14 {
 572 konrad.r    1.24   CMPIProvider::OpProviderHolder ph;
 573                    CTRL_STRINGS
 574                      strings;
 575                    Sint32
 576                      ccode;
 577 r.kieninger 1.15 
 578 konrad.r    1.24   String
 579                    lproviderName ("L");
 580                    PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "ProviderManager::getProvider");
 581 konrad.r    1.26   if (fileName.size() == 0)
 582                    {
 583                          throw Exception(MessageLoaderParms("ProviderManager.CMPI.CMPILocalProviderManager.CANNOT_FIND_LIBRARY",
 584                              "Provider library $0 was not found.",
 585                              fileName));
 586 r.kieninger 1.15 
 587 konrad.r    1.26   }
 588 konrad.r    1.24   lproviderName.append (providerName);
 589                    strings.fileName = &fileName;
 590                    strings.providerName = &lproviderName;
 591                    strings.location = &String::EMPTY;
 592 r.kieninger 1.14 
 593 konrad.r    1.24   try
 594                    {
 595                      ccode = _provider_ctrl (GET_PROVIDER, &strings, &ph);
 596                    }
 597                    catch (const Exception & e)
 598                    {
 599 konrad.r    1.27     DDD(cerr << "--- loading proxy: " << e.getMessage () << endl);
 600 konrad.r    1.24     PEG_METHOD_EXIT ();
 601                      throw;
 602                    }
 603                    catch (...)
 604                    {
 605                      PEG_METHOD_EXIT ();
 606                      throw;
 607                    }
 608 schuur      1.1  
 609                  
 610 konrad.r    1.24   PEG_METHOD_EXIT ();
 611                    return (ph);
 612 schuur      1.1  
 613                  }
 614                  
 615 konrad.r    1.24 void
 616                  CMPILocalProviderManager::unloadProvider (const String & fileName,
 617                                                            const String & providerName)
 618 r.kieninger 1.14 {
 619 konrad.r    1.24   CTRL_STRINGS strings;
 620                    PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "ProviderManager::unloadProvider");
 621 konrad.r    1.25 
 622                    String lproviderName ("L");
 623                    String rproviderName ("R");
 624                    lproviderName.append (providerName);
 625                    rproviderName.append (providerName);
 626                  
 627 konrad.r    1.24   strings.fileName = &fileName;
 628 konrad.r    1.25   strings.providerName = &lproviderName;
 629                    strings.location = &String::EMPTY;
 630 konrad.r    1.24   _provider_ctrl (UNLOAD_PROVIDER, &strings, (void *) 0);
 631 konrad.r    1.25    
 632                    strings.providerName = &rproviderName;
 633                  
 634                    _provider_ctrl (UNLOAD_PROVIDER, &strings, (void *) 0);
 635                  
 636 konrad.r    1.24   PEG_METHOD_EXIT ();
 637 r.kieninger 1.14 }
 638                  
 639 konrad.r    1.24 void
 640                  CMPILocalProviderManager::shutdownAllProviders (void)
 641 r.kieninger 1.14 {
 642                  
 643 konrad.r    1.24   PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
 644                                      "ProviderManager::shutdownAllProviders");
 645                    _provider_ctrl (UNLOAD_ALL_PROVIDERS, (void *) this, (void *) 0);
 646                    PEG_METHOD_EXIT ();
 647 r.kieninger 1.13 }
 648                  
 649                  
 650 konrad.r    1.24 Boolean
 651                  CMPILocalProviderManager::hasActiveProviders ()
 652 r.kieninger 1.14 {
 653 konrad.r    1.24   PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
 654                                      "ProviderManager::hasActiveProviders");
 655 r.kieninger 1.14 
 656 konrad.r    1.24   try
 657                    {
 658                      AutoMutex lock (_providerTableMutex);
 659                      Tracer::trace (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 660                                     "providers in _providers table = %d", _providers.size ());
 661 r.kieninger 1.14 
 662 konrad.r    1.24     // Iterate through the _providers table looking for an active provider
 663                      for (ProviderTable::Iterator i = _providers.start (); i != 0; i++)
 664                        {
 665                          if (i.value ()->getStatus () == CMPIProvider::INITIALIZED)
 666                            {
 667                              PEG_METHOD_EXIT ();
 668                              return true;
 669                            }
 670                        }
 671                    }
 672                    catch (...)
 673                    {
 674                      // Unexpected exception; do not assume that no providers are loaded
 675                      PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
 676                                        "Unexpected Exception in hasActiveProviders.");
 677                      PEG_METHOD_EXIT ();
 678                      return true;
 679                    }
 680 r.kieninger 1.14 
 681 konrad.r    1.24   // No active providers were found in the _providers table
 682                    PEG_METHOD_EXIT ();
 683                    return false;
 684 r.kieninger 1.14 }
 685                  
 686 konrad.r    1.24 void
 687                  CMPILocalProviderManager::unloadIdleProviders (void)
 688 r.kieninger 1.14 {
 689 konrad.r    1.24   PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
 690                                      "ProviderManager::unloadIdleProviders");
 691 r.kieninger 1.14 
 692 konrad.r    1.24   static struct timeval first = { 0, 0 }, now, last =
 693                    {
 694                    0, 0};
 695 r.kieninger 1.15 
 696 konrad.r    1.24   if (first.tv_sec == 0)
 697 r.kieninger 1.14     {
 698 konrad.r    1.24       gettimeofday (&first, NULL);
 699 r.kieninger 1.14     }
 700 konrad.r    1.24   gettimeofday (&now, NULL);
 701 r.kieninger 1.14 
 702 konrad.r    1.24   if (((now.tv_sec - first.tv_sec) > IDLE_LIMIT) &&
 703                        ((now.tv_sec - last.tv_sec) > IDLE_LIMIT))
 704 r.kieninger 1.14     {
 705 konrad.r    1.24       gettimeofday (&last, NULL);
 706                        PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 707                                          "Checking for Idle providers to unload.");
 708                        try
 709                        {
 710                          _provider_ctrl (UNLOAD_IDLE_PROVIDERS, this, (void *) 0);
 711                        }
 712                        catch (...)
 713                        {
 714                          PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
 715                                            "Caught unexpected exception from UNLOAD_IDLE_PROVIDERS.");
 716                        }
 717 r.kieninger 1.14     }
 718 konrad.r    1.24   PEG_METHOD_EXIT ();
 719 schuur      1.1  }
 720                  
 721 konrad.r    1.24 Array <
 722                    CMPIProvider * >CMPILocalProviderManager::getIndicationProvidersToEnable ()
 723 carolann.graves 1.17 {
 724 konrad.r        1.24   PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
 725                                          "CMPILocalProviderManager::getIndicationProvidersToEnable");
 726 carolann.graves 1.17 
 727 konrad.r        1.24   Array < CMPIProvider * >enableProviders;
 728 carolann.graves 1.17 
 729 konrad.r        1.24   Tracer::trace (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 730                                       "Number of providers in _providers table = %d",
 731                                       _providers.size ());
 732 carolann.graves 1.17 
 733 konrad.r        1.24   try
 734                        {
 735                          AutoMutex
 736                          lock (_providerTableMutex);
 737 carolann.graves 1.17 
 738 konrad.r        1.24     //
 739                          // Iterate through the _providers table
 740                          //
 741                          for (ProviderTable::Iterator i = _providers.start (); i != 0; i++)
 742                            {
 743 carolann.graves 1.17         //
 744 konrad.r        1.24         //  Enable any indication provider with current subscriptions
 745 carolann.graves 1.17         //
 746 konrad.r        1.24         CMPIProvider *
 747                                provider = i.value ();
 748                              if (provider->testSubscriptions ())
 749                                {
 750                                  enableProviders.append (provider);
 751                                }
 752                            }
 753                      
 754                        }
 755                        catch (const CIMException & e)
 756                        {
 757                          PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL2,
 758                                            "CIMException: " + e.getMessage ());
 759                        }
 760                        catch (const Exception & e)
 761                        {
 762                          PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL2,
 763                                            "Exception: " + e.getMessage ());
 764                        }
 765                        catch (...)
 766                        {
 767 konrad.r        1.24     PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL2,
 768                                            "Unexpected error in getIndicationProvidersToEnable");
 769                        }
 770                      
 771                        Tracer::trace (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 772                                       "Number of indication providers to enable = %d",
 773                                       enableProviders.size ());
 774                      
 775                        PEG_METHOD_EXIT ();
 776                        return enableProviders;
 777                      }
 778                      
 779                      CMPIProvider *
 780                      CMPILocalProviderManager::_initProvider (CMPIProvider * provider,
 781                                                               const String & moduleFileName)
 782                      {
 783                        PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "_initProvider");
 784 carolann.graves 1.17 
 785 konrad.r        1.24   CMPIProviderModule *module = 0;
 786                        ProviderVector base;
 787 carolann.graves 1.17 
 788 konrad.r        1.24   {
 789                          // lock the providerTable mutex
 790                          AutoMutex lock (_providerTableMutex);
 791 carolann.graves 1.17 
 792 konrad.r        1.24     // lookup provider module
 793                          module = _lookupModule (moduleFileName);
 794                        }                             // unlock the providerTable mutex
 795 schuur          1.1  
 796 konrad.r        1.24   Boolean deleteProvider = false;
 797 konrad.r        1.26   String exceptionMsg = moduleFileName;
 798 konrad.r        1.24   {
 799                          // lock the provider status mutex
 800                          AutoMutex lock (provider->_statusMutex);
 801 r.kieninger     1.14 
 802 konrad.r        1.24     if (provider->_status == CMPIProvider::INITIALIZED)
 803                            {
 804                              // Initialization is already complete
 805                              return provider;
 806                            }
 807 r.kieninger     1.14 
 808 konrad.r        1.24     PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 809                                            "Loading/Linking Provider Module " + moduleFileName);
 810 kumpf           1.18 
 811 konrad.r        1.24     // load the provider
 812                          try
 813                          {
 814                            base = module->load (provider->_name);
 815                          }
 816 konrad.r        1.26     catch (const Exception &e)
 817                          {
 818                      	  exceptionMsg = e.getMessage();
 819                            PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 820                                              "Exception caught Loading/Linking Provider Module " +
 821                                              moduleFileName+ " error is: "+exceptionMsg);
 822                      	  deleteProvider =true;
 823                          }
 824 konrad.r        1.24     catch (...)
 825 kumpf           1.18     {
 826 konrad.r        1.24       PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 827 konrad.r        1.26                         "Unknown exception caught Loading/Linking Provider Module " +
 828 konrad.r        1.24                         moduleFileName);
 829 konrad.r        1.26        exceptionMsg = moduleFileName;
 830 konrad.r        1.24     }
 831 konrad.r        1.26     if (!deleteProvider)
 832                          {
 833                            // initialize the provider
 834                            PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
 835                                            "Initializing Provider " + provider->getName());
 836 r.kieninger     1.14 
 837 konrad.r        1.26       CIMOMHandle *cimomHandle = new CIMOMHandle ();
 838                            provider->set (module, base, cimomHandle);
 839                            provider->_quantum = 0;
 840 konrad.r        1.24 
 841 konrad.r        1.26       try
 842                            {
 843                            	provider->initialize (*(provider->_cimom_handle));
 844                            }
 845                            catch (const Exception &e)
 846                            {
 847                           	PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
 848                      				"Problem initializing: " + e.getMessage());
 849                            	deleteProvider = true;
 850                      	exceptionMsg = e.getMessage();
 851                            }
 852                            catch (...) 
 853                            {
 854                           	PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
 855                      				"Unknown problem initializing " + provider->getName());
 856                            	deleteProvider = true;
 857                      	exceptionMsg = provider->getName();
 858                            }
 859                          }                             // unlock the provider status mutex
 860                        }
 861                        /* We wait until this moment to delete the provider b/c we need
 862 konrad.r        1.26      be outside the scope for the AutoMutex for the provider. */
 863                        if (deleteProvider)
 864                        {
 865 konrad.r        1.24       // delete the cimom handle
 866                            delete provider->_cimom_handle;
 867                            // set provider status to UNINITIALIZED
 868                            provider->reset ();
 869                            // unload provider module
 870                            module->unloadModule ();
 871 r.kieninger     1.14 
 872 konrad.r        1.24       AutoMutex lock (_providerTableMutex);
 873 konrad.r        1.26       _providers.remove (provider->_name);
 874 konrad.r        1.24       delete provider;
 875 konrad.r        1.26 
 876                            PEG_METHOD_EXIT ();
 877                            throw Exception(exceptionMsg);
 878 r.kieninger     1.14     }
 879                      
 880 konrad.r        1.24   PEG_METHOD_EXIT ();
 881                        return (provider);
 882 r.kieninger     1.14 }
 883                      
 884                      
 885 konrad.r        1.24 void
 886                      CMPILocalProviderManager::_unloadProvider (CMPIProvider * provider)
 887 r.kieninger     1.14 {
 888 konrad.r        1.24   //
 889                        // NOTE:  It is the caller's responsibility to make sure that
 890                        // the ProviderTable mutex is locked before calling this method.
 891                        //
 892                        PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "_unloadProvider");
 893 r.kieninger     1.14 
 894 konrad.r        1.24   PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 895 konrad.r        1.26                     "Unloading Provider " + provider->getName());
 896 r.kieninger     1.14 
 897 mike            1.31   if (provider->_current_operations.get ())
 898 r.kieninger     1.14     {
 899 konrad.r        1.24       PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 900                                              "Provider cannot be unloaded due to pending operations: "
 901 konrad.r        1.26                         + provider->getName());
 902 r.kieninger     1.14     }
 903 konrad.r        1.24   else
 904 r.kieninger     1.14     {
 905 konrad.r        1.24       PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 906 konrad.r        1.26                         "Terminating Provider " + provider->getName());
 907 konrad.r        1.24 
 908 r.kieninger     1.14 
 909 konrad.r        1.24       // lock the provider mutex
 910                            AutoMutex pr_lock (provider->_statusMutex);
 911 r.kieninger     1.14 
 912 konrad.r        1.24       try
 913                            {
 914                              provider->terminate ();
 915                            }
 916                            catch (...)
 917                            {
 918                              PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL3,
 919                                                "Error occured terminating CMPI provider " +
 920 konrad.r        1.26                           provider->getName());
 921 konrad.r        1.24       }
 922 r.kieninger     1.14 
 923 konrad.r        1.24       // delete the cimom handle
 924                            PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 925                                              "Destroying CMPIProvider's CIMOM Handle " +
 926 konrad.r        1.26                         provider->getName());
 927 r.kieninger     1.14 
 928 konrad.r        1.24       delete provider->_cimom_handle;
 929                            PEGASUS_ASSERT (provider->_module != 0);
 930 r.kieninger     1.14 
 931 konrad.r        1.24       // unload provider module
 932                            provider->_module->unloadModule ();
 933                            Logger::put (Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
 934                                         "CMPILocalProviderManager::_provider_crtl -  Unload provider $0",
 935                                         provider->getName ());
 936 r.kieninger     1.14 
 937 konrad.r        1.24       // set provider status to UNINITIALIZED
 938                            provider->reset ();
 939 r.kieninger     1.14 
 940 konrad.r        1.24       // Do not delete the provider. The function calling this function
 941                            // takes care of that.
 942 r.kieninger     1.14     }
 943 r.kieninger     1.13 
 944 konrad.r        1.24   PEG_METHOD_EXIT ();
 945 dj.gorey        1.6  }
 946                      
 947 konrad.r        1.24 CMPIProvider *
 948                      CMPILocalProviderManager::_lookupProvider (const String & providerName)
 949 r.kieninger     1.14 {
 950 konrad.r        1.24   PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "_lookupProvider");
 951                        // lock the providerTable mutex
 952                        AutoMutex lock (_providerTableMutex);
 953                        // look up provider in cache
 954                        CMPIProvider *pr = 0;
 955                        if (true == _providers.lookup (providerName, pr))
 956 r.kieninger     1.14     {
 957 konrad.r        1.24       PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 958                                              "Found Provider " + providerName +
 959                                              " in CMPI Provider Manager Cache");
 960 r.kieninger     1.14     }
 961 konrad.r        1.24   else
 962 r.kieninger     1.14     {
 963 konrad.r        1.24       // create provider
 964                            pr = new CMPIProvider (providerName, 0, 0);
 965                            // insert provider in provider table
 966                            _providers.insert (providerName, pr);
 967 r.kieninger     1.14 
 968 konrad.r        1.24       PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 969                                              "Created provider " + pr->getName ());
 970 r.kieninger     1.14     }
 971 dj.gorey        1.6  
 972 konrad.r        1.24   PEG_METHOD_EXIT ();
 973                        return (pr);
 974 dj.gorey        1.6  }
 975                      
 976                      
 977 konrad.r        1.24 CMPIProviderModule *
 978                      CMPILocalProviderManager::_lookupModule (const String & moduleFileName)
 979 r.kieninger     1.14 {
 980 konrad.r        1.24   PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "_lookupModule");
 981 r.kieninger     1.14 
 982 konrad.r        1.24   // look up provider module in cache
 983                        CMPIProviderModule *module = 0;
 984 r.kieninger     1.14 
 985 konrad.r        1.24   if (true == _modules.lookup (moduleFileName, module))
 986 r.kieninger     1.14     {
 987 konrad.r        1.24       // found provider module in cache
 988                            PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 989                                              "Found Provider Module" + moduleFileName +
 990                                              " in Provider Manager Cache");
 991 dj.gorey        1.6  
 992 konrad.r        1.24     }
 993                        else
 994                          {
 995                            // provider module not found in cache, create provider module
 996                            PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
 997                                              "Creating CMPI Provider Module " + moduleFileName);
 998 r.kieninger     1.14 
 999 konrad.r        1.24       module = new CMPIProviderModule (moduleFileName);
1000 r.kieninger     1.14 
1001 konrad.r        1.24       // insert provider module in module table
1002                            _modules.insert (moduleFileName, module);
1003 r.kieninger     1.14     }
1004 dj.gorey        1.6  
1005 konrad.r        1.24   PEG_METHOD_EXIT ();
1006                        return (module);
1007 schuur          1.1  }
1008                      
1009                      PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2