Boolean DefaultProviderManager::hasActiveProviders()
{
    PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
        "DefaultProviderManager::hasActiveProviders");

    try
    {
        AutoMutex lock(_providerTableMutex);
        PEG_TRACE((TRC_PROVIDERMANAGER, Tracer::LEVEL4,
            "Number of providers in _providers table = %d", _providers.size()));

        // Iterate through the _providers table looking for an active provider
        for (ProviderTable::Iterator i = _providers.start(); i != 0; i++)
        {
            if (i.value()->status.isInitialized())
            {
                PEG_METHOD_EXIT();
                return true;
            }
        }
    }
    catch (...)
    {
        // Unexpected exception; do not assume that no providers are loaded
        PEG_TRACE_CSTRING(TRC_PROVIDERMANAGER, Tracer::LEVEL1,
            "Unexpected Exception in hasActiveProviders.");
        PEG_METHOD_EXIT();
        return true;
    }

    // No active providers were found in the _providers table
    PEG_METHOD_EXIT();
    return false;
}
void DefaultProviderManager::unloadIdleProviders()
{
    PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
        "DefaultProviderManager::unloadIdleProviders");

    try
    {
        struct timeval now;
        Time::gettimeofday(&now);

        // Make a copy of the table so it is not locked during provider calls
        Array<ProviderMessageHandler*> providerList;
        {
            AutoMutex lock(_providerTableMutex);

            for (ProviderTable::Iterator i = _providers.start(); i != 0; i++)
            {
                providerList.append(i.value());
            }
        }

        for (Uint32 i = 0; i < providerList.size(); i++)
        {
            ProviderMessageHandler* provider = providerList[i];

            AutoMutex lock(provider->status.getStatusMutex());

            if (!provider->status.isInitialized())
            {
                continue;
            }

            struct timeval providerTime = {0, 0};
            provider->status.getLastOperationEndTime(&providerTime);

            PEG_TRACE((TRC_PROVIDERMANAGER, Tracer::LEVEL4,
                "provider->status.isIdle() returns: %s",
                (const char*)CIMValue(provider->status.isIdle())
                       .toString().getCString()));

            if (provider->status.isIdle() &&
                ((now.tv_sec - providerTime.tv_sec) >
                 ((Sint32)PEGASUS_PROVIDER_IDLE_TIMEOUT_SECONDS)))
            {
                PEG_TRACE((TRC_PROVIDERMANAGER, Tracer::LEVEL3,
                    "Unloading idle provider: %s",
                    (const char*)provider->getName().getCString()));
                _unloadProvider(provider);
            }
        }
    }
    catch (...)
    {
        PEG_TRACE_CSTRING(TRC_PROVIDERMANAGER, Tracer::LEVEL1,
            "Caught unexpected exception in unloadIdleProviders.");
    }

    PEG_METHOD_EXIT();
}
Array <JMPIProvider *>
JMPILocalProviderManager::getIndicationProvidersToEnable ()
{
    PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
        "JMPILocalProviderManager::getIndicationProvidersToEnable");

    Array <JMPIProvider *> enableProviders;

    try
    {
        AutoMutex lock (_providerTableMutex);

        Tracer::trace (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
            "Number of providers in _providers table = %d", _providers.size ());

        //
        // Iterate through the _providers table
        //
        for (ProviderTable::Iterator i = _providers.start (); i != 0; i++)
        {
            //
            //  Enable any indication provider with current subscriptions
            //
            JMPIProvider * provider = i.value ();
            if (provider->testSubscriptions ())
            {
                enableProviders.append (provider);
            }
        }
    }
    catch (CIMException & e)
    {
        PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL2,
            "CIMException: " + e.getMessage ());
    }
    catch (Exception & e)
    {
        PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL2,
            "Exception: " + e.getMessage ());
    }
    catch (...)
    {
        PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL2,
            "Unexpected error in getIndicationProvidersToEnable");
    }

    Tracer::trace (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
        "Number of indication providers to enable = %d",
        enableProviders.size ());

    PEG_METHOD_EXIT ();
    return enableProviders;
}
CIMResponseMessage*
DefaultProviderManager::_handleSubscriptionInitCompleteRequest(
    CIMRequestMessage* message)
{
    PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
        "DefaultProviderManager::_handleSubscriptionInitCompleteRequest");

    CIMSubscriptionInitCompleteRequestMessage* request =
        dynamic_cast<CIMSubscriptionInitCompleteRequestMessage*>(message);
    PEGASUS_ASSERT(request != 0);

    CIMSubscriptionInitCompleteResponseMessage* response =
        dynamic_cast<CIMSubscriptionInitCompleteResponseMessage*>(
            request->buildResponse());
    PEGASUS_ASSERT(response != 0);

    _subscriptionInitComplete = true;

    // Make a copy of the table so it is not locked during the provider calls
    Array<ProviderMessageHandler*> providerList;
    {
        AutoMutex lock(_providerTableMutex);

        for (ProviderTable::Iterator i = _providers.start(); i != 0; i++)
        {
            providerList.append(i.value());
        }
    }

    //
    // Notify all providers that subscription initialization is complete
    //
    for (Uint32 j = 0; j < providerList.size(); j++)
    {
        AutoMutex lock(providerList[j]->status.getStatusMutex());

        if (providerList[j]->status.isInitialized())
        {
            providerList[j]->subscriptionInitComplete();
        }
    }

    PEG_METHOD_EXIT();
    return response;
}
DefaultProviderManager::~DefaultProviderManager()
{
    PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
        "DefaultProviderManager::~DefaultProviderManager");

    _shutdownAllProviders();

    for (ProviderTable::Iterator i = _providers.start(); i != 0; i++)
    {
        ProviderMessageHandler* provider = i.value();
        delete provider;
    }

    for (ModuleTable::Iterator j = _modules.start(); j != 0; j++)
    {
        ProviderModule* module = j.value();
        delete module;
    }

    PEG_METHOD_EXIT();
}
void DefaultProviderManager::_shutdownAllProviders()
{
    PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
        "DefaultProviderManager::_shutdownAllProviders");

    AutoMutex lock(_providerTableMutex);
    PEG_TRACE((TRC_PROVIDERMANAGER, Tracer::LEVEL4,
        "providers in cache = %d", _providers.size()));

    //create an array of UnloadProviderRequest requests one per 
    //provider to process shutdown of providers simultaneously.
    Array<AsyncRequestExecutor::AsyncRequestMsg*> ProviderRequests;
    for (ProviderTable::Iterator i = _providers.start(); i != 0; i++)
    {
        AutoMutex lock(i.value()->status.getStatusMutex());
        if(i.value()->status.isInitialized())
        { 
            ProviderRequests.append(
                new UnloadProviderRequest(i.value()));
        }
    }

    //run the stop request on all providers on multiple threads using
    //the request executor. This will invoke _asyncRequestCallback() on a
    //seperate thread for each provider which in turn will unload that
    //provider.
 
    CIMException exception =
        AsyncRequestExecutor(&_asyncRequestCallback,this).executeRequests(
            ProviderRequests);

    if(exception.getCode() != CIM_ERR_SUCCESS)
    {
        PEG_TRACE_CSTRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
            "Unexpected Exception in _shutdownAllProviders().");
    }

    PEG_METHOD_EXIT();
}