diff options
author | Bernard Normier <bernard@zeroc.com> | 2007-11-19 16:13:05 -0500 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2007-11-19 16:13:05 -0500 |
commit | a9b2a73a6c8897e84e5e64ee8b41fe17b06d3f54 (patch) | |
tree | eb1216068d7e9be1c1039f13953b2101f00aa60f /cpp/src | |
parent | Added IceSL makedist.py (diff) | |
download | ice-a9b2a73a6c8897e84e5e64ee8b41fe17b06d3f54.tar.bz2 ice-a9b2a73a6c8897e84e5e64ee8b41fe17b06d3f54.tar.xz ice-a9b2a73a6c8897e84e5e64ee8b41fe17b06d3f54.zip |
Fixed bug #2543
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Freeze/ConnectionI.cpp | 2 | ||||
-rw-r--r-- | cpp/src/Freeze/EvictorIteratorI.cpp | 8 | ||||
-rw-r--r-- | cpp/src/Freeze/EvictorIteratorI.h | 2 | ||||
-rw-r--r-- | cpp/src/Freeze/IndexI.cpp | 4 | ||||
-rw-r--r-- | cpp/src/Freeze/MapI.cpp | 8 | ||||
-rw-r--r-- | cpp/src/Freeze/ObjectStore.cpp | 10 | ||||
-rw-r--r-- | cpp/src/Freeze/SharedDb.cpp | 8 | ||||
-rw-r--r-- | cpp/src/Freeze/TransactionI.cpp | 4 | ||||
-rw-r--r-- | cpp/src/Freeze/TransactionalEvictorContext.cpp | 57 | ||||
-rw-r--r-- | cpp/src/Freeze/TransactionalEvictorContext.h | 2 | ||||
-rw-r--r-- | cpp/src/Freeze/TransactionalEvictorI.cpp | 35 |
11 files changed, 112 insertions, 28 deletions
diff --git a/cpp/src/Freeze/ConnectionI.cpp b/cpp/src/Freeze/ConnectionI.cpp index 824fc167c9c..10af58cdbbe 100644 --- a/cpp/src/Freeze/ConnectionI.cpp +++ b/cpp/src/Freeze/ConnectionI.cpp @@ -56,7 +56,7 @@ Freeze::ConnectionI::removeMapIndex(const string& mapName, const string& indexNa } catch(const DbDeadlockException& dx) { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), _transaction); } catch(const DbException& dx) { diff --git a/cpp/src/Freeze/EvictorIteratorI.cpp b/cpp/src/Freeze/EvictorIteratorI.cpp index 401b17750fd..0ff5f418569 100644 --- a/cpp/src/Freeze/EvictorIteratorI.cpp +++ b/cpp/src/Freeze/EvictorIteratorI.cpp @@ -23,7 +23,7 @@ Freeze::EvictorIteratorI::EvictorIteratorI(ObjectStoreBase* store, const Transac _key(1024), _more(store != 0), _initialized(false), - _tx(tx == 0 ? 0 : tx->dbTxn()) + _tx(tx) { _batchIterator = _batch.end(); } @@ -74,6 +74,8 @@ Freeze::EvictorIteratorI::nextBatch() CommunicatorPtr communicator = _store->communicator(); + DbTxn* txn = _tx == 0 ? 0: _tx->dbTxn(); + try { for(;;) @@ -108,7 +110,7 @@ Freeze::EvictorIteratorI::nextBatch() dbKey.set_size(static_cast<u_int32_t>(firstKey.size())); } - _store->db()->cursor(_tx, &dbc, 0); + _store->db()->cursor(txn, &dbc, 0); bool done = false; do @@ -217,7 +219,7 @@ Freeze::EvictorIteratorI::nextBatch() } catch(const DbDeadlockException& dx) { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), _tx); } catch(const DbException& dx) { diff --git a/cpp/src/Freeze/EvictorIteratorI.h b/cpp/src/Freeze/EvictorIteratorI.h index 41fed5db623..4e3e540d49c 100644 --- a/cpp/src/Freeze/EvictorIteratorI.h +++ b/cpp/src/Freeze/EvictorIteratorI.h @@ -45,7 +45,7 @@ private: std::vector<Ice::Identity> _batch; bool _more; bool _initialized; - DbTxn* _tx; + TransactionIPtr _tx; }; } diff --git a/cpp/src/Freeze/IndexI.cpp b/cpp/src/Freeze/IndexI.cpp index 29b89cffcdb..f8ca1b32c7d 100644 --- a/cpp/src/Freeze/IndexI.cpp +++ b/cpp/src/Freeze/IndexI.cpp @@ -174,7 +174,7 @@ Freeze::IndexI::untypedFindFirst(const Key& bytes, Int firstN) const } catch(const DbDeadlockException& dx) { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } catch(const DbException& dx) { @@ -294,7 +294,7 @@ Freeze::IndexI::untypedCount(const Key& bytes) const } catch(const DbDeadlockException& dx) { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } catch(const DbException& dx) { diff --git a/cpp/src/Freeze/MapI.cpp b/cpp/src/Freeze/MapI.cpp index 25b0e088c94..669db800600 100644 --- a/cpp/src/Freeze/MapI.cpp +++ b/cpp/src/Freeze/MapI.cpp @@ -260,7 +260,7 @@ Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection, } else { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), tx); } } catch(const DbException& dx) @@ -1476,7 +1476,7 @@ Freeze::MapHelperI::destroy() } else { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), tx); } } catch(const DbException& dx) @@ -1798,7 +1798,7 @@ Freeze::MapIndexI::untypedCount(const Key& k, const ConnectionIPtr& connection) int result = 0; - DbTxn * txn = connection->dbTxn(); + DbTxn* txn = connection->dbTxn(); try { @@ -1892,7 +1892,7 @@ Freeze::MapIndexI::untypedCount(const Key& k, const ConnectionIPtr& connection) } catch(const DbDeadlockException& dx) { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), connection->currentTransaction()); } catch(const DbException& dx) { diff --git a/cpp/src/Freeze/ObjectStore.cpp b/cpp/src/Freeze/ObjectStore.cpp index 1d554c6bc2a..53f1c6140ac 100644 --- a/cpp/src/Freeze/ObjectStore.cpp +++ b/cpp/src/Freeze/ObjectStore.cpp @@ -255,7 +255,7 @@ Freeze::ObjectStoreBase::dbHasObject(const Identity& ident, const TransactionIPt if(tx != 0) { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } // Else, try again } @@ -406,7 +406,7 @@ Freeze::ObjectStoreBase::load(const Identity& ident, const TransactionIPtr& tran out << "Deadlock in Freeze::ObjectStoreBase::load while searching \"" << _evictor->filename() + "/" + _dbName << "\""; } - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } catch(const DbException& dx) { @@ -458,7 +458,7 @@ Freeze::ObjectStoreBase::update(const Identity& ident, const ObjectRecord& rec, out << "Deadlock in Freeze::ObjectStoreBase::update while updating \"" << _evictor->filename() + "/" + _dbName << "\""; } - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } catch(const DbException& dx) { @@ -511,7 +511,7 @@ Freeze::ObjectStoreBase::insert(const Identity& ident, const ObjectRecord& rec, } if(tx != 0) { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } // // Otherwise, try again @@ -559,7 +559,7 @@ Freeze::ObjectStoreBase::remove(const Identity& ident, const TransactionIPtr& tr } if(tx != 0) { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } // // Otherwise, try again diff --git a/cpp/src/Freeze/SharedDb.cpp b/cpp/src/Freeze/SharedDb.cpp index 57018ec6efc..ab651e267c2 100644 --- a/cpp/src/Freeze/SharedDb.cpp +++ b/cpp/src/Freeze/SharedDb.cpp @@ -198,6 +198,7 @@ Freeze::SharedDb::openCatalogs(SharedDbEnv& dbEnv, SharedDbPtr& catalog, SharedD assert(0); throw DatabaseException(__FILE__, __LINE__, "Catalog already opened"); } + newCatalog->_inMap = true; mapKey.dbName = _catalogIndexListName; @@ -212,6 +213,8 @@ Freeze::SharedDb::openCatalogs(SharedDbEnv& dbEnv, SharedDbPtr& catalog, SharedD assert(0); throw DatabaseException(__FILE__, __LINE__, "CatalogIndexList already opened"); } + newCatalogIndexList->_inMap = true; + catalog = newCatalog.release(); catalogIndexList = newCatalogIndexList.release(); @@ -572,7 +575,7 @@ Freeze::SharedDb::SharedDb(const MapKey& mapKey, } else { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), tx); } } catch(const DbException& dx) @@ -615,7 +618,8 @@ Freeze::SharedDb::SharedDb(const MapKey& mapKey, const string& keyTypeId, const _mapKey(mapKey), _key(keyTypeId), _value(valueTypeId), - _refCount(0) + _refCount(0), + _inMap(false) { _trace = _mapKey.communicator->getProperties()->getPropertyAsInt("Freeze.Trace.Map"); diff --git a/cpp/src/Freeze/TransactionI.cpp b/cpp/src/Freeze/TransactionI.cpp index 725953a4c6c..e8f1bdb2932 100644 --- a/cpp/src/Freeze/TransactionI.cpp +++ b/cpp/src/Freeze/TransactionI.cpp @@ -137,10 +137,12 @@ Freeze::TransactionI::rollbackInternal(bool warning) out << "failed to rollback transaction " << hex << txnId << dec << ": " << dx.what(); } + DeadlockException deadlockException(__FILE__, __LINE__, dx.what(), this); + postCompletion(false, true); // After postCompletion is called the transaction may be // dead. Beware! - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw deadlockException; } catch(const ::DbException& dx) { diff --git a/cpp/src/Freeze/TransactionalEvictorContext.cpp b/cpp/src/Freeze/TransactionalEvictorContext.cpp index 369c6fd1763..2c68a4eae2e 100644 --- a/cpp/src/Freeze/TransactionalEvictorContext.cpp +++ b/cpp/src/Freeze/TransactionalEvictorContext.cpp @@ -19,6 +19,49 @@ using namespace std; using namespace Freeze; using namespace Ice; +// +// TransactionalEvictorDeadlockException +// + +Freeze::TransactionalEvictorDeadlockException::TransactionalEvictorDeadlockException(const char* file, int line, const TransactionPtr& transaction) : + Ice::LocalException(file, line), + tx(transaction) +{ +} + +Freeze::TransactionalEvictorDeadlockException::~TransactionalEvictorDeadlockException() throw() +{ +} + +string +Freeze::TransactionalEvictorDeadlockException::ice_name() const +{ + return "Freeze::TransactionalEvictorDeadlockException"; +} + +Ice::Exception* +Freeze::TransactionalEvictorDeadlockException::ice_clone() const +{ + return new TransactionalEvictorDeadlockException(*this); +} + +void +Freeze::TransactionalEvictorDeadlockException::ice_throw() const +{ + throw *this; +} + +void +Freeze::TransactionalEvictorDeadlockException::ice_print(ostream& out) const +{ + Ice::Exception::ice_print(out); + out << ":\ntransactional evictor deadlock exception"; +} + + +// +// TransactionalEvictorContext +// Freeze::TransactionalEvictorContext::TransactionalEvictorContext(const SharedDbEnvPtr& dbEnv) : _tx((new ConnectionI(dbEnv))->beginTransactionI()), @@ -115,6 +158,11 @@ Freeze::TransactionalEvictorContext::checkDeadlockException() { _deadlockException->ice_throw(); } + + if(_nestedCallDeadlockException.get() != 0) + { + _nestedCallDeadlockException->ice_throw(); + } } bool @@ -157,6 +205,15 @@ Freeze::TransactionalEvictorContext::exception(const std::exception& ex) _deadlockException.reset(dynamic_cast<DeadlockException*>(dx->ice_clone())); return false; } + + const TransactionalEvictorDeadlockException* edx = + dynamic_cast<const TransactionalEvictorDeadlockException*>(&ex); + if(edx != 0 && _owner == IceUtil::ThreadControl()) + { + _nestedCallDeadlockException.reset(dynamic_cast<TransactionalEvictorDeadlockException*>(edx->ice_clone())); + return false; + } + return true; } diff --git a/cpp/src/Freeze/TransactionalEvictorContext.h b/cpp/src/Freeze/TransactionalEvictorContext.h index 12b2a2e8765..9c5e16a8348 100644 --- a/cpp/src/Freeze/TransactionalEvictorContext.h +++ b/cpp/src/Freeze/TransactionalEvictorContext.h @@ -14,6 +14,7 @@ #include <Freeze/TransactionalEvictor.h> #include <Freeze/EvictorStorage.h> #include <Freeze/EvictorI.h> +#include <Freeze/Initialize.h> #include <IceUtil/IceUtil.h> namespace Freeze @@ -147,6 +148,7 @@ private: bool _rollbackOnly; std::auto_ptr<DeadlockException> _deadlockException; + std::auto_ptr<TransactionalEvictorDeadlockException> _nestedCallDeadlockException; // // Protected by this diff --git a/cpp/src/Freeze/TransactionalEvictorI.cpp b/cpp/src/Freeze/TransactionalEvictorI.cpp index 5ce3ed9dab6..8951cde8e0f 100644 --- a/cpp/src/Freeze/TransactionalEvictorI.cpp +++ b/cpp/src/Freeze/TransactionalEvictorI.cpp @@ -394,10 +394,11 @@ Freeze::TransactionalEvictorI::dispatch(Request& request) { servantHolder.init(ctx, current, store); } - catch(const DeadlockException&) + catch(const DeadlockException& dx) { + assert(dx.tx == ctx->transaction()); ctx->deadlockException(); - throw; + throw TransactionalEvictorDeadlockException(__FILE__, __LINE__, dx.tx); } sample = servantHolder.servant(); } @@ -496,6 +497,8 @@ Freeze::TransactionalEvictorI::dispatch(Request& request) do { + TransactionPtr tx; + try { if(ownCtx) @@ -504,7 +507,8 @@ Freeze::TransactionalEvictorI::dispatch(Request& request) } CtxHolder ctxHolder(ownCtx, ctx, _dbEnv); - + tx = ctx->transaction(); + try { TransactionalEvictorContext::ServantHolder sh; @@ -540,7 +544,7 @@ Freeze::TransactionalEvictorI::dispatch(Request& request) if(dispatchStatus == DispatchAsync) { // - // May throw DeadlockException + // May throw DeadlockException or TransactionalEvictorDeadlockException // ctx->checkDeadlockException(); @@ -565,9 +569,12 @@ Freeze::TransactionalEvictorI::dispatch(Request& request) // servant holder destructor runs here and may throw (if !rolled back) // } - catch(const DeadlockException&) + catch(const DeadlockException& dx) { - ctx->deadlockException(); + if(dx.tx == tx) + { + ctx->deadlockException(); + } throw; } catch(...) @@ -583,9 +590,20 @@ Freeze::TransactionalEvictorI::dispatch(Request& request) // commit occurs here (when ownCtx) // } - catch(const DeadlockException&) + catch(const DeadlockException& dx) { - if(ownCtx) + if(ownCtx && dx.tx == tx) + { + tryAgain = true; + } + else + { + throw TransactionalEvictorDeadlockException(__FILE__, __LINE__, dx.tx); + } + } + catch(const TransactionalEvictorDeadlockException& dx) + { + if(ownCtx && dx.tx == tx) { tryAgain = true; } @@ -594,7 +612,6 @@ Freeze::TransactionalEvictorI::dispatch(Request& request) throw; } } - } while(tryAgain); } |