summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/RetryQueue.cpp
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2014-09-25 17:07:18 +0200
committerBenoit Foucher <benoit@zeroc.com>2014-09-25 17:07:18 +0200
commit089aed778ab4002336fbada8c4dc4e8b25f33a8c (patch)
tree6188b69af9d8c58e6dbc2079ca6da9d3e5976d1a /cpp/src/Ice/RetryQueue.cpp
parentNew fix for (ICE-5583) to always use a custom chain engine (diff)
downloadice-089aed778ab4002336fbada8c4dc4e8b25f33a8c.tar.bz2
ice-089aed778ab4002336fbada8c4dc4e8b25f33a8c.tar.xz
ice-089aed778ab4002336fbada8c4dc4e8b25f33a8c.zip
Fixed again ICE-5687 - adapterDeactivation test warnings
Diffstat (limited to 'cpp/src/Ice/RetryQueue.cpp')
-rw-r--r--cpp/src/Ice/RetryQueue.cpp45
1 files changed, 35 insertions, 10 deletions
diff --git a/cpp/src/Ice/RetryQueue.cpp b/cpp/src/Ice/RetryQueue.cpp
index 19fa86c61d5..6d58bc66fda 100644
--- a/cpp/src/Ice/RetryQueue.cpp
+++ b/cpp/src/Ice/RetryQueue.cpp
@@ -26,10 +26,15 @@ IceInternal::RetryTask::RetryTask(const RetryQueuePtr& queue, const OutgoingAsyn
void
IceInternal::RetryTask::runTimerTask()
{
- if(_queue->remove(this))
- {
- _outAsync->__processRetry(false);
- }
+ _outAsync->__processRetry(false);
+
+ //
+ // NOTE: this must be called last, destroy() blocks until all task
+ // are removed to prevent the client thread pool to be destroyed
+ // (we still need the client thread pool at this point to call
+ // exception callbacks with CommunicatorDestroyedException).
+ //
+ _queue->remove(this);
}
void
@@ -72,19 +77,39 @@ void
IceInternal::RetryQueue::destroy()
{
Lock sync(*this);
- for(set<RetryTaskPtr>::const_iterator p = _requests.begin(); p != _requests.end(); ++p)
+ assert(_instance);
+
+ set<RetryTaskPtr>::const_iterator p = _requests.begin();
+ while(p != _requests.end())
{
- _instance->timer()->cancel(*p);
- (*p)->destroy();
+ if(_instance->timer()->cancel(*p))
+ {
+ (*p)->destroy();
+ _requests.erase(p++);
+ }
+ else
+ {
+ ++p;
+ }
}
- _requests.clear();
+
_instance = 0;
+ while(!_requests.empty())
+ {
+ wait();
+ }
}
-bool
+void
IceInternal::RetryQueue::remove(const RetryTaskPtr& task)
{
Lock sync(*this);
- return _requests.erase(task) > 0;
+ assert(_requests.find(task) != _requests.end());
+ _requests.erase(task);
+ if(!_instance && _requests.empty())
+ {
+ notify(); // If we are destroying the queue, destroy is probably waiting on the queue to be empty.
+ }
}
+