void VSICurlStreamingHandle::PutRingBufferInCache() { if (nRingBufferFileOffset >= BKGND_BUFFER_SIZE) return; AcquireMutex(); /* Cache any remaining bytes available in the ring buffer */ size_t nBufSize = oRingBuffer.GetSize(); if ( nBufSize > 0 ) { if (nRingBufferFileOffset + nBufSize > BKGND_BUFFER_SIZE) nBufSize = (size_t) (BKGND_BUFFER_SIZE - nRingBufferFileOffset); GByte* pabyTmp = (GByte*) CPLMalloc(nBufSize); oRingBuffer.Read(pabyTmp, nBufSize); /* Signal to the producer that we have ingested some bytes */ CPLCondSignal(hCondConsumer); AddRegion(nRingBufferFileOffset, nBufSize, pabyTmp); nRingBufferFileOffset += nBufSize; CPLFree(pabyTmp); } ReleaseMutex(); }
void PackManager::Dispatch() { if (m_socketserver == nullptr) { fprintf(stderr, "socketserver ptr is null."); return; } RingBuffer ringbuffer = m_socketserver->GetRecvBuffer(); if (ringbuffer.IsComplete()) { long sz = ringbuffer.GetSize(); if (sz != ringbuffer.Read(m_readbuffer, sz)) { fprintf(stderr, "ringbuffer read data error."); return; } unsigned int version = PVERSION(m_readbuffer); unsigned int opcode = POPCODE(m_readbuffer); //google::protobuf::Message* pMessage = MessageFactory::CreateMessage(opcode); //pMessage->SerializeToArray(m_readbuffer, sz - HEADSIZE); } }
status_t Inode::ReadDataFromBuffer(void* data, size_t* _length, bool nonBlocking, bool isUser, ReadRequest& request) { size_t dataSize = *_length; *_length = 0; // wait until our request is first in queue status_t error; if (fReadRequests.Head() != &request) { if (nonBlocking) return B_WOULD_BLOCK; TRACE("Inode %p::%s(): wait for request %p to become the first " "request.\n", this, __FUNCTION__, &request); error = WaitForReadRequest(request); if (error != B_OK) return error; } // wait until data are available while (fBuffer.Readable() == 0) { if (nonBlocking) return B_WOULD_BLOCK; if (fActive && fWriterCount == 0) return B_OK; TRACE("Inode %p::%s(): wait for data, request %p\n", this, __FUNCTION__, &request); error = WaitForReadRequest(request); if (error != B_OK) return error; } // read as much as we can size_t toRead = fBuffer.Readable(); if (toRead > dataSize) toRead = dataSize; ssize_t bytesRead = fBuffer.Read(data, toRead, isUser); if (bytesRead < 0) return bytesRead; NotifyBytesRead(toRead); *_length = toRead; return B_OK; }
size_t VSICurlStreamingHandle::Read( void *pBuffer, size_t nSize, size_t nMemb ) { GByte* pabyBuffer = (GByte*)pBuffer; size_t nBufferRequestSize = nSize * nMemb; if (nBufferRequestSize == 0) return 0; size_t nRemaining = nBufferRequestSize; AcquireMutex(); int bHastComputedFileSizeLocal = bHastComputedFileSize; vsi_l_offset fileSizeLocal = fileSize; ReleaseMutex(); if (bHastComputedFileSizeLocal && curOffset >= fileSizeLocal) { CPLDebug("VSICURL", "Read attempt beyond end of file"); bEOF = TRUE; } if (bEOF) return 0; if (curOffset < nRingBufferFileOffset) PutRingBufferInCache(); if (ENABLE_DEBUG) CPLDebug("VSICURL", "Read [" CPL_FRMT_GUIB ", " CPL_FRMT_GUIB "[ in %s", curOffset, curOffset + nBufferRequestSize, pszURL); #ifdef notdef if( pCachedData != NULL && nCachedSize >= 1024 && nRecomputedChecksumOfFirst1024Bytes == 0 ) { for(size_t i = 0; i < 1024 / sizeof(int); i ++) { int nVal; memcpy(&nVal, pCachedData + i * sizeof(int), sizeof(int)); nRecomputedChecksumOfFirst1024Bytes += nVal; } if( bHastComputedFileSizeLocal ) { poFS->AcquireMutex(); CachedFileProp* cachedFileProp = poFS->GetCachedFileProp(pszURL); if( cachedFileProp->nChecksumOfFirst1024Bytes == 0 ) { cachedFileProp->nChecksumOfFirst1024Bytes = nRecomputedChecksumOfFirst1024Bytes; } else if( nRecomputedChecksumOfFirst1024Bytes != cachedFileProp->nChecksumOfFirst1024Bytes ) { CPLDebug("VSICURL", "Invalidating previously cached file size. First bytes of file have changed!"); AcquireMutex(); bHastComputedFileSize = FALSE; cachedFileProp->bHastComputedFileSize = FALSE; cachedFileProp->nChecksumOfFirst1024Bytes = 0; ReleaseMutex(); } poFS->ReleaseMutex(); } } #endif /* Can we use the cache ? */ if( pCachedData != NULL && curOffset < nCachedSize ) { size_t nSz = MIN(nRemaining, (size_t)(nCachedSize - curOffset)); if (ENABLE_DEBUG) CPLDebug("VSICURL", "Using cache for [%d, %d[ in %s", (int)curOffset, (int)(curOffset + nSz), pszURL); memcpy(pabyBuffer, pCachedData + curOffset, nSz); pabyBuffer += nSz; curOffset += nSz; nRemaining -= nSz; } /* Is the request partially covered by the cache and going beyond file size ? */ if ( pCachedData != NULL && bHastComputedFileSizeLocal && curOffset <= nCachedSize && curOffset + nRemaining > fileSizeLocal && fileSize == nCachedSize ) { size_t nSz = (size_t) (nCachedSize - curOffset); if (ENABLE_DEBUG && nSz != 0) CPLDebug("VSICURL", "Using cache for [%d, %d[ in %s", (int)curOffset, (int)(curOffset + nSz), pszURL); memcpy(pabyBuffer, pCachedData + curOffset, nSz); pabyBuffer += nSz; curOffset += nSz; nRemaining -= nSz; bEOF = TRUE; } /* Has a Seek() being done since the last Read() ? */ if (!bEOF && nRemaining > 0 && curOffset != nRingBufferFileOffset) { /* Backward seek : we need to restart the download from the start */ if (curOffset < nRingBufferFileOffset) StopDownload(); StartDownload(); #define SKIP_BUFFER_SIZE 32768 GByte* pabyTmp = (GByte*)CPLMalloc(SKIP_BUFFER_SIZE); CPLAssert(curOffset >= nRingBufferFileOffset); vsi_l_offset nBytesToSkip = curOffset - nRingBufferFileOffset; while(nBytesToSkip > 0) { vsi_l_offset nBytesToRead = nBytesToSkip; AcquireMutex(); if (nBytesToRead > oRingBuffer.GetSize()) nBytesToRead = oRingBuffer.GetSize(); if (nBytesToRead > SKIP_BUFFER_SIZE) nBytesToRead = SKIP_BUFFER_SIZE; oRingBuffer.Read(pabyTmp, (size_t)nBytesToRead); /* Signal to the producer that we have ingested some bytes */ CPLCondSignal(hCondConsumer); ReleaseMutex(); if (nBytesToRead) AddRegion(nRingBufferFileOffset, (size_t)nBytesToRead, pabyTmp); nBytesToSkip -= nBytesToRead; nRingBufferFileOffset += nBytesToRead; if (nBytesToRead == 0 && nBytesToSkip != 0) { if (ENABLE_DEBUG) CPLDebug("VSICURL", "Waiting for writer to produce some bytes..."); AcquireMutex(); while(oRingBuffer.GetSize() == 0 && bDownloadInProgress) CPLCondWait(hCondProducer, hRingBufferMutex); int bBufferEmpty = (oRingBuffer.GetSize() == 0); ReleaseMutex(); if (bBufferEmpty && !bDownloadInProgress) break; } } CPLFree(pabyTmp); if (nBytesToSkip != 0) { bEOF = TRUE; return 0; } } if (!bEOF && nRemaining > 0) { StartDownload(); CPLAssert(curOffset == nRingBufferFileOffset); } /* Fill the destination buffer from the ring buffer */ while(!bEOF && nRemaining > 0) { AcquireMutex(); size_t nToRead = oRingBuffer.GetSize(); if (nToRead > nRemaining) nToRead = nRemaining; oRingBuffer.Read(pabyBuffer, nToRead); /* Signal to the producer that we have ingested some bytes */ CPLCondSignal(hCondConsumer); ReleaseMutex(); if (nToRead) AddRegion(curOffset, nToRead, pabyBuffer); nRemaining -= nToRead; pabyBuffer += nToRead; curOffset += nToRead; nRingBufferFileOffset += nToRead; if (nToRead == 0 && nRemaining != 0) { if (ENABLE_DEBUG) CPLDebug("VSICURL", "Waiting for writer to produce some bytes..."); AcquireMutex(); while(oRingBuffer.GetSize() == 0 && bDownloadInProgress) CPLCondWait(hCondProducer, hRingBufferMutex); int bBufferEmpty = (oRingBuffer.GetSize() == 0); ReleaseMutex(); if (bBufferEmpty && !bDownloadInProgress) break; } } if (ENABLE_DEBUG) CPLDebug("VSICURL", "Read(%d) = %d", (int)nBufferRequestSize, (int)(nBufferRequestSize - nRemaining)); size_t nRet = (nBufferRequestSize - nRemaining) / nSize; if (nRet < nMemb) bEOF = TRUE; return nRet; }