diff options
Diffstat (limited to 'cpp/test')
-rw-r--r-- | cpp/test/Freeze/evictor/Client.cpp | 41 | ||||
-rw-r--r-- | cpp/test/Freeze/evictor/Test.ice | 8 | ||||
-rw-r--r-- | cpp/test/Freeze/evictor/TestI.cpp | 119 | ||||
-rw-r--r-- | cpp/test/Freeze/evictor/TestI.h | 4 |
4 files changed, 166 insertions, 6 deletions
diff --git a/cpp/test/Freeze/evictor/Client.cpp b/cpp/test/Freeze/evictor/Client.cpp index 0d090a33e80..a11d4cc23a3 100644 --- a/cpp/test/Freeze/evictor/Client.cpp +++ b/cpp/test/Freeze/evictor/Client.cpp @@ -371,6 +371,8 @@ public: void run() { + int transferOp = 0; + for(int i = 0; i < 1000; i++) { // @@ -385,9 +387,36 @@ public: } while(from == to); + try { - from->transfer(100, to); + // + // Alternate between transfer methods + // + switch(transferOp) + { + case 0: + { + from->transfer(100, to); + break; + } + case 1: + { + from->transfer2(100, to); + break; + } + case 2: + { + from->transfer3(100, to); + break; + } + default: + { + test(false); + } + }; + transferOp++; + transferOp = transferOp % 3; } catch(const Test::InsufficientFundsException&) { @@ -403,12 +432,12 @@ public: // test(false); } - + /* - if(i % 100 == 0) - { - cerr << "." << flush; - } + if(i % 100 == 0) + { + cerr << "." << flush; + } */ } } diff --git a/cpp/test/Freeze/evictor/Test.ice b/cpp/test/Freeze/evictor/Test.ice index adfc5827bf7..4770603c8da 100644 --- a/cpp/test/Freeze/evictor/Test.ice +++ b/cpp/test/Freeze/evictor/Test.ice @@ -38,6 +38,14 @@ class Account ["freeze:write"] void transfer(int amount, Account* toAccount) throws InsufficientFundsException; // + // Other implementations of transfer that we want to test as well + // + ["freeze:write", "amd"] void transfer2(int amount, Account* toAccount) throws InsufficientFundsException; + ["freeze:write", "amd"] void transfer3(int amount, Account* toAccount) throws InsufficientFundsException; + + + + // // "Internal" operation // ["freeze:write:mandatory"] void deposit(int amount) throws InsufficientFundsException; 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) diff --git a/cpp/test/Freeze/evictor/TestI.h b/cpp/test/Freeze/evictor/TestI.h index 9f39463a190..adcf6664ad0 100644 --- a/cpp/test/Freeze/evictor/TestI.h +++ b/cpp/test/Freeze/evictor/TestI.h @@ -33,6 +33,10 @@ public: virtual void transfer(int, const Test::AccountPrx&, const Ice::Current&); + virtual void transfer2_async(const AMD_Account_transfer2Ptr&, int, const Test::AccountPrx&, const Ice::Current&); + + virtual void transfer3_async(const AMD_Account_transfer3Ptr&, int, const Test::AccountPrx&, const Ice::Current&); + AccountI(int, const Freeze::TransactionalEvictorPtr&); AccountI(); |