ConnectionIPtr IceInternal::OutgoingConnectionFactory::create(const vector<EndpointIPtr>& endpts, bool hasMore, Ice::EndpointSelectionType selType, bool& compress) { assert(!endpts.empty()); // // Apply the overrides. // vector<EndpointIPtr> endpoints = applyOverrides(endpts); // // Try to find a connection to one of the given endpoints. // Ice::ConnectionIPtr connection = findConnection(endpoints, compress); if(connection) { return connection; } IceUtil::UniquePtr<Ice::LocalException> exception; // // If we didn't find a connection with the endpoints, we create the connectors // for the endpoints. // vector<ConnectorInfo> connectors; for(vector<EndpointIPtr>::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p) { // // Create connectors for the endpoint. // try { vector<ConnectorPtr> cons = (*p)->connectors(selType); assert(!cons.empty()); for(vector<ConnectorPtr>::const_iterator r = cons.begin(); r != cons.end(); ++r) { assert(*r); connectors.push_back(ConnectorInfo(*r, *p)); } } catch(const Ice::LocalException& ex) { exception.reset(ex.ice_clone()); handleException(ex, hasMore || p != endpoints.end() - 1); } } if(connectors.empty()) { assert(exception.get()); exception->ice_throw(); } // // Try to get a connection to one of the connectors. A null result indicates that no // connection was found and that we should try to establish the connection (and that // the connectors were added to _pending to prevent other threads from establishing // the connection). // connection = getConnection(connectors, 0, compress); if(connection) { return connection; } // // Try to establish the connection to the connectors. // DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides(); const CommunicatorObserverPtr& obsv = _instance->getObserver(); vector<ConnectorInfo>::const_iterator q; for(q = connectors.begin(); q != connectors.end(); ++q) { ObserverPtr observer; if(obsv) { observer = obsv->getConnectionEstablishmentObserver(q->endpoint, q->connector->toString()); if(observer) { observer->attach(); } } try { connection = createConnection(q->connector->connect(), *q); connection->start(0); if(observer) { observer->detach(); } if(defaultsAndOverrides->overrideCompress) { compress = defaultsAndOverrides->overrideCompressValue; } else { compress = q->endpoint->compress(); } connection->activate(); break; } catch(const Ice::CommunicatorDestroyedException& ex) { if(observer) { observer->failed(ex.ice_name()); observer->detach(); } exception.reset(ex.ice_clone()); handleConnectionException(*exception.get(), hasMore || q != connectors.end() - 1); connection = 0; break; // No need to continue } catch(const Ice::LocalException& ex) { if(observer) { observer->failed(ex.ice_name()); observer->detach(); } exception.reset(ex.ice_clone()); handleConnectionException(*exception.get(), hasMore || q != connectors.end() - 1); connection = 0; } } // // Finish creating the connection (this removes the connectors from the _pending // list and notifies any waiting threads). // if(connection) { finishGetConnection(connectors, *q, connection, 0); } else { finishGetConnection(connectors, *exception.get(), 0); } if(!connection) { assert(exception.get()); exception->ice_throw(); } return connection; }
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()), _encoding(connection->encoding()), _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; } // // Berkeley DB expects file paths to be UTF8 encoded. // open(txn, nativeToUTF8(_dbName, getProcessStringConverter()).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(); indexBase->_encoding = connection->encoding(); IceUtil::UniquePtr<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); } #ifdef NDEBUG _indices.insert(IndexMap::value_type(indexBase->name(), indexI.get())); #else bool inserted = _indices.insert(IndexMap::value_type(indexBase->name(), indexI.get())).second; assert(inserted); #endif 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; } } }