示例#1
0
文件: carbon_gui.cpp 项目: dyne/MuSE
void CARBON_GUI::msgOut(char *txt) {
	ItemCount nLines=0;
	SInt32 sLines;
	Handle oldText = NULL;
	TXNOffset start = 0;
	TXNOffset end = 0;
	TXNDataType dType;
	UniChar *p;
	int off = 0;
	statusLock();
	if(txt && statusText) {
		TXNGetLineCount(statusText,&nLines);
		if(nLines > CGUI_STATUS_MAX_LINES) {
			TXNControlTag iControlTags[1] = { kTXNAutoScrollBehaviorTag };
			TXNControlData iControlData[1] = { kTXNAutoScrollNever }; //kTXNAutoScrollWhenInsertionVisible };
			err = TXNSetTXNObjectControls(statusText,false,1,iControlTags,iControlData);

			TXNTypeAttributes attr = { kTXNTextEncodingAttribute,kTXNTextEncodingAttributeSize,{0} };
			
			//TXNGetIndexedRunInfoFromRange(statusText,0,kTXNStartOffset,kTXNEndOffset,&start,&end,&dType,1,&attr);
			
			if(TXNGetData(statusText,kTXNStartOffset,kTXNEndOffset,&oldText) != noErr)
				msg->error("Can't get status text buffer!! (%d)\n");
			
			end = TXNDataSize(statusText);
			p = (UniChar *)*oldText;
			while(*((*oldText)+off) != '\n' && off < end) {
				off++;
			}
			p++;
			off++;
			//off = 256;
			TXNSetData(statusText,kTXNTextData,"",0,kTXNStartOffset,off/sizeof(UniChar));
			/*
			if(end > off) 
				TXNSetData(statusText,kTXNUnicodeTextData,(*oldText)+off,end-off,kTXNStartOffset,kTXNEndOffset);
			*/
			//err = TXNScroll(statusText,kTXNScrollUnitsInLines,kTXNScrollUnitsInLines,&nLines,&nCols);
		}
		TXNSetData(statusText,kTXNTextData,"[*] ",4,kTXNEndOffset,kTXNEndOffset);
		TXNSetData(statusText,kTXNTextData,txt,strlen(txt),kTXNEndOffset,kTXNEndOffset);
		TXNSetData(statusText,kTXNTextData,"\n",1,kTXNEndOffset,kTXNEndOffset);
	}
	if(oldText)
		DisposeHandle(oldText);
	statusUnlock();
}
示例#2
0
// returning uint64_t(-1) means error
uint64_t ChunkBuffer::fill() {
    UniqueLock statusLock(&this->statusMutex);

    while (this->status != ReadyToFill) {
        pthread_cond_wait(&this->statusCondVar, &this->statusMutex);
    }

    if (S3QueryIsAbortInProgress() || this->isError()) {
        this->setSharedError(true);
        this->status = ReadyToRead;
        pthread_cond_signal(&this->statusCondVar);
        return -1;
    }

    uint64_t offset = this->curFileOffset;
    uint64_t leftLen = this->chunkDataSize;

    uint64_t readLen = 0;

    if (leftLen != 0) {
        try {
            readLen = this->s3Interface->fetchData(offset, this->chunkData, leftLen, this->s3Url);
            if (readLen != leftLen) {
                S3DEBUG("Failed to fetch expected data from S3");
                this->setSharedError(true, S3PartialResponseError(leftLen, readLen));
            } else {
                S3DEBUG("Got %" PRIu64 " bytes from S3", readLen);
            }
        } catch (S3Exception& e) {
            S3DEBUG("Failed to fetch expected data from S3");
            this->setSharedError(true);
        }
    }

    if (offset + leftLen >= offsetMgr.getKeySize()) {
        readLen = 0;  // Nothing to read, EOF
        S3DEBUG("Reached the end of file");
        this->eof = true;
    }

    this->status = ReadyToRead;
    pthread_cond_signal(&this->statusCondVar);

    return (this->isError()) ? -1 : readLen;
}
示例#3
0
// ret < len means EMPTY
// that's why it checks if leftLen is larger than *or equal to* len below[1], provides a chance ret
// is 0, which is smaller than len. Otherwise, other functions won't know when to read next buffer.
uint64_t ChunkBuffer::read(char* buf, uint64_t len) {
    // GPDB abort signal stops s3_import(), this check is not needed if s3_import() every time calls
    // ChunkBuffer->Read() only once, otherwise(as we did in downstreamReader->read() for
    // decompression feature before), first call sets buffer to ReadyToFill, second call hangs.
    S3_CHECK_OR_DIE(!S3QueryIsAbortInProgress(), S3QueryAbort, "");

    UniqueLock statusLock(&this->statusMutex);
    while (this->status != ReadyToRead) {
        pthread_cond_wait(&this->statusCondVar, &this->statusMutex);
    }

    // Error is shared between all chunks.
    if (this->isError()) {
        return 0;
    }

    uint64_t leftLen = this->chunkDataSize - this->curChunkOffset;
    uint64_t lenToRead = std::min(len, leftLen);

    if (lenToRead != 0) {
        memcpy(buf, this->chunkData.data() + this->curChunkOffset, lenToRead);
    }

    if (len <= leftLen) {                   // [1]
        this->curChunkOffset += lenToRead;  // not empty
    } else {                                // empty, reset everything
        this->curChunkOffset = 0;

        if (!this->isEOF()) {
            // Release chunkData memory to reduce consumption.
            this->chunkData.release();

            this->status = ReadyToFill;

            Range range = this->offsetMgr.getNextOffset();
            this->curFileOffset = range.offset;
            this->chunkDataSize = range.length;

            pthread_cond_signal(&this->statusCondVar);
        }
    }

    return lenToRead;
}
void WorkerPool::interruptRange(std::size_t inBegin, std::size_t inCount)
{
    LockMany<Mutex> locker;

    //
    // Lock all workers.
    //
    for (std::size_t idx = inBegin; idx != inBegin + inCount; ++idx)
    {
        Worker & worker = *mWorkers[idx];
        locker.lock(worker.mQueueMutex);

        // Keep queue locked for now.
    }

    //
    // Clear queues and interrupt the work.
    //
    for (std::size_t idx = inBegin; idx != inBegin + inCount; ++idx)
    {
        Worker & worker = *mWorkers[idx];

        worker.mQueue.clear();
        worker.interrupt(false);

        // NOTE: don't wait here, because that would be wasteful.
    }

    //
    // Wait until all workers are ready.
    //
    for (std::size_t idx = inBegin; idx != inBegin + inCount; ++idx)
    {
        Worker & worker = *mWorkers[idx];
        ScopedLock statusLock(worker.mStatusMutex);
        if (worker.mStatus == WorkerStatus_Working)
        {
            worker.mStatusCondition.wait(statusLock);
        }
    }
}