diff options
author | Benoit Foucher <benoit@zeroc.com> | 2015-04-24 11:44:22 +0200 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2015-04-24 11:44:22 +0200 |
commit | 4fdeea0210170c9916fdb1a60aed19ef6a005a02 (patch) | |
tree | 766629efc936998d341a5c05464e3e0ccd8709b9 /cpp/src | |
parent | ICE-6466 - Replace --icejs metadata js:ice-build (diff) | |
download | ice-4fdeea0210170c9916fdb1a60aed19ef6a005a02.tar.bz2 ice-4fdeea0210170c9916fdb1a60aed19ef6a005a02.tar.xz ice-4fdeea0210170c9916fdb1a60aed19ef6a005a02.zip |
Fixed ICE-6465: Windows IceGrid node support for more 64 processes
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/IceGrid/Activator.cpp | 71 | ||||
-rw-r--r-- | cpp/src/IceGrid/Activator.h | 33 |
2 files changed, 57 insertions, 47 deletions
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<Activator::Process*>(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<string, Process>::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<HANDLE> handles; - - // - // Lock while we collect the process handles. - // - { - IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this); - - for(map<string, Process>::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<DWORD>(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<HANDLE>::size_type pos = ret - WAIT_OBJECT_0; - assert(pos < handles.size()); - HANDLE hnd = handles[pos]; - + // + // Collect terminated processes + // vector<Process> terminated; bool deactivated = false; { IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this); - - if(hnd == _hIntr) - { - clearInterrupt(); - } - else + for(vector<Process*>::const_iterator q = _terminated.begin(); q != _terminated.end(); ++q) { for(map<string, Process>::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<Process>::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 diff --git a/cpp/src/IceGrid/Activator.h b/cpp/src/IceGrid/Activator.h index 8e45f6c1209..5251e8ab91d 100644 --- a/cpp/src/IceGrid/Activator.h +++ b/cpp/src/IceGrid/Activator.h @@ -32,6 +32,21 @@ class Activator : public IceUtil::Monitor< IceUtil::Mutex>, public IceUtil::Shar { public: + struct Process + { +#ifdef _WIN32 + Activator* activator; + DWORD pid; + HANDLE hnd; + HANDLE waithnd; +#else + pid_t pid; + int pipeFd; + std::string msg; +#endif + ServerIPtr server; + }; + Activator(const TraceLevelsPtr&); virtual ~Activator(); @@ -56,6 +71,10 @@ public: void sendSignal(const std::string&, int); void runTerminationListener(); +#ifdef _WIN32 + void processTerminated(Process*); +#endif + private: void terminationListener(); @@ -66,25 +85,13 @@ private: int waitPid(pid_t); #endif - struct Process - { -#ifdef _WIN32 - DWORD pid; - HANDLE hnd; -#else - pid_t pid; - int pipeFd; - std::string msg; -#endif - ServerIPtr server; - }; - TraceLevelsPtr _traceLevels; std::map<std::string, Process> _processes; bool _deactivating; #ifdef _WIN32 HANDLE _hIntr; + std::vector<Process*> _terminated; #else int _fdIntrRead; int _fdIntrWrite; |