TweetRetweet1VertexValueEntry* putTweetRetweet1VertexValueIfAbsent(TweetRetweet1VertexValueMap* tweetRetweet1VertexValueMap, int& tweetTweetIdRetweet1RetweetTweetId ) { int h = 31; hashCode(h, tweetTweetIdRetweet1RetweetTweetId ); h = h & (tweetRetweet1VertexValueMap->capacity - 1); TweetRetweet1VertexValueEntry* candidate = tweetRetweet1VertexValueMap->tweetRetweet1VertexValueEntryArray[h]; TweetRetweet1VertexValueEntry* lastP = NULL; while(candidate) { if( candidate->tweetTweetIdRetweet1RetweetTweetId == (tweetTweetIdRetweet1RetweetTweetId) ) { return candidate; } else { lastP = candidate; candidate = candidate->next; } } TweetRetweet1VertexValueEntry* p = new TweetRetweet1VertexValueEntry; p->tweetTweetIdRetweet1RetweetTweetId = tweetTweetIdRetweet1RetweetTweetId; if(lastP) lastP->next = p; else tweetRetweet1VertexValueMap->tweetRetweet1VertexValueEntryArray[h] = p; tweetRetweet1VertexValueMap->size++; ensureSize(tweetRetweet1VertexValueMap); return p; }
//%4 - vertex value attributes Follower4TweetVertexValueEntry* putFollower4TweetVertexValueIfAbsent(Follower4TweetVertexValueMap* follower4TweetVertexValueMap, int& follower4IdTweetUserId ) { int h = 31; //%1 - vertex value attribute values hashCode(h, follower4IdTweetUserId ); h = h & (follower4TweetVertexValueMap->capacity - 1); Follower4TweetVertexValueEntry* candidate = follower4TweetVertexValueMap->follower4TweetVertexValueEntryArray[h]; Follower4TweetVertexValueEntry* lastP = candidate; while(candidate) { if( candidate->follower4IdTweetUserId == (follower4IdTweetUserId) ) { return candidate; } else { lastP = candidate; candidate = candidate->next; } } Follower4TweetVertexValueEntry* p = new Follower4TweetVertexValueEntry; p->follower4IdTweetUserId = follower4IdTweetUserId; if(lastP) lastP->next = p; else follower4TweetVertexValueMap->follower4TweetVertexValueEntryArray[h] = p; follower4TweetVertexValueMap->size++; ensureSize(follower4TweetVertexValueMap); return p; }
Retweet3Retweet4VertexValueEntry* putRetweet3Retweet4VertexValueIfAbsent(Retweet3Retweet4VertexValueMap* retweet3Retweet4VertexValueMap, int& r3TweetIdR4RetweetTweetId ) { int h = 31; hashCode(h, r3TweetIdR4RetweetTweetId ); h = h & (retweet3Retweet4VertexValueMap->capacity - 1); Retweet3Retweet4VertexValueEntry* candidate = retweet3Retweet4VertexValueMap->retweet3Retweet4VertexValueEntryArray[h]; Retweet3Retweet4VertexValueEntry* lastP = candidate; while(candidate) { if( candidate->r3TweetIdR4RetweetTweetId == (r3TweetIdR4RetweetTweetId) ) { return candidate; } else { lastP = candidate; candidate = candidate->next; } } Retweet3Retweet4VertexValueEntry* p = new Retweet3Retweet4VertexValueEntry; p->r3TweetIdR4RetweetTweetId = r3TweetIdR4RetweetTweetId; if(lastP) lastP->next = p; else retweet3Retweet4VertexValueMap->retweet3Retweet4VertexValueEntryArray[h] = p; retweet3Retweet4VertexValueMap->size++; ensureSize(retweet3Retweet4VertexValueMap); return p; }
Retweet1JoinTupleEntry* putRetweet1JoinTupleIfAbsent(Retweet1JoinTupleMap* retweet1JoinTupleMap, int& r1TweetIdR2RetweetTweetId, Retweet1Retweet2VertexValueMap* retweet1Retweet2VertexValueMap ) { int h = 31; hashCode(h, r1TweetIdR2RetweetTweetId ); h = h & (retweet1JoinTupleMap->capacity - 1); Retweet1JoinTupleEntry* candidate = retweet1JoinTupleMap->retweet1JoinTupleEntryArray[h]; Retweet1JoinTupleEntry* lastP = candidate; while(candidate) { if( candidate->retweet1Retweet2VertexValue->r1TweetIdR2RetweetTweetId == r1TweetIdR2RetweetTweetId ) { return candidate; } else { lastP = candidate; candidate = candidate->next; } } Retweet1JoinTupleEntry* p = new Retweet1JoinTupleEntry; if(!lastP) retweet1JoinTupleMap->retweet1JoinTupleEntryArray[h] = p; else lastP->next = p; retweet1JoinTupleMap->size++; ensureSize(retweet1JoinTupleMap, r1TweetIdR2RetweetTweetId ); addToVertexValues(r1TweetIdR2RetweetTweetId , p, retweet1Retweet2VertexValueMap); return p; }
UserTweetVertexValueEntry* putUserTweetVertexValueIfAbsent(UserTweetVertexValueMap* userTweetVertexValueMap, int& userIdTweetUserId ) { int h = 31; hashCode(h, userIdTweetUserId ); h = h & (userTweetVertexValueMap->capacity - 1); UserTweetVertexValueEntry* candidate = userTweetVertexValueMap->userTweetVertexValueEntryArray[h]; UserTweetVertexValueEntry* lastP = NULL; while(candidate) { if( candidate->userIdTweetUserId == (userIdTweetUserId) ) { return candidate; } else { lastP = candidate; candidate = candidate->next; } } UserTweetVertexValueEntry* p = new UserTweetVertexValueEntry; p->userIdTweetUserId = userIdTweetUserId; if(lastP) lastP->next = p; else userTweetVertexValueMap->userTweetVertexValueEntryArray[h] = p; userTweetVertexValueMap->size++; ensureSize(userTweetVertexValueMap); return p; }
/* Sum contributions from all threads, save to _force&_torque. * Locks globalMutex, since one thread modifies common data (_force&_torque). * Must be called before get* methods are used. Exception is thrown otherwise, since data are not consistent. */ inline void sync(){ for(int i=0; i<nThreads; i++){ if (_maxId[i] > 0) { synced = false;} } if(synced) return; boost::mutex::scoped_lock lock(globalMutex); if(synced) return; // if synced meanwhile for(int i=0; i<nThreads; i++){ if (_maxId[i] > 0) { ensureSize(_maxId[i],i);} } syncSizesOfContainers(); for(long id=0; id<(long)size; id++){ Vector3r sumF(Vector3r::Zero()), sumT(Vector3r::Zero()); for(int thread=0; thread<nThreads; thread++){ sumF+=_forceData[thread][id]; sumT+=_torqueData[thread][id];} _force[id]=sumF; _torque[id]=sumT; if (permForceUsed) {_force[id]+=_permForce[id]; _torque[id]+=_permTorque[id];} } if(moveRotUsed){ for(long id=0; id<(long)size; id++){ Vector3r sumM(Vector3r::Zero()), sumR(Vector3r::Zero()); for(int thread=0; thread<nThreads; thread++){ sumM+=_moveData[thread][id]; sumR+=_rotData[thread][id];} _move[id]=sumM; _rot[id]=sumR; } } synced=true; syncCount++; }
//%3 - projected attributes TweetProjectedTupleEntry* putTweetProjectedTuple(TweetProjectedTupleMap* tweetProjectedTupleMap, int& tweetId ) { int h = 31; hashCode(h, tweetId ); h = h & (tweetProjectedTupleMap->capacity - 1); TweetProjectedTupleEntry* candidate = tweetProjectedTupleMap->tweetProjectedTupleEntryArray[h]; TweetProjectedTupleEntry* lastP = NULL; while(candidate) { if( //%1 - projected attributes candidate->tweetId == (tweetId) ) { candidate->count++; return candidate; } else { lastP = candidate; candidate = candidate->next; } } TweetProjectedTupleEntry* p = new TweetProjectedTupleEntry; //%1 - projected attributes p->tweetId = tweetId; if(!lastP) tweetProjectedTupleMap->tweetProjectedTupleEntryArray[h] = p; else lastP->next = p; tweetProjectedTupleMap->size++; ensureSize(tweetProjectedTupleMap); return p; }
prettyTable& prettyTable::addTitle(std::string title) { colRowTitles_++; maxColRowTitles_ = std::max(maxColRowTitles_, colRowTitles_); ensureSize(); rowTitles_[rowRowTitles_][colRowTitles_] = title; return *this; }
prettyTable& prettyTable::nextTitleRow() { maxColRowTitles_ = std::max(maxColRowTitles_, colRowTitles_); colRowTitles_ = -1; rowRowTitles_++; ensureSize(); return *this; }
prettyTable& prettyTable::addColumnName(std::string name) { rowColNames_++; maxRowColNames_ = std::max(maxRowColNames_, rowColNames_); ensureSize(); colNames_[rowColNames_][colColNames_] = name; return *this; }
const Vector3r getTorqueSingle(Body::id_t id){ ensureSize(id); if (permForceUsed) { return _torque[id] + _permTorque[id]; } else { return _torque[id]; } }
prettyTable& prettyTable::nextColumnNameColumn() { //maxRowColNames_ = std::max(maxRowColNames_, rowColNames_); rowColNames_ = -1; colColNames_++; ensureSize(); return *this; }
void IOBuffer::storeDoubleLE(double data) { ensureSize(8); rx_uint64 val = 0; memcpy(&val, &data, 8); val = ToLE64(data); memcpy(buffer+published, &val, 8); published += 8; }
bool IOBuffer::storeBytes(const char* someData, const rx_uint32 numBytes) { if(!ensureSize(numBytes)) { return false; } memcpy(buffer+published, someData, numBytes); published += numBytes; return true; }
Tablespace::Tablespace(ConfigParser& cfg, IndexType defaultTablespaceSize) : databases(defaultTablespaceSize), cfg(cfg) { ensureSize(defaultTablespaceSize); //Use malloc here to allow usage of realloc //Initialize all pointers to zero for (size_t i = 0; i < databases.size(); i++) { databases[i] = nullptr; } }
void pushBump(element_type const & entry) { if ( expect_false(full()) ) { ensureSize(std::max(2*f,static_cast<size_t>(1))); assert ( ! full() ); } push(entry); }
void sync() { if (_maxId>0) {ensureSize(_maxId); _maxId=0;} if (permForceUsed) { for(long id=0; id<(long)size; id++) { _force[id]+=_permForce[id]; _torque[id]+=_permTorque[id]; } } return; }
static void append(buffer_t* buf, char* str) { int needed; int len; len = strlen(str); needed = buf->pos + len + 1; ensureSize(buf, needed); strcpy(buf->block + buf->pos, str); buf->pos += len; }
si64 CBufferedStream::read(ui8 * data, si64 size) { ensureSize(position + size); auto start = buffer.data() + position; si64 toRead = std::min<si64>(size, buffer.size() - position); std::copy(start, start + toRead, data); position += toRead; return size; }
void write (const MinMaxValue* const values, const int startIndex, const int numValues) { resetPeak(); if (startIndex + numValues > data.size()) ensureSize (startIndex + numValues); MinMaxValue* const dest = getData (startIndex); for (int i = 0; i < numValues; ++i) dest[i] = values[i]; }
int IOBuffer::storeBuffer(IOBuffer& other, rx_uint32 numBytes) { // check if we can read this many bytes from other buffer. numBytes = other.getMostNumberOfBytesWeCanConsume(numBytes); if(numBytes == 0) { return 0; } ensureSize(numBytes); memcpy(buffer+published, other.buffer+other.consumed, numBytes); published += numBytes; other.published += numBytes; return numBytes; }
void QWaylandShmBackingStore::beginPaint(const QRegion &) { mPainting = true; ensureSize(); if (waylandWindow()->attached() && mBackBuffer == waylandWindow()->attached() && mFrameCallback) { QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->handle()); Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm); waylandWindow->waitForFrameSync(); } }
void IOBuffer::setup(rx_uint32 expectedSize) { if( (buffer != NULL) || (size != 0) || (published != 0) || (consumed != 0) ) { printf("iobuffer error: buffer has been setup already\n"); return; } ensureSize(expectedSize); //memset(buffer, 0, expectedSize); }
void Being::setSprite(unsigned int slot, int id, const std::string &color, bool isWeapon) { if (slot >= size()) ensureSize(slot + 1); if (slot >= mSpriteIDs.size()) mSpriteIDs.resize(slot + 1); if (slot >= mSpriteColors.size()) mSpriteColors.resize(slot + 1); // id = 0 means unequip if (id == 0) { removeSprite(slot); if (isWeapon) mEquippedWeapon = 0; } else { std::string filename = itemDb->get(id).getSprite(mGender); AnimatedSprite *equipmentSprite = 0; if (!filename.empty()) { if (!color.empty()) filename += "|" + color; equipmentSprite = AnimatedSprite::load( paths.getStringValue("sprites") + filename); } if (equipmentSprite) equipmentSprite->setDirection(getSpriteDirection()); CompoundSprite::setSprite(slot, equipmentSprite); if (isWeapon) mEquippedWeapon = &itemDb->get(id); setAction(mAction); } mSpriteIDs[slot] = id; mSpriteColors[slot] = color; }
void BitVector::mergeSlow(const BitVector& other) { if (other.isInline()) { ASSERT(!isInline()); *bits() |= cleanseInlineBits(other.m_bitsOrPointer); return; } ensureSize(other.size()); ASSERT(!isInline()); ASSERT(!other.isInline()); OutOfLineBits* a = outOfLineBits(); const OutOfLineBits* b = other.outOfLineBits(); for (unsigned i = a->numWords(); i--;) a->bits()[i] |= b->bits()[i]; }
prettyTable& prettyTable::addValue(double value) { if (fillRowWise_) { if (col_ == maxCol_) { ++row_; col_ = 0; } else { ++col_; } } else { if (row_ == maxRow_) { ++col_; row_ = 0; } else { ++row_; } } ensureSize(); values_[row_][col_] = value; return *this; }
bool refillCache (const int numSamples, double startTime, const double endTime, const double rate, const int numChans, const int sampsPerThumbSample, LevelDataSource* levelData, const OwnedArray<ThumbData>& chans) { const double timePerPixel = (endTime - startTime) / numSamples; if (numSamples <= 0 || timePerPixel <= 0.0 || rate <= 0) { invalidate(); return false; } if (numSamples == numSamplesCached && numChannelsCached == numChans && startTime == cachedStart && timePerPixel == cachedTimePerPixel && ! cacheNeedsRefilling) { return ! cacheNeedsRefilling; } numSamplesCached = numSamples; numChannelsCached = numChans; cachedStart = startTime; cachedTimePerPixel = timePerPixel; cacheNeedsRefilling = false; ensureSize (numSamples); if (timePerPixel * rate <= sampsPerThumbSample && levelData != nullptr) { int sample = roundToInt (startTime * rate); Array<float> levels; int i; for (i = 0; i < numSamples; ++i) { const int nextSample = roundToInt ((startTime + timePerPixel) * rate); if (sample >= 0) { if (sample >= levelData->lengthInSamples) break; levelData->getLevels (sample, jmax (1, nextSample - sample), levels); const int totalChans = jmin (levels.size() / 2, numChannelsCached); for (int chan = 0; chan < totalChans; ++chan) getData (chan, i)->setFloat (levels.getUnchecked (chan * 2), levels.getUnchecked (chan * 2 + 1)); } startTime += timePerPixel; sample = nextSample; } numSamplesCached = i; } else { jassert (chans.size() == numChannelsCached); for (int channelNum = 0; channelNum < numChannelsCached; ++channelNum) { ThumbData* channelData = chans.getUnchecked (channelNum); MinMaxValue* cacheData = getData (channelNum, 0); const double timeToThumbSampleFactor = rate / (double) sampsPerThumbSample; startTime = cachedStart; int sample = roundToInt (startTime * timeToThumbSampleFactor); for (int i = numSamples; --i >= 0;) { const int nextSample = roundToInt ((startTime + timePerPixel) * timeToThumbSampleFactor); channelData->getMinMax (sample, nextSample, *cacheData); ++cacheData; startTime += timePerPixel; sample = nextSample; } } } return true; }
ThumbData (const int numThumbSamples) : peakLevel (-1) { ensureSize (numThumbSamples); }
si64 CBufferedStream::seek(si64 position) { ensureSize(position); this->position = std::min<si64>(position, buffer.size()); return this->position; }
int main() { int argc; wchar_t ** argv = CommandLineToArgvW(GetCommandLine(), &argc); // Make sure that we've been passed the right number of arguments if (argc < 8) { _tprintf(_T("Usage: %s (four inheritable event handles) (CommandLineToSpawn)\n"), argv[0]); return(0); } // Construct the full command line int nCmdLineLength= MAX_CMD_LINE_LENGTH; wchar_t * szCmdLine= (wchar_t *)malloc(nCmdLineLength * sizeof(wchar_t)); szCmdLine[0]= 0; int nPos = 0; for(int i = 8; i < argc; ++i) { int nCpyLen; int len= wcslen(argv[i]); int requiredSize= nPos+len+2; if (requiredSize > 32*1024) { #ifdef DEBUG_MONITOR OutputDebugStringW(_T("Command line too long!\n")); #endif return 0; } ensureSize(&szCmdLine, &nCmdLineLength, requiredSize); if (NULL == szCmdLine) { #ifdef DEBUG_MONITOR OutputDebugStringW(_T("Not enough memory to build cmd line!\n")); #endif return 0; } if(0 > (nCpyLen = copyTo(szCmdLine + nPos, argv[i], len, nCmdLineLength - nPos))) { #ifdef DEBUG_MONITOR OutputDebugStringW(_T("Not enough space to build command line\n")); #endif return 0; } nPos += nCpyLen; szCmdLine[nPos] = _T(' '); ++nPos; } szCmdLine[nPos] = _T('\0'); STARTUPINFOW si = {sizeof(si)}; PROCESS_INFORMATION pi = {0}; DWORD dwExitCode = 0; #ifdef DEBUG_MONITOR int currentPID = GetCurrentProcessId(); wchar_t buffer[MAX_CMD_LINE_LENGTH]; #endif BOOL exitProc = FALSE; HANDLE waitEvent = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[4]); HANDLE h[5]; h[0] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[3]); // simulated SIGINT (CTRL-C or Cygwin 'kill -SIGINT') // h[1] we reserve for the process handle h[2] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[5]); // simulated SIGTERM h[3] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[6]); // simulated SIGKILL h[4] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[7]); // CTRL-C, in all cases SetConsoleCtrlHandler(HandlerRoutine, TRUE); int parentPid = wcstol(argv[1], NULL, 10); int nCounter = wcstol(argv[2], NULL, 10); wchar_t inPipeName[PIPE_NAME_LENGTH]; wchar_t outPipeName[PIPE_NAME_LENGTH]; wchar_t errPipeName[PIPE_NAME_LENGTH]; swprintf(inPipeName, L"\\\\.\\pipe\\stdin%08i%010i", parentPid, nCounter); swprintf(outPipeName, L"\\\\.\\pipe\\stdout%08i%010i", parentPid, nCounter); swprintf(errPipeName, L"\\\\.\\pipe\\stderr%08i%010i", parentPid, nCounter); #ifdef DEBUG_MONITOR swprintf(buffer, _T("Pipes: %s, %s, %s\n"), inPipeName, outPipeName, errPipeName); OutputDebugStringW(buffer); #endif HANDLE stdHandles[3]; SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; if((INVALID_HANDLE_VALUE == (stdHandles[0] = CreateFileW(inPipeName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, &sa))) || (INVALID_HANDLE_VALUE == (stdHandles[1] = CreateFileW(outPipeName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, &sa))) || (INVALID_HANDLE_VALUE == (stdHandles[2] = CreateFileW(errPipeName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, &sa)))) { #ifdef DEBUG_MONITOR swprintf(buffer, _T("Failed to open pipe %i, %i, %i: %i\n"), stdHandles[0], stdHandles[1], stdHandles[2], GetLastError()); OutputDebugStringW(buffer); #endif CloseHandle(stdHandles[0]); CloseHandle(stdHandles[1]); CloseHandle(stdHandles[2]); return -1;; } SetHandleInformation(stdHandles[0], HANDLE_FLAG_INHERIT, TRUE); SetHandleInformation(stdHandles[1], HANDLE_FLAG_INHERIT, TRUE); SetHandleInformation(stdHandles[2], HANDLE_FLAG_INHERIT, TRUE); if(!SetStdHandle(STD_INPUT_HANDLE, stdHandles[0]) || !SetStdHandle(STD_OUTPUT_HANDLE, stdHandles[1]) || !SetStdHandle(STD_ERROR_HANDLE, stdHandles[2])) { #ifdef DEBUG_MONITOR swprintf(buffer, _T("Failed to reassign standard streams: %i\n"), GetLastError()); OutputDebugStringW(buffer); #endif CloseHandle(stdHandles[0]); CloseHandle(stdHandles[1]); CloseHandle(stdHandles[2]); return -1;; } #ifdef DEBUG_MONITOR wchar_t * lpvEnv = GetEnvironmentStringsW(); // If the returned pointer is NULL, exit. if (lpvEnv == NULL) OutputDebugStringW(_T("Cannot Read Environment\n")); else { // Variable strings are separated by NULL byte, and the block is // terminated by a NULL byte. OutputDebugStringW(_T("Starter: Environment\n")); for (wchar_t * lpszVariable = (wchar_t *) lpvEnv; *lpszVariable; lpszVariable+=wcslen(lpszVariable) + 1) { swprintf(buffer, _T("%s\n"), lpszVariable); OutputDebugStringW(buffer); } FreeEnvironmentStringsW(lpvEnv); } #endif #ifdef DEBUG_MONITOR swprintf(buffer, _T("Starting: %s\n"), szCmdLine); OutputDebugStringW(buffer); #endif // Create job object HANDLE hJob = CreateJobObject(NULL, NULL); // Spawn the other processes as part of this Process Group BOOL f = CreateProcessW(NULL, szCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); // We don't need them any more CloseHandle(stdHandles[0]); CloseHandle(stdHandles[1]); CloseHandle(stdHandles[2]); if (f) { #ifdef DEBUG_MONITOR swprintf(buffer, _T("Process %i started\n"), pi.dwProcessId); OutputDebugStringW(buffer); #endif SetEvent(waitEvent); // Means thar process has been spawned CloseHandle(pi.hThread); h[1] = pi.hProcess; if(NULL != hJob) { if(!AssignProcessToJobObject(hJob, pi.hProcess)) { #ifdef DEBUG_MONITOR swprintf(buffer, _T("Cannot assign process %i to a job\n"), pi.dwProcessId); OutputDebugStringW(buffer); DisplayErrorMessage(); #endif } } while(!exitProc) { // Wait for the spawned-process to die or for the event // indicating that the processes should be forcibly killed. DWORD event = WaitForMultipleObjects(5, h, FALSE, INFINITE); switch (event) { case WAIT_OBJECT_0 + 0: // SIGINT case WAIT_OBJECT_0 + 4: // CTRL-C #ifdef DEBUG_MONITOR swprintf(buffer, _T("starter (PID %i) received CTRL-C event\n"), currentPID); OutputDebugStringW(buffer); #endif if ((event == (WAIT_OBJECT_0 + 0)) && isCygwin(h[1])) { // Need to issue a kill command wchar_t kill[1024]; swprintf(kill, L"kill -SIGINT %d", pi.dwProcessId); if (!runCygwinCommand(kill)) { // fall back to console event GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); } } else { GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); } SetEvent(waitEvent); break; case WAIT_OBJECT_0 + 1: // App terminated normally // Make it's exit code our exit code #ifdef DEBUG_MONITOR swprintf(buffer, _T("starter: launched process has been terminated(PID %i)\n"), pi.dwProcessId); OutputDebugStringW(buffer); #endif GetExitCodeProcess(pi.hProcess, &dwExitCode); exitProc = TRUE; break; // Terminate and Kill behavior differ only for cygwin processes, where // we use the cygwin 'kill' command. We send a SIGKILL in one case, // SIGTERM in the other. For non-cygwin processes, both requests // are treated exactly the same case WAIT_OBJECT_0 + 2: // TERM case WAIT_OBJECT_0 + 3: // KILL { const wchar_t* signal = (event == WAIT_OBJECT_0 + 2) ? L"TERM" : L"KILL"; #ifdef DEBUG_MONITOR swprintf(buffer, _T("starter received %s event (PID %i)\n"), signal, currentPID); OutputDebugStringW(buffer); #endif if (isCygwin(h[1])) { // Need to issue a kill command wchar_t kill[1024]; swprintf(kill, L"kill -%s %d", signal, pi.dwProcessId); if (!runCygwinCommand(kill)) { // fall back to console event GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); } } else { GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); } SetEvent(waitEvent); if(NULL != hJob) { if(!TerminateJobObject(hJob, (DWORD)-1)) { #ifdef DEBUG_MONITOR OutputDebugStringW(_T("Cannot terminate job\n")); DisplayErrorMessage(); #endif } } // Note that we keep trucking until the child process terminates (case WAIT_OBJECT_0 + 1) break; } default: // Unexpected code #ifdef DEBUG_MONITOR DisplayErrorMessage(); #endif exitProc = TRUE; break; } } } else { #ifdef DEBUG_MONITOR swprintf(buffer, _T("Cannot start: %s\n"), szCmdLine); OutputDebugStringW(buffer); DisplayErrorMessage(); #endif } if (NULL != szCmdLine) { free(szCmdLine); } CloseHandle(waitEvent); CloseHandle(h[0]); CloseHandle(h[1]); CloseHandle(h[2]); CloseHandle(h[3]); CloseHandle(h[4]); return(dwExitCode); }