void Ice::PluginManagerI::loadPlugin(const string& name, const string& pluginSpec, StringSeq& cmdArgs) { assert(_communicator); string entryPoint; StringSeq args; if(!pluginSpec.empty()) { // // Split the entire property value into arguments. An entry point containing spaces // must be enclosed in quotes. // try { args = IceUtilInternal::Options::split(pluginSpec); } catch(const IceUtilInternal::BadOptException& ex) { PluginInitializationException e(__FILE__, __LINE__); e.reason = "invalid arguments for plug-in `" + name + "':\n" + ex.reason; throw e; } assert(!args.empty()); // // Shift the arguments. // entryPoint = args[0]; args.erase(args.begin()); // // Convert command-line options into properties. First we // convert the options from the plug-in configuration, then // we convert the options from the application command-line. // PropertiesPtr properties = _communicator->getProperties(); args = properties->parseCommandLineOptions(name, args); cmdArgs = properties->parseCommandLineOptions(name, cmdArgs); } PluginFactory factory = 0; DynamicLibraryPtr library; // // Always check the static plugin factory table first, it takes // precedence over the the entryPoint specified in the plugin // property value. // if(factories) { map<string, PluginFactory>::const_iterator p = factories->find(name); if(p != factories->end()) { factory = p->second; } } // // If we didn't find the factory, get the factory using the entry // point symbol. // if(!factory) { assert(!entryPoint.empty()); library = new DynamicLibrary(); DynamicLibrary::symbol_type sym = library->loadEntryPoint(entryPoint); if(sym == 0) { ostringstream out; string msg = library->getErrorMessage(); out << "unable to load entry point `" << entryPoint << "'"; if(!msg.empty()) { out << ": " + msg; } PluginInitializationException ex(__FILE__, __LINE__); ex.reason = out.str(); throw ex; } #ifdef __IBMCPP__ // xlC warns when casting a void* to function pointer # pragma report(disable, "1540-0216") #endif factory = reinterpret_cast<PluginFactory>(sym); } // // Invoke the factory function. No exceptions can be raised // by the factory function because it's declared extern "C". // PluginPtr plugin(factory(_communicator, name, args)); if(!plugin) { PluginInitializationException e(__FILE__, __LINE__); ostringstream out; out << "failure in entry point `" << entryPoint << "'"; e.reason = out.str(); throw e; } PluginInfo info; info.name = name; info.plugin = plugin; _plugins.push_back(info); if(library) { _libraries->add(library); } }
Freeze::MapDb::MapDb(const ConnectionIPtr& connection, const string& dbName, const string& key, const string& value, const KeyCompareBasePtr& keyCompare, const vector<MapIndexBasePtr>& indices, bool createDb) : Db(connection->dbEnv()->getEnv(), 0), _communicator(connection->communicator()), _dbName(dbName), _trace(connection->trace()), _keyCompare(keyCompare) { if(_trace >= 1) { Trace out(_communicator->getLogger(), "Freeze.Map"); out << "opening Db \"" << _dbName << "\""; } Catalog catalog(connection, _catalogName); TransactionPtr tx = connection->currentTransaction(); bool ownTx = (tx == 0); for(;;) { try { if(ownTx) { tx = 0; tx = connection->beginTransaction(); } Catalog::iterator ci = catalog.find(_dbName); if(ci != catalog.end()) { if(ci->second.evictor) { throw DatabaseException(__FILE__, __LINE__, _dbName + " is an evictor database"); } _key = ci->second.key; _value = ci->second.value; checkTypes(key, value); } else { _key = key; _value = value; } set_app_private(this); if(_keyCompare->compareEnabled()) { set_bt_compare(&customCompare); } PropertiesPtr properties = _communicator->getProperties(); string propPrefix = "Freeze.Map." + _dbName + "."; int btreeMinKey = properties->getPropertyAsInt(propPrefix + "BtreeMinKey"); if(btreeMinKey > 2) { if(_trace >= 1) { Trace out(_communicator->getLogger(), "Freeze.Map"); out << "Setting \"" << _dbName << "\"'s btree minkey to " << btreeMinKey; } set_bt_minkey(btreeMinKey); } bool checksum = properties->getPropertyAsInt(propPrefix + "Checksum") > 0; if(checksum) { if(_trace >= 1) { Trace out(_communicator->getLogger(), "Freeze.Map"); out << "Turning checksum on for \"" << _dbName << "\""; } set_flags(DB_CHKSUM); } int pageSize = properties->getPropertyAsInt(propPrefix + "PageSize"); if(pageSize > 0) { if(_trace >= 1) { Trace out(_communicator->getLogger(), "Freeze.Map"); out << "Setting \"" << _dbName << "\"'s pagesize to " << pageSize; } set_pagesize(pageSize); } DbTxn* txn = getTxn(tx); u_int32_t flags = DB_THREAD; if(createDb) { flags |= DB_CREATE; } open(txn, Ice::nativeToUTF8(_communicator, _dbName).c_str(), 0, DB_BTREE, flags, FREEZE_DB_MODE); StringSeq oldIndices; StringSeq newIndices; size_t oldSize = 0; CatalogIndexList catalogIndexList(connection, _catalogIndexListName); if(createDb) { CatalogIndexList::iterator cil = catalogIndexList.find(_dbName); if(cil != catalogIndexList.end()) { oldIndices = cil->second; oldSize = oldIndices.size(); } } for(vector<MapIndexBasePtr>::const_iterator p = indices.begin(); p != indices.end(); ++p) { const MapIndexBasePtr& indexBase = *p; assert(indexBase->_impl == 0); assert(indexBase->_communicator == 0); indexBase->_communicator = connection->communicator(); auto_ptr<MapIndexI> indexI; try { indexI.reset(new MapIndexI(connection, *this, txn, createDb, indexBase)); } catch(const DbDeadlockException&) { throw; } catch(const DbException& dx) { string message = "Error while opening index \"" + _dbName + "." + indexBase->name() + "\": " + dx.what(); throw DatabaseException(__FILE__, __LINE__, message); } #ifndef NDEBUG bool inserted = #endif _indices.insert(IndexMap::value_type(indexBase->name(), indexI.get())).second; assert(inserted); indexBase->_impl = indexI.release(); if(createDb) { newIndices.push_back(indexBase->name()); oldIndices.erase(std::remove(oldIndices.begin(), oldIndices.end(), indexBase->name()), oldIndices.end()); } } if(ci == catalog.end()) { CatalogData catalogData; catalogData.evictor = false; catalogData.key = key; catalogData.value = value; catalog.put(Catalog::value_type(_dbName, catalogData)); } if(createDb) { // // Remove old indices and write the new ones // bool indexRemoved = false; for(StringSeq::const_iterator q = oldIndices.begin(); q != oldIndices.end(); ++q) { const string& index = *q; if(_trace >= 1) { Trace out(_communicator->getLogger(), "Freeze.Map"); out << "removing old index \"" << index << "\" on Db \"" << _dbName << "\""; } try { connection->removeMapIndex(_dbName, *q); indexRemoved = true; } catch(const IndexNotFoundException&) { // Ignored if(_trace >= 1) { Trace out(_communicator->getLogger(), "Freeze.Map"); out << "index \"" << index << "\" on Db \"" << _dbName << "\" does not exist"; } } } if(indexRemoved || oldSize != newIndices.size()) { if(newIndices.size() == 0) { catalogIndexList.erase(_dbName); if(_trace >= 1) { Trace out(_communicator->getLogger(), "Freeze.Map"); out << "Removed catalogIndexList entry for Db \"" << _dbName << "\""; } } else { catalogIndexList.put(CatalogIndexList::value_type(_dbName, newIndices)); if(_trace >= 1) { Trace out(_communicator->getLogger(), "Freeze.Map"); out << "Updated catalogIndexList entry for Db \"" << _dbName << "\""; } } } } if(ownTx) { tx->commit(); } break; // for(;;) } catch(const DbDeadlockException& dx) { if(ownTx) { if(connection->deadlockWarning()) { Warning out(connection->communicator()->getLogger()); out << "Deadlock in Freeze::MapDb::MapDb on Map \"" << _dbName << "\"; retrying ..."; } // // Ignored, try again // } else { throw DeadlockException(__FILE__, __LINE__, dx.what(), tx); } } catch(const DbException& dx) { if(ownTx) { try { tx->rollback(); } catch(...) { } } string message = "Error while opening Db \"" + _dbName + "\": " + dx.what(); throw DatabaseException(__FILE__, __LINE__, message); } catch(...) { if(ownTx && tx != 0) { try { tx->rollback(); } catch(...) { } } throw; } } }