diff options
author | Joe George <joe@zeroc.com> | 2015-03-06 15:54:12 +0000 |
---|---|---|
committer | Joe George <joe@zeroc.com> | 2015-05-12 11:39:06 -0400 |
commit | 155860614280ca13d3ae15171803bf40fce925fb (patch) | |
tree | 983682633327efdc70f3d5b3b4ba99eb6a4fb29b | |
parent | Patch 3 - Fix marshaling bug with nested optionals (diff) | |
download | ice-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.cpp | 10 | ||||
-rw-r--r-- | cpp/src/Ice/Selector.h | 2 | ||||
-rw-r--r-- | cpp/src/Ice/ThreadPool.cpp | 11 | ||||
-rw-r--r-- | cpp/src/Ice/ThreadPool.h | 3 |
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; }; |