diff options
author | Bernard Normier <bernard@zeroc.com> | 2007-07-06 15:14:06 -0400 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2007-07-06 15:14:06 -0400 |
commit | 3a5a3740e06b15d27badc3a000e174f01403bc60 (patch) | |
tree | 8ea1e9abebfd82e996b6b90cfcf635ff74c00bb9 /cpp/test/Freeze/evictor/TestI.cpp | |
parent | AMD testing + AMD "rollback on user exception" fix (diff) | |
download | ice-3a5a3740e06b15d27badc3a000e174f01403bc60.tar.bz2 ice-3a5a3740e06b15d27badc3a000e174f01403bc60.tar.xz ice-3a5a3740e06b15d27badc3a000e174f01403bc60.zip |
AMD testing + minimal rollback on user exception support in AMD
Diffstat (limited to 'cpp/test/Freeze/evictor/TestI.cpp')
-rw-r--r-- | cpp/test/Freeze/evictor/TestI.cpp | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/cpp/test/Freeze/evictor/TestI.cpp b/cpp/test/Freeze/evictor/TestI.cpp index ba64434c0aa..df6c87176ac 100644 --- a/cpp/test/Freeze/evictor/TestI.cpp +++ b/cpp/test/Freeze/evictor/TestI.cpp @@ -45,6 +45,125 @@ Test::AccountI::transfer(int amount, const Test::AccountPrx& toAccount, const Cu deposit(-amount, current); // direct call } +void +Test::AccountI::transfer2_async(const AMD_Account_transfer2Ptr& cb, int amount, const Test::AccountPrx& toAccount, const Current& current) +{ + // + // Here the dispatch thread does everything + // + test(_evictor->getCurrentTransaction() != 0); + + try + { + toAccount->deposit(amount); // collocated call + deposit(-amount, current); // direct call + } + catch(const InsufficientFundsException& ex) + { + cb->ice_exception(ex); + return; + } + + 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) + { + } + + void response() + { + Lock sync(*this); + _response = true; + notify(); + } + + void exception(const Ice::UserException& e) + { + Lock sync(*this); + _exception.reset(dynamic_cast<Ice::UserException*>(e.ice_clone())); + notify(); + } + + + virtual void run() + { + Lock sync(*this); + + bool timedOut = false; + + while(!timedOut && _response == false && _exception.get() == 0) + { + timedOut = !timedWait(IceUtil::Time::seconds(1)); + } + + if(timedOut) + { + return; + } + + if(_response) + { + _cb->ice_response(); + } + else if(_exception.get() != 0) + { + _cb->ice_exception(*_exception.get()); + } + else + { + _cb->ice_exception(Ice::TimeoutException(__FILE__, __LINE__)); + } + } + +private: + Test::AMD_Account_transfer3Ptr _cb; + bool _response; + 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) +{ + // + // Here the dispatch thread does the actual work, but a separate thread sends the response + // + + ResponseThreadPtr thread = new ResponseThread(cb); + thread->start(33000).detach(); + + test(_evictor->getCurrentTransaction() != 0); + + try + { + toAccount->deposit(amount); // collocated call + deposit(-amount, current); // direct call + } + catch(const Ice::UserException& e) + { + // + // Need to rollback here -- "rollback on user exception" does not work + // when the dispatch commits before it gets any response! + // + _evictor->getCurrentTransaction()->rollback(); + + thread->exception(e); + return; + } + + thread->response(); +} + + Test::AccountI::AccountI(int initialBalance, const Freeze::TransactionalEvictorPtr& evictor) : Account(initialBalance), _evictor(evictor) |