From 4fdeea0210170c9916fdb1a60aed19ef6a005a02 Mon Sep 17 00:00:00 2001 From: Benoit Foucher Date: Fri, 24 Apr 2015 11:44:22 +0200 Subject: Fixed ICE-6465: Windows IceGrid node support for more 64 processes --- cpp/src/IceGrid/Activator.cpp | 71 ++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 34 deletions(-) (limited to 'cpp/src/IceGrid/Activator.cpp') diff --git a/cpp/src/IceGrid/Activator.cpp b/cpp/src/IceGrid/Activator.cpp index a7969d6fad9..6b06cbc3d5d 100644 --- a/cpp/src/IceGrid/Activator.cpp +++ b/cpp/src/IceGrid/Activator.cpp @@ -289,6 +289,14 @@ operator()(const wstring& lhs, const wstring& rhs) const } +#ifdef _WIN32 +extern "C" void CALLBACK activatorWaitCallback(PVOID data, BOOLEAN) +{ + Activator::Process* process = reinterpret_cast(data); + process->activator->processTerminated(process); +} +#endif + Activator::Activator(const TraceLevelsPtr& traceLevels) : _traceLevels(traceLevels), _deactivating(false) @@ -599,16 +607,21 @@ Activator::activate(const string& name, // keep the thread handle, so we close it now. The process handle will be closed later. // CloseHandle(pi.hThread); - + process.activator = this; process.pid = pi.dwProcessId; process.hnd = pi.hProcess; process.server = server; - _processes.insert(make_pair(name, process)); + map::iterator it = _processes.insert(make_pair(name, process)).first; - setInterrupt(); + Process* pp = &it->second; + if(!RegisterWaitForSingleObject(&pp->waithnd, pp->hnd, activatorWaitCallback, pp, INFINITE, + WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) + { + throw IceUtilInternal::lastErrorToString(); + } // - // Don't print the following trace, this might interfere with the + // Don't print the following trace, this might interfer with the // output of the started process if it fails with an error message. // // if(_traceLevels->activator > 0) @@ -1146,51 +1159,30 @@ Activator::terminationListener() #ifdef _WIN32 while(true) { - vector handles; - - // - // Lock while we collect the process handles. - // - { - IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this); - - for(map::iterator p = _processes.begin(); p != _processes.end(); ++p) - { - handles.push_back(p->second.hnd); - } - } - - handles.push_back(_hIntr); - // - // Wait for a child to terminate, or the interrupt event to be signaled. + // Wait for the interrupt event to be signaled. // - DWORD ret = WaitForMultipleObjects(static_cast(handles.size()), &handles[0], FALSE, INFINITE); + DWORD ret = WaitForSingleObject(_hIntr, INFINITE); if(ret == WAIT_FAILED) { SyscallException ex(__FILE__, __LINE__); ex.error = getSystemErrno(); throw ex; } + clearInterrupt(); - vector::size_type pos = ret - WAIT_OBJECT_0; - assert(pos < handles.size()); - HANDLE hnd = handles[pos]; - + // + // Collect terminated processes + // vector terminated; bool deactivated = false; { IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this); - - if(hnd == _hIntr) - { - clearInterrupt(); - } - else + for(vector::const_iterator q = _terminated.begin(); q != _terminated.end(); ++q) { for(map::iterator p = _processes.begin(); p != _processes.end(); ++p) { - if(p->second.hnd == hnd) + if(&p->second == *q) { terminated.push_back(p->second); _processes.erase(p); @@ -1198,14 +1190,17 @@ Activator::terminationListener() } } } - + _terminated.clear(); deactivated = _deactivating && _processes.empty(); } for(vector::const_iterator p = terminated.begin(); p != terminated.end(); ++p) { + UnregisterWait(p->waithnd); + DWORD status; GetExitCodeProcess(p->hnd, &status); + CloseHandle(p->hnd); assert(status != STILL_ACTIVE); @@ -1477,4 +1472,12 @@ Activator::waitPid(pid_t processPid) return -1; } } +#else +void +Activator::processTerminated(Activator::Process* process) +{ + IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this); + setInterrupt(); + _terminated.push_back(process); +} #endif -- cgit v1.2.3