summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe George <joe@zeroc.com>2015-03-06 15:54:12 +0000
committerJoe George <joe@zeroc.com>2015-05-12 11:39:06 -0400
commit155860614280ca13d3ae15171803bf40fce925fb (patch)
tree983682633327efdc70f3d5b3b4ba99eb6a4fb29b
parentPatch 3 - Fix marshaling bug with nested optionals (diff)
downloadice-155860614280ca13d3ae15171803bf40fce925fb.tar.bz2
ice-155860614280ca13d3ae15171803bf40fce925fb.tar.xz
ice-155860614280ca13d3ae15171803bf40fce925fb.zip
Patch 4 - Fixes race condition on Windows with C++
-rw-r--r--cpp/src/Ice/Selector.cpp10
-rw-r--r--cpp/src/Ice/Selector.h2
-rw-r--r--cpp/src/Ice/ThreadPool.cpp11
-rw-r--r--cpp/src/Ice/ThreadPool.h3
4 files changed, 17 insertions, 9 deletions
diff --git a/cpp/src/Ice/Selector.cpp b/cpp/src/Ice/Selector.cpp
index c9763d6e2a9..4d5aaf3c790 100644
--- a/cpp/src/Ice/Selector.cpp
+++ b/cpp/src/Ice/Selector.cpp
@@ -178,11 +178,11 @@ Selector::finish(EventHandler* handler)
}
EventHandler*
-Selector::getNextHandler(SocketOperation& status, int timeout)
+Selector::getNextHandler(SocketOperation& status, DWORD& count, int& error, int timeout)
{
ULONG_PTR key;
LPOVERLAPPED ol;
- DWORD count;
+ error = 0;
if(!GetQueuedCompletionStatus(_handle, &count, &key, &ol, timeout > 0 ? timeout * 1000 : INFINITE))
{
@@ -205,16 +205,14 @@ Selector::getNextHandler(SocketOperation& status, int timeout)
}
AsyncInfo* info = static_cast<AsyncInfo*>(ol);
status = info->status;
- info->count = SOCKET_ERROR;
- info->error = WSAGetLastError();
+ count = SOCKET_ERROR;
+ error = WSAGetLastError();
return reinterpret_cast<EventHandler*>(key);
}
assert(ol);
AsyncInfo* info = static_cast<AsyncInfo*>(ol);
status = info->status;
- info->count = count;
- info->error = 0;
return reinterpret_cast<EventHandler*>(key);
}
diff --git a/cpp/src/Ice/Selector.h b/cpp/src/Ice/Selector.h
index e53357a0065..48ccfd15ef8 100644
--- a/cpp/src/Ice/Selector.h
+++ b/cpp/src/Ice/Selector.h
@@ -92,7 +92,7 @@ public:
void update(EventHandler*, SocketOperation, SocketOperation);
void finish(EventHandler*);
- EventHandler* getNextHandler(SocketOperation&, int);
+ EventHandler* getNextHandler(SocketOperation&, DWORD&, int&, int);
HANDLE getIOCPHandle() { return _handle; }
diff --git a/cpp/src/Ice/ThreadPool.cpp b/cpp/src/Ice/ThreadPool.cpp
index 2234e8c7ceb..1c297dacdc1 100644
--- a/cpp/src/Ice/ThreadPool.cpp
+++ b/cpp/src/Ice/ThreadPool.cpp
@@ -774,7 +774,8 @@ IceInternal::ThreadPool::run(const EventHandlerThreadPtr& thread)
try
{
current._ioCompleted = false;
- current._handler = _selector.getNextHandler(current.operation, _threadIdleTime);
+ current._handler = _selector.getNextHandler(current.operation, current._count, current._error,
+ _threadIdleTime);
}
catch(const SelectorTimeoutException&)
{
@@ -819,7 +820,8 @@ IceInternal::ThreadPool::run(const EventHandlerThreadPtr& thread)
try
{
- current._handler = _selector.getNextHandler(current.operation, _serverIdleTime);
+ current._handler = _selector.getNextHandler(current.operation, current._count, current._error,
+ _serverIdleTime);
}
catch(const SelectorTimeoutException&)
{
@@ -967,6 +969,11 @@ IceInternal::ThreadPool::startMessage(ThreadPoolCurrent& current)
assert(!(current._handler->_ready & current.operation));
current._handler->_ready = static_cast<SocketOperation>(current._handler->_ready | current.operation);
current._handler->_started = static_cast<SocketOperation>(current._handler->_started & ~current.operation);
+
+ AsyncInfo* info = current._handler->getNativeInfo()->getAsyncInfo(current.operation);
+ info->count = current._count;
+ info->error = current._error;
+
if(!current._handler->finishAsync(current.operation)) // Returns false if the handler is finished.
{
current._handler->_pending = static_cast<SocketOperation>(current._handler->_pending & ~current.operation);
diff --git a/cpp/src/Ice/ThreadPool.h b/cpp/src/Ice/ThreadPool.h
index 43a8f2fb361..a782b3ebf92 100644
--- a/cpp/src/Ice/ThreadPool.h
+++ b/cpp/src/Ice/ThreadPool.h
@@ -165,6 +165,9 @@ private:
bool _ioCompleted;
#if !defined(ICE_USE_IOCP) && !defined(ICE_OS_WINRT)
bool _leader;
+#else
+ DWORD _count;
+ int _error;
#endif
friend class ThreadPool;
};