summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Freeze/ConnectionI.cpp2
-rw-r--r--cpp/src/Freeze/EvictorIteratorI.cpp8
-rw-r--r--cpp/src/Freeze/EvictorIteratorI.h2
-rw-r--r--cpp/src/Freeze/IndexI.cpp4
-rw-r--r--cpp/src/Freeze/MapI.cpp8
-rw-r--r--cpp/src/Freeze/ObjectStore.cpp10
-rw-r--r--cpp/src/Freeze/SharedDb.cpp8
-rw-r--r--cpp/src/Freeze/TransactionI.cpp4
-rw-r--r--cpp/src/Freeze/TransactionalEvictorContext.cpp57
-rw-r--r--cpp/src/Freeze/TransactionalEvictorContext.h2
-rw-r--r--cpp/src/Freeze/TransactionalEvictorI.cpp35
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);
}