diff options
author | Bernard Normier <bernard@zeroc.com> | 2008-12-31 14:34:37 -0500 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2008-12-31 14:34:37 -0500 |
commit | a0dfb6ad783f35c1b0cad78b9cdae077b57d6de3 (patch) | |
tree | 31fd8eb1d67cce0091b3f1757da55b2114af9363 | |
parent | Merge branch 'R3_3_branch' of ssh://git/home/git/ice into R3_3_branch (diff) | |
download | ice-a0dfb6ad783f35c1b0cad78b9cdae077b57d6de3.tar.bz2 ice-a0dfb6ad783f35c1b0cad78b9cdae077b57d6de3.tar.xz ice-a0dfb6ad783f35c1b0cad78b9cdae077b57d6de3.zip |
Fixed bug #3232 (Freeze transactional evictor leaks)
-rw-r--r-- | cpp/src/Freeze/TransactionI.cpp | 5 | ||||
-rw-r--r-- | cpp/src/Freeze/TransactionalEvictorI.cpp | 13 | ||||
-rw-r--r-- | cpp/test/Freeze/evictor/TestI.cpp | 34 | ||||
-rw-r--r-- | java/src/Freeze/TransactionI.java | 9 | ||||
-rw-r--r-- | java/src/Freeze/TransactionalEvictorI.java | 10 | ||||
-rw-r--r-- | java/test/Freeze/evictor/AccountI.java | 9 |
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(); } |