00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00036 #include "OW_config.h"
00037 #include "OW_CppProviderIFC.hpp"
00038 #include "OW_SharedLibraryException.hpp"
00039 #include "OW_SharedLibraryLoader.hpp"
00040 #include "OW_Format.hpp"
00041 #include "OW_SignalScope.hpp"
00042 #include "OW_ConfigOpts.hpp"
00043 #include "OW_FileSystem.hpp"
00044 #include "OW_CppProxyProvider.hpp"
00045 #include "OW_NoSuchProviderException.hpp"
00046 #include "OW_Assertion.hpp"
00047 #include "OW_IntrusiveCountableBase.hpp"
00048 #include "OW_NonRecursiveMutex.hpp"
00049 #include "OW_NonRecursiveMutexLock.hpp"
00050 #include "OW_Condition.hpp"
00051 #include "OW_ExceptionIds.hpp"
00052 #include "OW_RepositoryIFC.hpp"
00053
00054 namespace OW_NAMESPACE
00055 {
00056
00057 OW_DECLARE_EXCEPTION(CppProviderIFC);
00058 OW_DEFINE_EXCEPTION_WITH_ID(CppProviderIFC);
00059
00060
00061 typedef CppProviderBaseIFC* (*ProviderCreationFunc)();
00062 typedef const char* (*versionFunc_t)();
00063 namespace
00064 {
00065 const String COMPONENT_NAME("ow.provider.cpp.ifc");
00066
00067 class ProvRegEnv : public ProviderRegistrationEnvironmentIFC
00068 {
00069 public:
00070 ProvRegEnv(const ProviderEnvironmentIFCRef& env)
00071 : ProviderRegistrationEnvironmentIFC()
00072 , m_env(env)
00073 {
00074 }
00075
00076 virtual ~ProvRegEnv()
00077 {
00078 }
00079
00080 virtual RepositoryIFCRef getRepository() const
00081 {
00082 return m_env->getRepository();
00083 }
00084
00085 virtual LoggerRef getLogger(const String& componentName) const
00086 {
00087 return m_env->getLogger(componentName);
00088 }
00089
00090 virtual String getConfigItem(const String &name, const String& defRetVal="") const
00091 {
00092 return m_env->getConfigItem(name, defRetVal);
00093 }
00094
00095 virtual StringArray getMultiConfigItem(const String &itemName,
00096 const StringArray& defRetVal, const char* tokenizeSeparator = 0) const
00097 {
00098 return m_env->getMultiConfigItem(itemName, defRetVal, tokenizeSeparator);
00099 }
00100
00101 virtual ProviderRegistrationEnvironmentIFCRef clone() const
00102 {
00103 return ProviderRegistrationEnvironmentIFCRef(new ProvRegEnv(m_env));
00104 }
00105
00106 private:
00107 ProviderEnvironmentIFCRef m_env;
00108 };
00109
00110 ProviderRegistrationEnvironmentIFCRef
00111 createProvRegEnv(const ProviderEnvironmentIFCRef& env)
00112 {
00113 return ProviderRegistrationEnvironmentIFCRef(new ProvRegEnv(env));
00114 }
00115
00116 }
00117
00118 const char* const CppProviderIFC::CREATIONFUNC = "createProvider";
00119
00121 class CppProviderIFC::CppProviderInitializationHelper : public IntrusiveCountableBase
00122 {
00123 public:
00124
00125 explicit CppProviderInitializationHelper(const CppProviderBaseIFCRef& provider)
00126 : m_initialized(false)
00127 , m_initializeFailed(false)
00128 , m_provider(provider)
00129 {
00130
00131 }
00132
00133
00134 bool waitUntilInitialized() const
00135 {
00136 NonRecursiveMutexLock l(m_initializedGuard);
00137 while (!m_initialized && !m_initializeFailed)
00138 {
00139 m_initializedCond.wait(l);
00140 }
00141 return !m_initializeFailed;
00142 }
00143
00144 void initialize(const ProviderEnvironmentIFCRef& env)
00145 {
00146 try
00147 {
00148 m_provider->initialize(env);
00149 }
00150 catch (...)
00151 {
00152 NonRecursiveMutexLock l(m_initializedGuard);
00153 m_initializeFailed = true;
00154 m_initializedCond.notifyAll();
00155 throw;
00156 }
00157
00158 NonRecursiveMutexLock l(m_initializedGuard);
00159 m_initialized = true;
00160 m_initializedCond.notifyAll();
00161 }
00162
00163 CppProviderBaseIFCRef getProvider() const
00164 {
00165 return m_provider;
00166 }
00167 private:
00168 bool m_initialized;
00169 bool m_initializeFailed;
00170 mutable NonRecursiveMutex m_initializedGuard;
00171 mutable Condition m_initializedCond;
00172 CppProviderBaseIFCRef m_provider;
00173 };
00174
00176 CppProviderIFC::CppProviderIFC()
00177 : ProviderIFCBaseIFC()
00178 , m_provs()
00179 , m_guard()
00180 , m_noUnloadProviders()
00181 , m_loadDone(false)
00182 {
00183 }
00185 CppProviderIFC::~CppProviderIFC()
00186 {
00187 try
00188 {
00189 ProviderMap::iterator it = m_provs.begin();
00190 while (it != m_provs.end())
00191 {
00192 it->second = 0;
00193 it++;
00194 }
00195
00196 m_provs.clear();
00197
00198 for (size_t i = 0; i < m_noUnloadProviders.size(); i++)
00199 {
00200 m_noUnloadProviders[i].setNull();
00201 }
00202
00203 m_noUnloadProviders.clear();
00204 }
00205 catch (...)
00206 {
00207
00208 }
00209 }
00211 void
00212 CppProviderIFC::doInit(const ProviderEnvironmentIFCRef& env,
00213 InstanceProviderInfoArray& i,
00214 SecondaryInstanceProviderInfoArray& si,
00215 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00216 AssociatorProviderInfoArray& a,
00217 #endif
00218 MethodProviderInfoArray& m,
00219 IndicationProviderInfoArray& ind)
00220 {
00221 loadProviders(env, i,
00222 si,
00223 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00224 a,
00225 #endif
00226 m,
00227 ind);
00228 }
00230 InstanceProviderIFCRef
00231 CppProviderIFC::doGetInstanceProvider(const ProviderEnvironmentIFCRef& env,
00232 const char* provIdString)
00233 {
00234 CppProviderBaseIFCRef pProv = getProvider(env, provIdString);
00235 if (pProv)
00236 {
00237 CppInstanceProviderIFC* pIP = pProv->getInstanceProvider();
00238 if (pIP)
00239 {
00240 OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME),
00241 Format("CPPProviderIFC found instance provider %1", provIdString));
00242 CppInstanceProviderIFCRef ipRef(pProv.getLibRef(), pIP);
00243
00244 return InstanceProviderIFCRef(new CppInstanceProviderProxy(ipRef));
00245 }
00246 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Provider %1 is not an instance provider",
00247 provIdString));
00248 }
00249 OW_THROW(NoSuchProviderException, provIdString);
00250 }
00252 SecondaryInstanceProviderIFCRef
00253 CppProviderIFC::doGetSecondaryInstanceProvider(const ProviderEnvironmentIFCRef& env,
00254 const char* provIdString)
00255 {
00256 CppProviderBaseIFCRef pProv = getProvider(env, provIdString);
00257 if (pProv)
00258 {
00259 CppSecondaryInstanceProviderIFC* pIP = pProv->getSecondaryInstanceProvider();
00260 if (pIP)
00261 {
00262 OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME),
00263 Format("CPPProviderIFC found secondary instance provider %1", provIdString));
00264 CppSecondaryInstanceProviderIFCRef ipRef(pProv.getLibRef(), pIP);
00265
00266 return SecondaryInstanceProviderIFCRef(new CppSecondaryInstanceProviderProxy(ipRef));
00267 }
00268 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Provider %1 is not a secondary instance provider",
00269 provIdString));
00270 }
00271 OW_THROW(NoSuchProviderException, provIdString);
00272 }
00274 IndicationExportProviderIFCRefArray
00275 CppProviderIFC::doGetIndicationExportProviders(const ProviderEnvironmentIFCRef&)
00276 {
00277 IndicationExportProviderIFCRefArray rvra;
00278 for (size_t i = 0; i < m_noUnloadProviders.size(); i++)
00279 {
00280 CppProviderBaseIFCRef pProv = m_noUnloadProviders[i];
00281 CppIndicationExportProviderIFC* pIEP =
00282 pProv->getIndicationExportProvider();
00283 if (pIEP)
00284 {
00285 CppIndicationExportProviderIFCRef iepRef(pProv.getLibRef(), pIEP);
00286
00287 rvra.append(
00288 IndicationExportProviderIFCRef(new
00289 CppIndicationExportProviderProxy(iepRef)));
00290 }
00291 }
00292 return rvra;
00293 }
00295 PolledProviderIFCRefArray
00296 CppProviderIFC::doGetPolledProviders(const ProviderEnvironmentIFCRef&)
00297 {
00298 PolledProviderIFCRefArray rvra;
00299 for (size_t i = 0; i < m_noUnloadProviders.size(); i++)
00300 {
00301 CppProviderBaseIFCRef pProv = m_noUnloadProviders[i];
00302 CppPolledProviderIFC* pPP = pProv->getPolledProvider();
00303 if (pPP)
00304 {
00305 CppPolledProviderIFCRef ppRef(pProv.getLibRef(), pPP);
00306
00307 rvra.append(
00308 PolledProviderIFCRef(new
00309 CppPolledProviderProxy(ppRef)));
00310 }
00311 }
00312 return rvra;
00313 }
00315 MethodProviderIFCRef
00316 CppProviderIFC::doGetMethodProvider(const ProviderEnvironmentIFCRef& env,
00317 const char* provIdString)
00318 {
00319 CppProviderBaseIFCRef pProv = getProvider(env, provIdString);
00320 if (pProv)
00321 {
00322 CppMethodProviderIFC* pMP = pProv->getMethodProvider();
00323 if (pMP)
00324 {
00325 OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("CPPProviderIFC found method provider %1",
00326 provIdString));
00327 CppMethodProviderIFCRef mpRef(pProv.getLibRef(), pMP);
00328
00329 return MethodProviderIFCRef(
00330 new CppMethodProviderProxy(mpRef));
00331 }
00332 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Provider %1 is not a method provider",
00333 provIdString));
00334 }
00335 OW_THROW(NoSuchProviderException, provIdString);
00336 }
00337 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00338
00339 AssociatorProviderIFCRef
00340 CppProviderIFC::doGetAssociatorProvider(const ProviderEnvironmentIFCRef& env,
00341 const char* provIdString)
00342 {
00343 CppProviderBaseIFCRef pProv = getProvider(env, provIdString);
00344 if (pProv)
00345 {
00346 CppAssociatorProviderIFC* pAP = pProv->getAssociatorProvider();
00347 if (pAP)
00348 {
00349 OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("CPPProviderIFC found associator provider %1",
00350 provIdString));
00351 CppAssociatorProviderIFCRef apRef(pProv.getLibRef(), pAP);
00352
00353 return AssociatorProviderIFCRef(new
00354 CppAssociatorProviderProxy(apRef));
00355 }
00356 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Provider %1 is not an associator provider",
00357 provIdString));
00358 }
00359 OW_THROW(NoSuchProviderException, provIdString);
00360 }
00361 #endif
00362
00363 IndicationProviderIFCRef
00364 CppProviderIFC::doGetIndicationProvider(const ProviderEnvironmentIFCRef& env,
00365 const char* provIdString)
00366 {
00367 CppProviderBaseIFCRef pProv = getProvider(env, provIdString);
00368 if (pProv)
00369 {
00370 CppIndicationProviderIFC* pAP = pProv->getIndicationProvider();
00371 if (pAP)
00372 {
00373 OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("CPPProviderIFC found indication provider %1",
00374 provIdString));
00375
00376 IndicationProviderMap::const_iterator ci = m_indicationProviders.find(provIdString);
00377 if (ci != m_indicationProviders.end())
00378 {
00379 return ci->second;
00380 }
00381
00382 CppIndicationProviderIFCRef apRef(pProv.getLibRef(), pAP);
00383
00384 IndicationProviderIFCRef rv(new
00385 CppIndicationProviderProxy(apRef));
00386
00387 m_indicationProviders.insert(IndicationProviderMap::value_type(provIdString, rv));
00388
00389 return rv;
00390 }
00391 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Provider %1 is not an indication provider",
00392 provIdString));
00393 }
00394 OW_THROW(NoSuchProviderException, provIdString);
00395 }
00397 void
00398 CppProviderIFC::loadProviders(const ProviderEnvironmentIFCRef& env,
00399 InstanceProviderInfoArray& instanceProviderInfo,
00400 SecondaryInstanceProviderInfoArray& secondaryInstanceProviderInfo,
00401 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00402 AssociatorProviderInfoArray& associatorProviderInfo,
00403 #endif
00404 MethodProviderInfoArray& methodProviderInfo,
00405 IndicationProviderInfoArray& indicationProviderInfo)
00406 {
00407 MutexLock ml(m_guard);
00408 if (m_loadDone)
00409 {
00410 return;
00411 }
00412 m_loadDone = true;
00413
00414
00415
00416 SharedLibraryLoaderRef ldr =
00417 SharedLibraryLoader::createSharedLibraryLoader();
00418 if (!ldr)
00419 {
00420 const char* msg = "C++ provider ifc failed to get shared lib loader";
00421 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), msg);
00422 OW_THROW(CppProviderIFCException, msg);
00423 }
00424
00425 StringArray paths = env->getMultiConfigItem(
00426 ConfigOpts::CPPPROVIFC_PROV_LOCATION_opt,
00427 String(OW_DEFAULT_CPPPROVIFC_PROV_LOCATION).tokenize(OW_PATHNAME_SEPARATOR),
00428 OW_PATHNAME_SEPARATOR);
00429 for (StringArray::size_type i1 = 0; i1 < paths.size(); i1++)
00430 {
00431 StringArray dirEntries;
00432 if (!FileSystem::getDirectoryContents(paths[i1], dirEntries))
00433 {
00434 String msg(Format("C++ provider ifc failed getting contents of directory: %1", paths[i1]));
00435 OW_LOG_INFO(env->getLogger(COMPONENT_NAME), msg);
00436 continue;
00437 }
00438 for (size_t i = 0; i < dirEntries.size(); i++)
00439 {
00440 if (!dirEntries[i].endsWith(OW_SHAREDLIB_EXTENSION))
00441 {
00442 continue;
00443 }
00444 String libName = paths[i1];
00445 libName += OW_FILENAME_SEPARATOR;
00446 libName += dirEntries[i];
00447
00448 #ifdef OW_DARWIN
00449 if (!FileSystem::isLink(libName))
00450 {
00451 continue;
00452 }
00453 #endif // OW_DARWIN
00454
00455 SharedLibraryRef theLib = ldr->loadSharedLibrary(libName,
00456 env->getLogger(COMPONENT_NAME));
00457 if (!theLib)
00458 {
00459 String msg(Format("C++ provider ifc failed to load library: %1", libName));
00460 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), "****************************************");
00461 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), msg);
00462 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), "****************************************");
00463 OW_THROW(CppProviderIFCException, msg.c_str());
00464 }
00465 versionFunc_t versFunc;
00466 if (!theLib->getFunctionPointer("getOWVersion",
00467 versFunc))
00468 {
00469 String msg(Format("C++ provider ifc failed getting function pointer to \"getOWVersion\" from"
00470 " library: %1", libName));
00471 OW_LOG_INFO(env->getLogger(COMPONENT_NAME), msg);
00472
00473
00474
00475 continue;
00476 }
00477 const char* strVer = (*versFunc)();
00478 if (strcmp(strVer, OW_VERSION))
00479 {
00480 String msg(Format("C++ provider ifc got invalid version from provider: %1", strVer));
00481 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), "****************************************");
00482 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), msg);
00483 msg = Format("C++ provider ifc version: %1 provider version: %2 library: %3",
00484 OW_VERSION, strVer, libName);
00485 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), msg);
00486 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), "****************************************");
00487 OW_THROW(CppProviderIFCException, msg.c_str());
00488 }
00489 ProviderCreationFunc createProvider;
00490 String creationFuncName = String(CREATIONFUNC) + "NO_ID";
00491 if (!theLib->getFunctionPointer(creationFuncName,
00492 createProvider))
00493 {
00494
00495
00496 String providerid = dirEntries[i];
00497
00498 providerid = providerid.substring(3,
00499 providerid.length() - (strlen(OW_SHAREDLIB_EXTENSION) + 3));
00500
00501 CppProviderBaseIFCRef p = getProvider(env, providerid.c_str(),
00502 dontStoreProvider, dontInitializeProvider);
00503
00504 if (!p)
00505 {
00506 String msg(Format("C++ provider ifc: Libary %1 does not load", libName));
00507 OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), "****************************************");
00508 OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), msg);
00509 OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), "****************************************");
00510 OW_THROW(CppProviderIFCException, msg.c_str());
00511 }
00512
00513
00514
00515
00516
00517
00518 CppPolledProviderIFC* p_polledProv = p->getPolledProvider();
00519 CppIndicationExportProviderIFC* p_indExpProv =
00520 p->getIndicationExportProvider();
00521 if (p_polledProv || p_indExpProv)
00522 {
00523 if (p_indExpProv)
00524 {
00525 OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME),
00526 Format("C++ provider ifc loaded indication export provider from lib: %1 - initializing", libName));
00527 }
00528
00529 if (p_polledProv)
00530 {
00531 OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME),
00532 Format("C++ provider ifc loaded polled provider from lib: %1 - initializing", libName));
00533 }
00534 CppProviderInitializationHelperRef p2(new CppProviderInitializationHelper(p));
00535 p2->initialize(env);
00536 p->setPersist(true);
00537 m_noUnloadProviders.append(p);
00538 m_provs[providerid] = p2;
00539 }
00540
00541 CppInstanceProviderIFC* p_ip = p->getInstanceProvider();
00542 if (p_ip)
00543 {
00544 InstanceProviderInfo info;
00545 info.setProviderName(providerid);
00546 p_ip->getInstanceProviderInfoWithEnv(
00547 createProvRegEnv(env), info);
00548 instanceProviderInfo.push_back(info);
00549 }
00550
00551 CppSecondaryInstanceProviderIFC* p_sip =
00552 p->getSecondaryInstanceProvider();
00553
00554 if (p_sip)
00555 {
00556 SecondaryInstanceProviderInfo info;
00557 info.setProviderName(providerid);
00558 p_sip->getSecondaryInstanceProviderInfoWithEnv(
00559 createProvRegEnv(env), info);
00560 secondaryInstanceProviderInfo.push_back(info);
00561 }
00562 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00563 CppAssociatorProviderIFC* p_ap = p->getAssociatorProvider();
00564 if (p_ap)
00565 {
00566 AssociatorProviderInfo info;
00567 info.setProviderName(providerid);
00568 p_ap->getAssociatorProviderInfoWithEnv(
00569 createProvRegEnv(env), info);
00570 associatorProviderInfo.push_back(info);
00571 }
00572 #endif
00573 CppMethodProviderIFC* p_mp = p->getMethodProvider();
00574 if (p_mp)
00575 {
00576 MethodProviderInfo info;
00577 info.setProviderName(providerid);
00578 p_mp->getMethodProviderInfoWithEnv(
00579 createProvRegEnv(env), info);
00580 methodProviderInfo.push_back(info);
00581 }
00582 CppIndicationProviderIFC* p_indp = p->getIndicationProvider();
00583 if (p_indp)
00584 {
00585 IndicationProviderInfo info;
00586 info.setProviderName(providerid);
00587 p_indp->getIndicationProviderInfoWithEnv(
00588 createProvRegEnv(env), info);
00589 indicationProviderInfo.push_back(info);
00590 }
00591
00592 continue;
00593 }
00594
00595
00596
00597
00598 AutoPtr<CppProviderBaseIFC> pProv((*createProvider)());
00599 if (!pProv.get())
00600 {
00601 String msg(Format("C++ provider ifc: Libary %1 - %2 returned null provider", libName, creationFuncName));
00602 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), "****************************************");
00603 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), msg);
00604 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), "****************************************");
00605 OW_THROW(CppProviderIFCException, msg.c_str());
00606 }
00607 CppPolledProviderIFC* p_itp = pProv->getPolledProvider();
00608 CppIndicationExportProviderIFC* p_iep =
00609 pProv->getIndicationExportProvider();
00610 if (p_itp || p_iep)
00611 {
00612 if (p_iep)
00613 {
00614 OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME),
00615 Format("C++ provider ifc loaded indication export provider from lib: %1 - initializing", libName));
00616 }
00617 if (p_itp)
00618 {
00619 OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME),
00620 Format("C++ provider ifc loaded polled provider from lib: %1 - initializing",
00621 libName));
00622 }
00623
00624 pProv->initialize(env);
00625 m_noUnloadProviders.append(CppProviderBaseIFCRef(theLib,
00626 pProv.release()));
00627 }
00628 }
00629 }
00630 }
00631
00633
00634 CppProviderBaseIFCRef
00635 CppProviderIFC::loadProvider(const String& libName, LoggerRef logger)
00636 {
00637 String provId = libName.substring(libName.lastIndexOf(OW_FILENAME_SEPARATOR)+1);
00638
00639 provId = provId.substring(3, provId.length() - (strlen(OW_SHAREDLIB_EXTENSION) + 3));
00640
00641 SharedLibraryLoaderRef ldr = SharedLibraryLoader::createSharedLibraryLoader();
00642 if (!ldr)
00643 {
00644 OW_LOG_ERROR(logger, "C++ provider ifc FAILED to get shared lib loader");
00645 return CppProviderBaseIFCRef();
00646 }
00647
00648 OW_LOG_DEBUG(logger, Format("CppProviderIFC::loadProvider loading library: %1", libName));
00649
00650 SharedLibraryRef theLib = ldr->loadSharedLibrary(libName, logger);
00651
00652 versionFunc_t versFunc;
00653 if (!theLib->getFunctionPointer("getOWVersion", versFunc))
00654 {
00655 OW_LOG_ERROR(logger, Format("C++ provider ifc failed getting function pointer to \"getOWVersion\" from library %1.", libName));
00656 return CppProviderBaseIFCRef();
00657 }
00658 const char* strVer = (*versFunc)();
00659 if (strcmp(strVer, OW_VERSION))
00660 {
00661 OW_LOG_ERROR(logger, "C++ provider ifc got invalid version from provider");
00662 OW_LOG_ERROR(logger, Format("C++ provider ifc version: %1 provider version: %2 library: %3",
00663 OW_VERSION, strVer, libName));
00664 return CppProviderBaseIFCRef();
00665 }
00666
00667 ProviderCreationFunc createProvider;
00668 String creationFuncName = String(CREATIONFUNC) + provId;
00669 if (!theLib->getFunctionPointer(creationFuncName, createProvider))
00670 {
00671 OW_LOG_ERROR(logger, Format("C++ provider ifc: Libary %1 does not contain %2 function.",
00672 libName, creationFuncName));
00673 return CppProviderBaseIFCRef();
00674 }
00675
00676 CppProviderBaseIFC* pProv = (*createProvider)();
00677
00678 if (!pProv)
00679 {
00680 OW_LOG_ERROR(logger, Format("C++ provider ifc: Libary %1 -"
00681 " %2 returned null provider. Not loaded.", libName, creationFuncName));
00682 return CppProviderBaseIFCRef();
00683 }
00684
00685 CppProviderBaseIFCRef rval(theLib, pProv);
00686
00687 OW_LOG_DEBUG(logger, Format("C++ provider ifc successfully loaded library %1 for provider %2", libName, provId));
00688
00689 return rval;
00690 }
00691
00693 CppProviderBaseIFCRef
00694 CppProviderIFC::getProvider(
00695 const ProviderEnvironmentIFCRef& env, const char* provIdString,
00696 StoreProviderFlag storeP, InitializeProviderFlag initP)
00697 {
00698 OW_ASSERT((initP == initializeProvider && storeP == storeProvider) || (initP == dontInitializeProvider && storeP == dontStoreProvider));
00699
00700 MutexLock ml(m_guard);
00701
00702 String provId(provIdString);
00703 ProviderMap::iterator it = m_provs.find(provId);
00704 if (it != m_provs.end())
00705 {
00706
00707 CppProviderInitializationHelperRef prov(it->second);
00708
00709 ml.release();
00710
00711
00712 if (prov->waitUntilInitialized())
00713 {
00714 return prov->getProvider();
00715 }
00716 else
00717 {
00718
00719 return CppProviderBaseIFCRef();
00720 }
00721 }
00722
00723 String libName;
00724 CppProviderBaseIFCRef rval;
00725
00726 StringArray paths = env->getMultiConfigItem(
00727 ConfigOpts::CPPPROVIFC_PROV_LOCATION_opt,
00728 String(OW_DEFAULT_CPPPROVIFC_PROV_LOCATION).tokenize(OW_PATHNAME_SEPARATOR),
00729 OW_PATHNAME_SEPARATOR);
00730 for (StringArray::size_type i = 0; i < paths.size(); i++)
00731 {
00732 libName = paths[i];
00733 libName += OW_FILENAME_SEPARATOR;
00734 libName += "lib";
00735 libName += provId;
00736 libName += OW_SHAREDLIB_EXTENSION;
00737
00738 if (!FileSystem::exists(libName))
00739 {
00740 continue;
00741 }
00742
00743 rval = loadProvider(libName, env->getLogger(COMPONENT_NAME));
00744
00745 if (rval)
00746 {
00747 break;
00748 }
00749
00750 }
00751
00752 if (!rval)
00753 {
00754 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME),
00755 Format("C++ provider ifc failed to load library: %1 for provider id %2.", libName, provId));
00756 return rval;
00757 }
00758
00759 if (initP == initializeProvider && storeP == storeProvider)
00760 {
00761 CppProviderInitializationHelperRef provInitHelper(new CppProviderInitializationHelper(rval));
00762
00763 m_provs[provId] = provInitHelper;
00764
00765
00766 ml.release();
00767
00768 OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME),
00769 Format("C++ provider ifc calling initialize for provider %1", provId));
00770
00771 try
00772 {
00773 provInitHelper->initialize(env);
00774 }
00775 catch (...)
00776 {
00777
00778 MutexLock lock(m_guard);
00779 m_provs.erase(provId);
00780 throw;
00781 }
00782
00783 OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME),
00784 Format("C++ provider ifc: provider %1 loaded and initialized", provId));
00785
00786 }
00787 else
00788 {
00789 OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME),
00790 Format("C++ provider ifc: provider %1 loaded but not initialized", provId));
00791 }
00792
00793 return rval;
00794 }
00796 void
00797 CppProviderIFC::doUnloadProviders(const ProviderEnvironmentIFCRef& env)
00798 {
00799 String timeWindow = env->getConfigItem(ConfigOpts::CPPPROVIFC_PROV_TTL_opt, OW_DEFAULT_CPPPROVIFC_PROV_TTL);
00800 Int32 iTimeWindow;
00801 try
00802 {
00803 iTimeWindow = timeWindow.toInt32();
00804 }
00805 catch (const StringConversionException&)
00806 {
00807 iTimeWindow = String(OW_DEFAULT_CPPPROVIFC_PROV_TTL).toInt32();
00808 }
00809 if (iTimeWindow < 0)
00810 {
00811 return;
00812 }
00813 DateTime dt;
00814 dt.setToCurrent();
00815 MutexLock l(m_guard);
00816 for (ProviderMap::iterator iter = m_provs.begin();
00817 iter != m_provs.end();)
00818 {
00819
00820 if (!iter->second->getProvider()->getPersist())
00821 {
00822 DateTime provDt = iter->second->getProvider()->getLastAccessTime();
00823 provDt.addMinutes(iTimeWindow);
00824 if (provDt < dt && iter->second->getProvider()->canUnload())
00825 {
00826 OW_LOG_INFO(env->getLogger(COMPONENT_NAME), Format("Unloading Provider %1",
00827 iter->first));
00828 iter->second = 0;
00829 m_provs.erase(iter++);
00830 continue;
00831 }
00832 }
00833
00834 ++iter;
00835 }
00836 }
00837
00838 void CppProviderIFC::doShuttingDown(const ProviderEnvironmentIFCRef& env)
00839 {
00840
00841
00842 MutexLock l(m_guard);
00843 ProviderMap provsCopy(m_provs);
00844 LoadedProviderArray noUnloadProvidersCopy(m_noUnloadProviders);
00845 l.release();
00846
00847 ProviderMap::iterator it, itend = provsCopy.end();
00848 for (it = provsCopy.begin(); it != itend; ++it)
00849 {
00850 try
00851 {
00852 it->second->getProvider()->shuttingDown(env);
00853 }
00854 catch (Exception& e)
00855 {
00856 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Caught exception while calling shuttingDown() on provider: %1", e));
00857 }
00858 }
00859
00860
00861
00862 for (LoadedProviderArray::iterator curProv = noUnloadProvidersCopy.begin(); curProv != noUnloadProvidersCopy.end(); ++curProv)
00863 {
00864 bool found(false);
00865
00866 for (it = provsCopy.begin(); it != itend; ++it)
00867 {
00868 if (it->second->getProvider() == *curProv)
00869 {
00870 found = true;
00871 break;
00872 }
00873 }
00874
00875 if (!found)
00876 {
00877 try
00878 {
00879 (*curProv)->shuttingDown(env);
00880 }
00881 catch (Exception& e)
00882 {
00883 OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Caught exception while calling shuttingDown() on provider: %1", e));
00884 }
00885 }
00886 }
00887 }
00888
00889 }
00890