From 2c036ca6ca7f39b6987135839a1a899cd080877d Mon Sep 17 00:00:00 2001 From: Benoit Foucher Date: Thu, 18 Jul 2019 18:09:15 +0200 Subject: Fixed non-thread safe AMD dispatch, fixes #448 (#449) The caching of the output stream which was added back to solve #414 made the dispatch of AMD requests non thread-safe if a dispatch interceptor was installed and if the interceptor retried the dispatch. Multiple continuation could run concurrently and eventually re-use the cached output stream to marshal multiple responses. --- cpp/test/Ice/interceptor/MyObjectI.cpp | 36 ++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'cpp/test/Ice/interceptor/MyObjectI.cpp') diff --git a/cpp/test/Ice/interceptor/MyObjectI.cpp b/cpp/test/Ice/interceptor/MyObjectI.cpp index 8604cd7007f..f3164ac4426 100644 --- a/cpp/test/Ice/interceptor/MyObjectI.cpp +++ b/cpp/test/Ice/interceptor/MyObjectI.cpp @@ -83,13 +83,22 @@ MyObjectI::amdAddAsync(int x, int y, function response, function, - const Ice::Current&) + const Ice::Current& current) { + Ice::Context::const_iterator p = current.ctx.find("retry"); + bool retry = p != current.ctx.end(); std::thread t( - [x, y, response]() + [x, y, response, retry]() { this_thread::sleep_for(chrono::milliseconds(10)); - response(x + y); + try + { + response(x + y); + } + catch(const Ice::ResponseSentException&) + { + test(retry); + } }); t.detach(); } @@ -200,31 +209,42 @@ MyObjectI::amdBadSystemAddAsync(int, } #else void -MyObjectI::amdAdd_async(const Test::AMD_MyObject_amdAddPtr& cb, int x, int y, const Ice::Current&) +MyObjectI::amdAdd_async(const Test::AMD_MyObject_amdAddPtr& cb, int x, int y, const Ice::Current& current) { class ThreadI : public Thread { public: - ThreadI(const Test::AMD_MyObject_amdAddPtr& cb, int x, int y) : + ThreadI(const Test::AMD_MyObject_amdAddPtr& cb, int x, int y, bool retry) : _cb(cb), _x(x), - _y(y) + _y(y), + _retry(retry) { } void run() { ThreadControl::sleep(Time::milliSeconds(10)); - _cb->ice_response(_x + _y); + try + { + _cb->ice_response(_x + _y); + } + catch(const Ice::ResponseSentException&) + { + test(_retry); + } } private: Test::AMD_MyObject_amdAddPtr _cb; int _x; int _y; + bool _retry; }; - ThreadPtr thread = new ThreadI(cb, x, y); + Ice::Context::const_iterator p = current.ctx.find("retry"); + bool retry = p != current.ctx.end(); + ThreadPtr thread = new ThreadI(cb, x, y, retry); thread->start().detach(); } -- cgit v1.2.3