OW_ProviderAgent.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003 * Copyright (C) 2004 Novell, Inc. All rights reserved.
00004 *
00005 * Redistribution and use in source and binary forms, with or without
00006 * modification, are permitted provided that the following conditions are met:
00007 *
00008 *  - Redistributions of source code must retain the above copyright notice,
00009 *    this list of conditions and the following disclaimer.
00010 *
00011 *  - Redistributions in binary form must reproduce the above copyright notice,
00012 *    this list of conditions and the following disclaimer in the documentation
00013 *    and/or other materials provided with the distribution.
00014 *
00015 *  - Neither the name of Vintela, Inc. nor the names of its
00016 *    contributors may be used to endorse or promote products derived from this
00017 *    software without specific prior written permission.
00018 *
00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00023 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00029 * POSSIBILITY OF SUCH DAMAGE.
00030 *******************************************************************************/
00031 
00037 #include "OW_config.h"
00038 #include "OW_ProviderAgent.hpp"
00039 #include "OW_HTTPServer.hpp"
00040 #include "OW_CIMClass.hpp"
00041 #include "OW_ServiceEnvironmentIFC.hpp"
00042 #include "OW_SelectEngine.hpp"
00043 #include "OW_IOException.hpp"
00044 #include "OW_Thread.hpp"
00045 #include "OW_ProviderAgentEnvironment.hpp"
00046 #include "OW_CppProviderBaseIFC.hpp"
00047 #include "OW_Format.hpp"
00048 
00049 #include <cerrno>
00050 
00051 namespace OW_NAMESPACE
00052 {
00053 
00054 using namespace WBEMFlags;
00055 namespace
00056 {
00057 // This anonymous namespace has the effect of giving this class internal
00058 // linkage.  That means it won't cause a link error if another translation
00059 // unit has a class with the same name.
00060 
00061 
00062 
00063 
00064 class SelectEngineThread : public Thread
00065 {
00066 public:
00067    SelectEngineThread(const Reference<Array<SelectablePair_t> >& selectables,
00068       const ProviderAgentLifecycleCallbackIFCRef& lifecycleCB)
00069    : Thread()
00070    , m_selectables(selectables)
00071    , m_stopObject(UnnamedPipe::createUnnamedPipe())
00072    , m_lifecycleCB(lifecycleCB)
00073    {
00074       m_stopObject->setBlocking(UnnamedPipe::E_NONBLOCKING);
00075    }
00080    virtual Int32 run()
00081    {
00082       try
00083       {
00084          SelectEngine engine;
00085          SelectableCallbackIFCRef cb(new SelectEngineStopper(engine));
00086          m_selectables->push_back(std::make_pair(m_stopObject, cb));
00087          for (size_t i = 0; i < m_selectables->size(); ++i)
00088          {
00089             engine.addSelectableObject((*m_selectables)[i].first,
00090                (*m_selectables)[i].second);
00091          }
00092          if (m_lifecycleCB)
00093          {
00094             m_lifecycleCB->started();
00095          }
00096          engine.go();
00097       }
00098       catch (Exception& e)
00099       {
00100          if (m_lifecycleCB)
00101          {
00102             m_lifecycleCB->fatalError(Format("%1", e));
00103          }
00104          throw;
00105       }
00106       catch (...)
00107       {
00108          if (m_lifecycleCB)
00109          {
00110             m_lifecycleCB->fatalError("unknown");
00111          }
00112          throw;
00113       }
00114       return 0;
00115    }
00116    virtual void doCooperativeCancel()
00117    {
00118       // write something into the stop pipe to stop the select engine so the
00119       // thread will exit
00120       if (m_stopObject->writeInt(0) == -1)
00121       {
00122          OW_THROW_ERRNO_MSG(IOException, "Writing to the termination pipe failed");
00123       }
00124    }
00125 private:
00126    Reference<Array<SelectablePair_t> > m_selectables;
00127    UnnamedPipeRef m_stopObject;
00128    ProviderAgentLifecycleCallbackIFCRef m_lifecycleCB;
00129 };
00130 
00131 
00132 } // end anonymous namespace
00133 
00134 
00135 const char* const ProviderAgent::LockingType_opt = "provider_agent.locking_type";
00136 const char* const ProviderAgent::LockingTypeNone = "none";
00137 const char* const ProviderAgent::LockingTypeSWMR = "swmr";
00138 const char* const ProviderAgent::LockingTypeSingleThreaded = "single_threaded";
00139 
00140 const char* const ProviderAgent::LockingTimeout_opt = "provider_agent.locking_timeout";
00141 const char* const ProviderAgent::DynamicClassRetrieval_opt = "provider_agent.dynamic_class_retrieval";
00142 const char* const ProviderAgent::UseConnectionCredentials_opt = "provider_agent.use_connection_credentials";
00143 
00145 ProviderAgent::ProviderAgent(
00146    const ConfigFile::ConfigMap& configMap,
00147    const Array<CppProviderBaseIFCRef>& providers,
00148    const Array<CIMClass>& cimClasses,
00149    const Array<RequestHandlerIFCRef>& requestHandlers,
00150    const AuthenticatorIFCRef& authenticator,
00151    const LoggerRef& logger,
00152    const String& callbackURL,
00153    const ProviderAgentLockerIFCRef& locker,
00154    const ProviderAgentLifecycleCallbackIFCRef& lifecycleCB)
00155    : m_httpServer(new HTTPServer)
00156    , m_lifecycleCB(lifecycleCB)
00157 {
00158    Reference<Array<SelectablePair_t> >
00159          selectables(new Array<SelectablePair_t>);
00160    ServiceEnvironmentIFCRef env(new ProviderAgentEnvironment(configMap,
00161          providers, cimClasses, authenticator, requestHandlers,
00162          logger, callbackURL, selectables, locker));
00163    m_httpServer->init(env);
00164    m_httpServer->start();  // The http server will add it's server
00165    // sockets to the environment's selectables, which is really
00166    // the selectables defined above.  We'll give these to the select engine
00167    // thread below which will use them to run the select engine.
00168    
00169    // start a thread to run the http server
00170    m_httpThread = new SelectEngineThread(selectables, m_lifecycleCB);
00171    m_httpThread->start();
00172 }
00174 ProviderAgent::~ProviderAgent()
00175 {
00176    try
00177    {
00178       shutdownHttpServer();
00179    }
00180    catch (...)
00181    {
00182       // don't let exceptions escape
00183    }
00184 }
00185 
00187 void
00188 ProviderAgent::shutdownHttpServer()
00189 {
00190    if (m_lifecycleCB)
00191    {
00192       m_lifecycleCB->shuttingDown();
00193    }
00194    if (m_httpThread)
00195    {
00196       m_httpThread->definitiveCancel();
00197       // wait for the thread to quit
00198       m_httpThread->join();
00199       m_httpThread = 0;
00200    }
00201    if (m_httpServer)
00202    {
00203       // stop the http server
00204       m_httpServer->shutdown();
00205       m_httpServer = 0;
00206    }
00207 }
00209 
00210 } // end namespace OW_NAMESPACE
00211 

Generated on Thu Feb 9 08:48:08 2006 for openwbem by  doxygen 1.4.6