summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernard Normier <bernard@zeroc.com>2008-12-31 14:34:37 -0500
committerBernard Normier <bernard@zeroc.com>2008-12-31 14:34:37 -0500
commita0dfb6ad783f35c1b0cad78b9cdae077b57d6de3 (patch)
tree31fd8eb1d67cce0091b3f1757da55b2114af9363
parentMerge branch 'R3_3_branch' of ssh://git/home/git/ice into R3_3_branch (diff)
downloadice-a0dfb6ad783f35c1b0cad78b9cdae077b57d6de3.tar.bz2
ice-a0dfb6ad783f35c1b0cad78b9cdae077b57d6de3.tar.xz
ice-a0dfb6ad783f35c1b0cad78b9cdae077b57d6de3.zip
Fixed bug #3232 (Freeze transactional evictor leaks)
-rw-r--r--cpp/src/Freeze/TransactionI.cpp5
-rw-r--r--cpp/src/Freeze/TransactionalEvictorI.cpp13
-rw-r--r--cpp/test/Freeze/evictor/TestI.cpp34
-rw-r--r--java/src/Freeze/TransactionI.java9
-rw-r--r--java/src/Freeze/TransactionalEvictorI.java10
-rw-r--r--java/test/Freeze/evictor/AccountI.java9
6 files changed, 67 insertions, 13 deletions
diff --git a/cpp/src/Freeze/TransactionI.cpp b/cpp/src/Freeze/TransactionI.cpp
index ac595af5120..4f1a04253de 100644
--- a/cpp/src/Freeze/TransactionI.cpp
+++ b/cpp/src/Freeze/TransactionI.cpp
@@ -270,7 +270,10 @@ Freeze::TransactionI::postCompletion(bool committed, bool deadlock)
if(_postCompletionCallback != 0)
{
- _postCompletionCallback->postCompletion(committed, deadlock);
+ PostCompletionCallbackPtr cb = _postCompletionCallback;
+ _postCompletionCallback = 0;
+
+ cb->postCompletion(committed, deadlock);
}
ConnectionIPtr connection = _connection;
diff --git a/cpp/src/Freeze/TransactionalEvictorI.cpp b/cpp/src/Freeze/TransactionalEvictorI.cpp
index e2798be89da..ab3d61444f8 100644
--- a/cpp/src/Freeze/TransactionalEvictorI.cpp
+++ b/cpp/src/Freeze/TransactionalEvictorI.cpp
@@ -625,7 +625,7 @@ Freeze::TransactionalEvictorI::dispatch(Request& request)
}
//
- // Can be reached
+ // Can't be reached
//
assert(0);
throw OperationNotExistException(__FILE__, __LINE__);
@@ -637,6 +637,17 @@ Freeze::TransactionalEvictorI::deactivate(const string&)
{
if(_deactivateController.deactivate())
{
+ {
+ Lock sync(*this);
+
+ //
+ // Set the evictor size to zero, meaning that we will evict
+ // everything possible.
+ //
+ _evictorSize = 0;
+ evict();
+ }
+
//
// Break cycle
//
diff --git a/cpp/test/Freeze/evictor/TestI.cpp b/cpp/test/Freeze/evictor/TestI.cpp
index 3b213b3e93c..cd05dbd5f9d 100644
--- a/cpp/test/Freeze/evictor/TestI.cpp
+++ b/cpp/test/Freeze/evictor/TestI.cpp
@@ -67,14 +67,14 @@ Test::AccountI::transfer2_async(const AMD_Account_transfer2Ptr& cb, int amount,
cb->ice_response();
}
-
class ResponseThread : public IceUtil::Thread, private IceUtil::Monitor<IceUtil::Mutex>
{
public:
ResponseThread(const Test::AMD_Account_transfer3Ptr& cb) :
_cb(cb),
- _response(false)
+ _response(false),
+ _cancelled(false)
{
}
@@ -92,6 +92,13 @@ public:
notify();
}
+ void cancel()
+ {
+ Lock sync(*this);
+ _cancelled = true;
+ notify();
+ }
+
virtual void run()
{
@@ -99,12 +106,12 @@ public:
bool timedOut = false;
- while(!timedOut && _response == false && _exception.get() == 0)
+ while(!timedOut && _response == false && _cancelled == false && _exception.get() == 0)
{
timedOut = !timedWait(IceUtil::Time::seconds(1));
}
- if(timedOut)
+ if(_cancelled)
{
return;
}
@@ -126,11 +133,15 @@ public:
private:
Test::AMD_Account_transfer3Ptr _cb;
bool _response;
+ bool _cancelled;
std::auto_ptr<Ice::UserException> _exception;
};
typedef IceUtil::Handle<ResponseThread> ResponseThreadPtr;
+
+
+
void
Test::AccountI::transfer3_async(const AMD_Account_transfer3Ptr& cb, int amount, const Test::AccountPrx& toAccount, const Current& current)
{
@@ -139,8 +150,8 @@ Test::AccountI::transfer3_async(const AMD_Account_transfer3Ptr& cb, int amount,
//
ResponseThreadPtr thread = new ResponseThread(cb);
- thread->start(33000).detach();
-
+ IceUtil::ThreadControl tc = thread->start(33000);
+
test(_evictor->getCurrentTransaction() != 0);
try
@@ -150,6 +161,8 @@ Test::AccountI::transfer3_async(const AMD_Account_transfer3Ptr& cb, int amount,
}
catch(const Ice::UserException& e)
{
+ tc.detach();
+
//
// Need to rollback here -- "rollback on user exception" does not work
// when the dispatch commits before it gets any response!
@@ -157,9 +170,17 @@ Test::AccountI::transfer3_async(const AMD_Account_transfer3Ptr& cb, int amount,
_evictor->getCurrentTransaction()->rollback();
thread->exception(e);
+
return;
}
+ catch(...)
+ {
+ thread->cancel();
+ tc.join();
+ throw;
+ }
+ tc.detach();
thread->response();
}
@@ -593,7 +614,6 @@ Test::RemoteEvictorI::destroyAllServants(const string& facetName, const Current&
}
}
-
Test::RemoteEvictorFactoryI::RemoteEvictorFactoryI(const ObjectAdapterPtr& adapter,
const std::string& envName) :
_adapter(adapter),
diff --git a/java/src/Freeze/TransactionI.java b/java/src/Freeze/TransactionI.java
index b1d0a807048..e05eab4c663 100644
--- a/java/src/Freeze/TransactionI.java
+++ b/java/src/Freeze/TransactionI.java
@@ -222,7 +222,14 @@ class TransactionI implements Transaction
{
if(_postCompletionCallback != null)
{
- _postCompletionCallback.postCompletion(committed, deadlock);
+ try
+ {
+ _postCompletionCallback.postCompletion(committed, deadlock);
+ }
+ finally
+ {
+ _postCompletionCallback = null;
+ }
}
}
diff --git a/java/src/Freeze/TransactionalEvictorI.java b/java/src/Freeze/TransactionalEvictorI.java
index 6d44f055ea3..26623346c53 100644
--- a/java/src/Freeze/TransactionalEvictorI.java
+++ b/java/src/Freeze/TransactionalEvictorI.java
@@ -252,6 +252,16 @@ class TransactionalEvictorI extends EvictorI implements TransactionalEvictor
{
if(_deactivateController.deactivate())
{
+ synchronized(this)
+ {
+ //
+ // Set the evictor size to zero, meaning that we will evict
+ // everything possible.
+ //
+ _evictorSize = 0;
+ evict();
+ }
+
try
{
closeDbEnv();
diff --git a/java/test/Freeze/evictor/AccountI.java b/java/test/Freeze/evictor/AccountI.java
index 8df7057eeaa..949d77c3b42 100644
--- a/java/test/Freeze/evictor/AccountI.java
+++ b/java/test/Freeze/evictor/AccountI.java
@@ -81,7 +81,6 @@ public class AccountI extends Test.Account
notify();
}
-
public synchronized void run()
{
if(_response == false && _exception == null)
@@ -129,8 +128,7 @@ public class AccountI extends Test.Account
ResponseThread thread = new ResponseThread();
thread.setDaemon(true);
- thread.start();
-
+
test(_evictor.getCurrentTransaction() != null);
try
@@ -140,6 +138,9 @@ public class AccountI extends Test.Account
}
catch(Ice.UserException e)
{
+ thread.start();
+ Thread.yield();
+
//
// Need to rollback here -- "rollback on user exception" does not work
// when the dispatch commits before it gets any response!
@@ -150,6 +151,8 @@ public class AccountI extends Test.Account
return;
}
+ thread.start();
+ Thread.yield();
thread.response();
}