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;
}
Exemplo n.º 6
0
		/* 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;
}
Exemplo n.º 8
0
prettyTable& prettyTable::addTitle(std::string title) {
    colRowTitles_++;
    maxColRowTitles_ = std::max(maxColRowTitles_, colRowTitles_);
    ensureSize();
    rowTitles_[rowRowTitles_][colRowTitles_] = title;

    return *this;
}
Exemplo n.º 9
0
prettyTable& prettyTable::nextTitleRow() {
    maxColRowTitles_ = std::max(maxColRowTitles_, colRowTitles_);
    colRowTitles_ = -1;
    rowRowTitles_++;
    ensureSize();

    return *this;
}
Exemplo n.º 10
0
prettyTable& prettyTable::addColumnName(std::string name) {
    rowColNames_++;
    maxRowColNames_ = std::max(maxRowColNames_, rowColNames_);
    ensureSize();
    colNames_[rowColNames_][colColNames_] = name;

    return *this;
}
Exemplo n.º 11
0
		const Vector3r getTorqueSingle(Body::id_t id){ 
			ensureSize(id); 
			if (permForceUsed) {
				return _torque[id] + _permTorque[id];
			} else {
				return _torque[id];
			}
		}
Exemplo n.º 12
0
prettyTable& prettyTable::nextColumnNameColumn() {
    //maxRowColNames_ = std::max(maxRowColNames_, rowColNames_);
    rowColNames_ = -1;
    colColNames_++;
    ensureSize();

    return *this;
}
Exemplo n.º 13
0
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;
}
Exemplo n.º 14
0
bool IOBuffer::storeBytes(const char* someData, const rx_uint32 numBytes) {
	if(!ensureSize(numBytes)) {
		return false;
	}
	memcpy(buffer+published, someData, numBytes);
	published += numBytes;
	return true;
}
Exemplo n.º 15
0
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;
    }
}
Exemplo n.º 16
0
			void pushBump(element_type const & entry)
			{
				if ( expect_false(full()) )
				{
					ensureSize(std::max(2*f,static_cast<size_t>(1)));
					assert ( ! full() );
				}
				push(entry);
			}
Exemplo n.º 17
0
		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;
		}
Exemplo n.º 18
0
Arquivo: pnuts.c Projeto: kmizu/spnuts
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;
}
Exemplo n.º 19
0
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;
}
Exemplo n.º 20
0
    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];
    }
Exemplo n.º 21
0
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;
}
Exemplo n.º 22
0
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();
    }

}
Exemplo n.º 23
0
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);
}
Exemplo n.º 24
0
Arquivo: being.cpp Projeto: Ablu/mana
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];
}
Exemplo n.º 26
0
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;
}
Exemplo n.º 27
0
    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;
    }
Exemplo n.º 28
0
 ThumbData (const int numThumbSamples)
     : peakLevel (-1)
 {
     ensureSize (numThumbSamples);
 }
Exemplo n.º 29
0
si64 CBufferedStream::seek(si64 position)
{
	ensureSize(position);
	this->position = std::min<si64>(position, buffer.size());
	return this->position;
}
Exemplo n.º 30
0
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);
}