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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2