CPLMutexHolder::CPLMutexHolder( void **phMutex, double dfWaitInSeconds, const char *pszFileIn, int nLineIn ) { #ifndef MUTEX_NONE pszFile = pszFileIn; nLine = nLineIn; #ifdef DEBUG_MUTEX CPLDebug( "MH", "Request %p for pid %ld at %d/%s", *phMutex, (long) CPLGetPID(), nLine, pszFile ); #endif if( !CPLCreateOrAcquireMutex( phMutex, dfWaitInSeconds ) ) { CPLDebug( "CPLMutexHolder", "failed to acquire mutex!" ); hMutex = NULL; } else { #ifdef DEBUG_MUTEX CPLDebug( "MH", "Acquired %p for pid %ld at %d/%s", *phMutex, (long) CPLGetPID(), nLine, pszFile ); #endif hMutex = *phMutex; } #endif /* ndef MUTEX_NONE */ }
VSIFileManager *VSIFileManager::Get() { static volatile GPtrDiff_t nConstructerPID = 0; if( poManager != NULL ) { if( nConstructerPID != 0 ) { GPtrDiff_t nCurrentPID = static_cast<GPtrDiff_t>(CPLGetPID()); if( nConstructerPID != nCurrentPID ) { { CPLMutexHolder oHolder( &hVSIFileManagerMutex ); } if ( nConstructerPID != 0 ) { VSIDebug1( "nConstructerPID != 0: %d", nConstructerPID); assert(false); } } } return poManager; } CPLMutexHolder oHolder2( &hVSIFileManagerMutex ); if( poManager == NULL ) { nConstructerPID = static_cast<GPtrDiff_t>(CPLGetPID()); #ifdef DEBUG_VERBOSE printf("Thread %d: VSIFileManager in construction\n", nConstructerPID); #endif poManager = new VSIFileManager; VSIInstallLargeFileHandler(); VSIInstallSubFileHandler(); VSIInstallMemFileHandler(); #ifdef HAVE_LIBZ VSIInstallGZipFileHandler(); VSIInstallZipFileHandler(); #endif #ifdef HAVE_CURL VSIInstallCurlFileHandler(); VSIInstallCurlStreamingFileHandler(); VSIInstallS3FileHandler(); VSIInstallS3StreamingFileHandler(); #endif VSIInstallStdinHandler(); VSIInstallStdoutHandler(); VSIInstallSparseFileHandler(); VSIInstallTarFileHandler(); VSIInstallCryptFileHandler(); //printf("Thread %d: VSIFileManager construction finished\n", nConstructerPID); nConstructerPID = 0; } return poManager; }
VSIFileManager *VSIFileManager::Get() { static volatile int nConstructerPID = 0; if( poManager != NULL ) { if( nConstructerPID != 0 ) { int nCurrentPID = (int)CPLGetPID(); if( nConstructerPID != nCurrentPID ) { //printf("Thread %d: Waiting for VSIFileManager to be finished by other thread.\n", nCurrentPID); { CPLMutexHolder oHolder( &hVSIFileManagerMutex ); } //printf("Thread %d: End of wait for VSIFileManager construction to be finished\n", nCurrentPID); CPLAssert(nConstructerPID == 0); } } return poManager; } CPLMutexHolder oHolder2( &hVSIFileManagerMutex ); if( poManager == NULL ) { nConstructerPID = (int)CPLGetPID(); //printf("Thread %d: VSIFileManager in construction\n", nConstructerPID); poManager = new VSIFileManager; VSIInstallLargeFileHandler(); VSIInstallSubFileHandler(); VSIInstallMemFileHandler(); #ifdef HAVE_LIBZ VSIInstallGZipFileHandler(); VSIInstallZipFileHandler(); #endif #ifdef HAVE_CURL VSIInstallCurlFileHandler(); VSIInstallCurlStreamingFileHandler(); #endif VSIInstallStdinHandler(); VSIInstallStdoutHandler(); VSIInstallSparseFileHandler(); VSIInstallTarFileHandler(); //printf("Thread %d: VSIFileManager construction finished\n", nConstructerPID); nConstructerPID = 0; } return poManager; }
void VSIFree( void * pData ) { #ifdef DEBUG_VSIMALLOC if (pData == NULL) return; char* ptr = ((char*)pData) - 4 - sizeof(size_t); VSICheckMarker(ptr); ptr[0] = 'M'; ptr[1] = 'I'; ptr[2] = 'S'; ptr[3] = 'V'; #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE) size_t nOldSize; memcpy(&nOldSize, ptr + 4, sizeof(size_t)); { CPLMutexHolderD(&hMemStatMutex); #ifdef DEBUG_VSIMALLOC_VERBOSE fprintf(stderr, "Thread[%p] VSIFree(%p, (%d bytes))\n", (void*)CPLGetPID(), pData, (int)nOldSize); #endif #ifdef DEBUG_VSIMALLOC_STATS nVSIFrees ++; nCurrentTotalAllocs -= nOldSize; #endif } #endif free(ptr); #else if( pData != NULL ) free( pData ); #endif }
const char *CPLGenerateTempFilename( const char *pszStem ) { const char *pszDir = CPLGetConfigOption( "CPL_TMPDIR", NULL ); static volatile int nTempFileCounter = 0; if( pszDir == NULL ) pszDir = CPLGetConfigOption( "TMPDIR", NULL ); if( pszDir == NULL ) pszDir = CPLGetConfigOption( "TEMP", NULL ); if( pszDir == NULL ) pszDir = "."; CPLString osFilename; if( pszStem == NULL ) pszStem = ""; osFilename.Printf( "%s%u_%d", pszStem, (int) CPLGetPID(), nTempFileCounter++ ); return CPLFormFilename( pszDir, osFilename, NULL ); }
int main(int argc, char* argv[]) { CPLJoinableThread* hThread; printf("main thread %p\n", (void*)CPLGetPID()); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); CPLSetConfigOption("GDAL_CACHEMAX", "0"); CPLSetConfigOption("GDAL_DEBUG_BLOCK_CACHE", "ON"); MyDataset* poDS = new MyDataset(); char buf1[] = { 1 } ; CPL_IGNORE_RET_VAL(GDALRasterIO(GDALGetRasterBand(poDS, 1), GF_Write, 0, 0, 1, 1, buf1, 1, 1, GDT_Byte, 0, 0)); hThread = CPLCreateJoinableThread(thread_func, NULL); CPLSleep(0.3); CPL_IGNORE_RET_VAL(GDALRasterIO(GDALGetRasterBand(poDS, 1), GF_Write, 1, 0, 1, 1, buf1, 1, 1, GDT_Byte, 0, 0)); GDALFlushCacheBlock(); CPLJoinThread(hThread); delete poDS; GDALDestroyDriverManager(); CSLDestroy( argv ); return 0; }
int GDALRasterBlock::TakeLock() { const int nLockVal = AddLock(); CPLAssert(nLockVal >= 0); if( bSleepsForBockCacheDebug ) CPLSleep(CPLAtof( CPLGetConfigOption("GDAL_RB_TRYGET_SLEEP_AFTER_TAKE_LOCK", "0"))); if( nLockVal == 0 ) { #ifdef DEBUG CPLDebug( "GDAL", "TakeLock(%p): Block(%d,%d,%p) is being evicted while trying to " "reacquire it.", reinterpret_cast<void *>(CPLGetPID()), nXOff, nYOff, poBand ); #endif // The block is being evicted by GDALRasterBlock::Internalize() // or FlushCacheBlock(), so wait for this to be done before trying // again. DropLock(); // wait for the block having been unreferenced TAKE_LOCK; return FALSE; } Touch(); return TRUE; }
void *VSIMalloc( size_t nSize ) { #ifdef DEBUG_VSIMALLOC char* ptr = (char*) malloc(4 + sizeof(size_t) + nSize); if (ptr == NULL) return NULL; ptr[0] = 'V'; ptr[1] = 'S'; ptr[2] = 'I'; ptr[3] = 'M'; memcpy(ptr + 4, &nSize, sizeof(size_t)); #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE) { CPLMutexHolderD(&hMemStatMutex); #ifdef DEBUG_VSIMALLOC_VERBOSE fprintf(stderr, "Thread[%p] VSIMalloc(%d) = %p\n", (void*)CPLGetPID(), (int)nSize, ptr + 4 + sizeof(size_t)); #endif #ifdef DEBUG_VSIMALLOC_STATS nVSIMallocs ++; if (nMaxTotalAllocs == 0) atexit(VSIShowMemStats); nCurrentTotalAllocs += nSize; if (nCurrentTotalAllocs > nMaxTotalAllocs) nMaxTotalAllocs = nCurrentTotalAllocs; #endif } #endif return ptr + 4 + sizeof(size_t); #else return( malloc( nSize ) ); #endif }
void *VSIMalloc( size_t nSize ) { #ifdef DEBUG_VSIMALLOC if (nMaxPeakAllocSize < 0) { char* pszMaxPeakAllocSize = getenv("CPL_MAX_PEAK_ALLOC_SIZE"); nMaxPeakAllocSize = (pszMaxPeakAllocSize) ? atoi(pszMaxPeakAllocSize) : 0; char* pszMaxCumulAllocSize = getenv("CPL_MAX_CUMUL_ALLOC_SIZE"); nMaxCumulAllocSize = (pszMaxCumulAllocSize) ? atoi(pszMaxCumulAllocSize) : 0; } if (nMaxPeakAllocSize > 0 && (GIntBig)nSize > nMaxPeakAllocSize) return NULL; #ifdef DEBUG_VSIMALLOC_STATS if (nMaxCumulAllocSize > 0 && (GIntBig)nCurrentTotalAllocs + (GIntBig)nSize > nMaxCumulAllocSize) return NULL; #endif #ifdef DEBUG_VSIMALLOC_MPROTECT char* ptr = NULL; size_t nPageSize = getpagesize(); posix_memalign((void**)&ptr, nPageSize, (3 * sizeof(void*) + nSize + nPageSize - 1) & ~(nPageSize - 1)); #else char* ptr = (char*) malloc(3 * sizeof(void*) + nSize); #endif if (ptr == NULL) return NULL; ptr[0] = 'V'; ptr[1] = 'S'; ptr[2] = 'I'; ptr[3] = 'M'; memcpy(ptr + sizeof(void*), &nSize, sizeof(void*)); ptr[2 * sizeof(void*) + nSize + 0] = 'E'; ptr[2 * sizeof(void*) + nSize + 1] = 'V'; ptr[2 * sizeof(void*) + nSize + 2] = 'S'; ptr[2 * sizeof(void*) + nSize + 3] = 'I'; #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE) { CPLMutexHolderD(&hMemStatMutex); #ifdef DEBUG_VSIMALLOC_VERBOSE fprintf(stderr, "Thread[%p] VSIMalloc(%d) = %p\n", (void*)CPLGetPID(), (int)nSize, ptr + 2 * sizeof(void*)); #endif #ifdef DEBUG_VSIMALLOC_STATS nVSIMallocs ++; if (nMaxTotalAllocs == 0) atexit(VSIShowMemStats); nCurrentTotalAllocs += nSize; if (nCurrentTotalAllocs > nMaxTotalAllocs) nMaxTotalAllocs = nCurrentTotalAllocs; #endif } #endif return ptr + 2 * sizeof(void*); #else return( malloc( nSize ) ); #endif }
CPLMutexHolder::~CPLMutexHolder() { #ifndef MUTEX_NONE if( hMutex != NULL ) { #ifdef DEBUG_MUTEX CPLDebug( "MH", "Release %p for pid %ld at %d/%s", hMutex, (long) CPLGetPID(), nLine, pszFile ); #endif CPLReleaseMutex( hMutex ); } #endif /* ndef MUTEX_NONE */ }
CPLMutexHolder::CPLMutexHolder( void **phMutex, double dfWaitInSeconds, const char *pszFileIn, int nLineIn ) { #ifndef MUTEX_NONE pszFile = pszFileIn; nLine = nLineIn; #ifdef DEBUG_MUTEX /* * XXX: There is no way to use CPLDebug() here because it works with * mutexes itself so we will fall in infinite recursion. Good old * fprintf() will do the job right. */ fprintf( stderr, "CPLMutexHolder: Request %p for pid %ld at %d/%s.\n", *phMutex, (long) CPLGetPID(), nLine, pszFile ); #endif if( !CPLCreateOrAcquireMutex( phMutex, dfWaitInSeconds ) ) { fprintf( stderr, "CPLMutexHolder: Failed to acquire mutex!\n" ); hMutex = NULL; } else { #ifdef DEBUG_MUTEX fprintf( stderr, "CPLMutexHolder: Acquired %p for pid %ld at %d/%s.\n", *phMutex, (long) CPLGetPID(), nLine, pszFile ); #endif hMutex = *phMutex; } #endif /* ndef MUTEX_NONE */ }
CPLMutexHolder::~CPLMutexHolder() { #ifndef MUTEX_NONE if( hMutex != NULL ) { #ifdef DEBUG_MUTEX fprintf( stderr, "~CPLMutexHolder: Release %p for pid %ld at %d/%s.\n", hMutex, (long) CPLGetPID(), nLine, pszFile ); #endif CPLReleaseMutex( hMutex ); } #endif /* ndef MUTEX_NONE */ }
void VSIFree( void * pData ) { #ifdef DEBUG_VSIMALLOC if (pData == NULL) return; char* ptr = ((char*)pData) - 2 * sizeof(void*); VSICheckMarkerBegin(ptr); size_t nOldSize; memcpy(&nOldSize, ptr + sizeof(void*), sizeof(void*)); VSICheckMarkerEnd(ptr, 2 * sizeof(void*) + nOldSize); ptr[0] = 'M'; ptr[1] = 'I'; ptr[2] = 'S'; ptr[3] = 'V'; ptr[2 * sizeof(void*) + nOldSize + 0] = 'I'; ptr[2 * sizeof(void*) + nOldSize + 1] = 'S'; ptr[2 * sizeof(void*) + nOldSize + 2] = 'V'; ptr[2 * sizeof(void*) + nOldSize + 3] = 'E'; #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE) { CPLMutexHolderD(&hMemStatMutex); #ifdef DEBUG_VSIMALLOC_VERBOSE fprintf(stderr, "Thread[%p] VSIFree(%p, (%d bytes))\n", (void*)CPLGetPID(), pData, (int)nOldSize); #endif #ifdef DEBUG_VSIMALLOC_STATS nVSIFrees ++; nCurrentTotalAllocs -= nOldSize; #endif } #endif #ifdef DEBUG_VSIMALLOC_MPROTECT mprotect(ptr, nOldSize + 2 * sizeof(void*), PROT_NONE); #else free(ptr); #endif #else if( pData != NULL ) free( pData ); #endif }
/*************************************************************************** * \brief Create a PQconn object and store it in a list * * The PostGIS Raster driver keeps the connection with the PostgreSQL database * server for as long it leaves. Following PostGISRasterDataset instance * can re-use the existing connection as long it used the same database, * same host, port and user name. * * The PostGIS Raster driver will keep a list of all the successful * connections so, when connection is requested and it does not exist * on the list a new one will be instantiated, added to the list and * returned to the caller. * * All connection will be destroyed when the PostGISRasterDriver is destroyed. * ***************************************************************************/ PGconn* PostGISRasterDriver::GetConnection(const char* pszConnectionString, const char * pszDbnameIn, const char * pszHostIn, const char * pszPortIn, const char * pszUserIn) { PGconn * poConn = NULL; if( pszHostIn == NULL ) pszHostIn = "(null)"; if( pszPortIn == NULL ) pszPortIn = "(null)"; if( pszUserIn == NULL ) pszUserIn = "(null)"; CPLString osKey = pszDbnameIn; osKey += "-"; osKey += pszHostIn; osKey += "-"; osKey += pszPortIn; osKey += "-"; osKey += pszUserIn; osKey += "-"; osKey += CPLSPrintf(CPL_FRMT_GIB, CPLGetPID()); /** * Look for an existing connection in the map **/ CPLMutexHolderD(&hMutex); std::map<CPLString, PGconn*>::iterator oIter = oMapConnection.find(osKey); if( oIter != oMapConnection.end() ) return oIter->second; /** * There's no existing connection. Create a new one. **/ poConn = PQconnectdb(pszConnectionString); if (poConn == NULL || PQstatus(poConn) == CONNECTION_BAD) { CPLError(CE_Failure, CPLE_AppDefined, "PQconnectdb failed: %s\n", PQerrorMessage(poConn)); PQfinish(poConn); return NULL; } /** * Save connection in the connection map. **/ oMapConnection[osKey] = poConn; return poConn; }
int GDALRasterBlock::DropLockForRemovalFromStorage() { // Detect potential conflict with GDALRasterBlock::Internalize() // or FlushCacheBlock() if( CPLAtomicCompareAndExchange(&nLockCount, 0, -1) ) return TRUE; #ifdef DEBUG CPLDebug( "GDAL", "DropLockForRemovalFromStorage(%p): Block(%d,%d,%p) was attempted " "to be flushed from band but it is flushed by global cache.", reinterpret_cast<void *>(CPLGetPID()), nXOff, nYOff, poBand ); #endif // Wait for the block for having been unreferenced. TAKE_LOCK; return FALSE; }
void * VSIRealloc( void * pData, size_t nNewSize ) { #ifdef DEBUG_VSIMALLOC if (pData == NULL) return VSIMalloc(nNewSize); char* ptr = ((char*)pData) - 4 - sizeof(size_t); VSICheckMarker(ptr); #ifdef DEBUG_VSIMALLOC_STATS size_t nOldSize; memcpy(&nOldSize, ptr + 4, sizeof(size_t)); #endif ptr = (char*) realloc(ptr, nNewSize + 4 + sizeof(size_t)); if (ptr == NULL) return NULL; memcpy(ptr + 4, &nNewSize, sizeof(size_t)); #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE) { CPLMutexHolderD(&hMemStatMutex); #ifdef DEBUG_VSIMALLOC_VERBOSE fprintf(stderr, "Thread[%p] VSIRealloc(%p, %d) = %p\n", (void*)CPLGetPID(), pData, (int)nNewSize, ptr + 4 + sizeof(size_t)); #endif #ifdef DEBUG_VSIMALLOC_STATS nVSIReallocs ++; nCurrentTotalAllocs -= nOldSize; nCurrentTotalAllocs += nNewSize; if (nCurrentTotalAllocs > nMaxTotalAllocs) nMaxTotalAllocs = nCurrentTotalAllocs; #endif } #endif return ptr + 4 + sizeof(size_t); #else return( realloc( pData, nNewSize ) ); #endif }
int CPLSpawn(const char * const papszArgv[], VSILFILE* fin, VSILFILE* fout, int bDisplayErr) { CPLSpawnedProcess* sp = CPLSpawnAsync(NULL, papszArgv, TRUE, TRUE, TRUE, NULL); if( sp == NULL ) return -1; CPL_FILE_HANDLE in_child = CPLSpawnAsyncGetOutputFileHandle(sp); if (fin != NULL) FillPipeFromFile(fin, in_child); CPLSpawnAsyncCloseOutputFileHandle(sp); CPL_FILE_HANDLE out_child = CPLSpawnAsyncGetInputFileHandle(sp); if (fout != NULL) FillFileFromPipe(out_child, fout); CPLSpawnAsyncCloseInputFileHandle(sp); CPL_FILE_HANDLE err_child = CPLSpawnAsyncGetErrorFileHandle(sp); CPLString osName; osName.Printf("/vsimem/child_stderr_" CPL_FRMT_GIB, CPLGetPID()); VSILFILE* ferr = VSIFOpenL(osName.c_str(), "w"); FillFileFromPipe(err_child, ferr); CPLSpawnAsyncCloseErrorFileHandle(sp); CPL_IGNORE_RET_VAL(VSIFCloseL(ferr)); vsi_l_offset nDataLength = 0; GByte* pData = VSIGetMemFileBuffer(osName.c_str(), &nDataLength, TRUE); if( nDataLength > 0 ) pData[nDataLength-1] = '\0'; if( pData && strstr( const_cast<const char *>( reinterpret_cast<char *>( pData ) ), "An error occurred while forking process") != NULL ) bDisplayErr = TRUE; if( pData && bDisplayErr ) CPLError(CE_Failure, CPLE_AppDefined, "[%s error] %s", papszArgv[0], pData); CPLFree(pData); return CPLSpawnAsyncFinish(sp, TRUE, FALSE); }
void IncRecCounter() { oRecOpenCount[CPLGetPID()] ++; }
void * VSIRealloc( void * pData, size_t nNewSize ) { #ifdef DEBUG_VSIMALLOC if (pData == NULL) return VSIMalloc(nNewSize); char* ptr = ((char*)pData) - 2 * sizeof(void*); VSICheckMarkerBegin(ptr); size_t nOldSize; memcpy(&nOldSize, ptr + sizeof(void*), sizeof(void*)); VSICheckMarkerEnd(ptr, 2 * sizeof(void*) + nOldSize); ptr[2 * sizeof(void*) + nOldSize + 0] = 'I'; ptr[2 * sizeof(void*) + nOldSize + 1] = 'S'; ptr[2 * sizeof(void*) + nOldSize + 2] = 'V'; ptr[2 * sizeof(void*) + nOldSize + 3] = 'E'; if (nMaxPeakAllocSize < 0) { char* pszMaxPeakAllocSize = getenv("CPL_MAX_PEAK_ALLOC_SIZE"); nMaxPeakAllocSize = (pszMaxPeakAllocSize) ? atoi(pszMaxPeakAllocSize) : 0; } if (nMaxPeakAllocSize > 0 && (GIntBig)nNewSize > nMaxPeakAllocSize) return NULL; #ifdef DEBUG_VSIMALLOC_STATS if (nMaxCumulAllocSize > 0 && (GIntBig)nCurrentTotalAllocs + (GIntBig)nNewSize - (GIntBig)nOldSize > nMaxCumulAllocSize) return NULL; #endif #ifdef DEBUG_VSIMALLOC_MPROTECT char* newptr = NULL; size_t nPageSize = getpagesize(); posix_memalign((void**)&newptr, nPageSize, (nNewSize + 3 * sizeof(void*) + nPageSize - 1) & ~(nPageSize - 1)); if (newptr == NULL) { ptr[2 * sizeof(void*) + nOldSize + 0] = 'E'; ptr[2 * sizeof(void*) + nOldSize + 1] = 'V'; ptr[2 * sizeof(void*) + nOldSize + 2] = 'S'; ptr[2 * sizeof(void*) + nOldSize + 3] = 'I'; return NULL; } memcpy(newptr + 2 * sizeof(void*), pData, nOldSize); ptr[0] = 'M'; ptr[1] = 'I'; ptr[2] = 'S'; ptr[3] = 'V'; free(ptr); newptr[0] = 'V'; newptr[1] = 'S'; newptr[2] = 'I'; newptr[3] = 'M'; #else void* newptr = realloc(ptr, nNewSize + 3 * sizeof(void*)); if (newptr == NULL) { ptr[2 * sizeof(void*) + nOldSize + 0] = 'E'; ptr[2 * sizeof(void*) + nOldSize + 1] = 'V'; ptr[2 * sizeof(void*) + nOldSize + 2] = 'S'; ptr[2 * sizeof(void*) + nOldSize + 3] = 'I'; return NULL; } #endif ptr = (char*) newptr; memcpy(ptr + sizeof(void*), &nNewSize, sizeof(void*)); ptr[2 * sizeof(void*) + nNewSize + 0] = 'E'; ptr[2 * sizeof(void*) + nNewSize + 1] = 'V'; ptr[2 * sizeof(void*) + nNewSize + 2] = 'S'; ptr[2 * sizeof(void*) + nNewSize + 3] = 'I'; #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE) { CPLMutexHolderD(&hMemStatMutex); #ifdef DEBUG_VSIMALLOC_VERBOSE fprintf(stderr, "Thread[%p] VSIRealloc(%p, %d) = %p\n", (void*)CPLGetPID(), pData, (int)nNewSize, ptr + 2 * sizeof(void*)); #endif #ifdef DEBUG_VSIMALLOC_STATS nVSIReallocs ++; nCurrentTotalAllocs -= nOldSize; nCurrentTotalAllocs += nNewSize; if (nCurrentTotalAllocs > nMaxTotalAllocs) nMaxTotalAllocs = nCurrentTotalAllocs; #endif } #endif return ptr + 2 * sizeof(void*); #else return( realloc( pData, nNewSize ) ); #endif }
void *VSICalloc( size_t nCount, size_t nSize ) { #ifdef DEBUG_VSIMALLOC size_t nMul = nCount * nSize; if (nCount != 0 && nMul / nCount != nSize) { fprintf(stderr, "Overflow in VSICalloc(%d, %d)\n", (int)nCount, (int)nSize); return NULL; } if (nMaxPeakAllocSize < 0) { char* pszMaxPeakAllocSize = getenv("CPL_MAX_PEAK_ALLOC_SIZE"); nMaxPeakAllocSize = (pszMaxPeakAllocSize) ? atoi(pszMaxPeakAllocSize) : 0; char* pszMaxCumulAllocSize = getenv("CPL_MAX_CUMUL_ALLOC_SIZE"); nMaxCumulAllocSize = (pszMaxCumulAllocSize) ? atoi(pszMaxCumulAllocSize) : 0; } if (nMaxPeakAllocSize > 0 && (GIntBig)nMul > nMaxPeakAllocSize) return NULL; #ifdef DEBUG_VSIMALLOC_STATS if (nMaxCumulAllocSize > 0 && (GIntBig)nCurrentTotalAllocs + (GIntBig)nMul > nMaxCumulAllocSize) return NULL; #endif #ifdef DEBUG_VSIMALLOC_MPROTECT char* ptr = NULL; size_t nPageSize = getpagesize(); posix_memalign((void**)&ptr, nPageSize, (3 * sizeof(void*) + nMul + nPageSize - 1) & ~(nPageSize - 1)); if (ptr == NULL) return NULL; memset(ptr + 2 * sizeof(void*), 0, nMul); #else char* ptr = (char*) calloc(1, 3 * sizeof(void*) + nMul); if (ptr == NULL) return NULL; #endif ptr[0] = 'V'; ptr[1] = 'S'; ptr[2] = 'I'; ptr[3] = 'M'; memcpy(ptr + sizeof(void*), &nMul, sizeof(void*)); ptr[2 * sizeof(void*) + nMul + 0] = 'E'; ptr[2 * sizeof(void*) + nMul + 1] = 'V'; ptr[2 * sizeof(void*) + nMul + 2] = 'S'; ptr[2 * sizeof(void*) + nMul + 3] = 'I'; #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE) { CPLMutexHolderD(&hMemStatMutex); #ifdef DEBUG_VSIMALLOC_VERBOSE if( nMul > THRESHOLD_PRINT ) { fprintf(stderr, "Thread[%p] VSICalloc(%d,%d) = %p\n", (void*)CPLGetPID(), (int)nCount, (int)nSize, ptr + 2 * sizeof(void*)); } #endif #ifdef DEBUG_VSIMALLOC_STATS nVSICallocs ++; if (nMaxTotalAllocs == 0) atexit(VSIShowMemStats); nCurrentTotalAllocs += nMul; if (nCurrentTotalAllocs > nMaxTotalAllocs) nMaxTotalAllocs = nCurrentTotalAllocs; #endif } #endif return ptr + 2 * sizeof(void*); #else return calloc( nCount, nSize ); #endif }
void *VSIMalloc( size_t nSize ) { if (nMaxPeakAllocSize < 0) { char* pszMaxPeakAllocSize = getenv("CPL_MAX_PEAK_ALLOC_SIZE"); nMaxPeakAllocSize = (pszMaxPeakAllocSize) ? atoi(pszMaxPeakAllocSize) : 0; char* pszMaxCumulAllocSize = getenv("CPL_MAX_CUMUL_ALLOC_SIZE"); nMaxCumulAllocSize = (pszMaxCumulAllocSize) ? atoi(pszMaxCumulAllocSize) : 0; } if (nMaxPeakAllocSize > 0 && (GIntBig)nSize > nMaxPeakAllocSize) return NULL; #ifdef DEBUG_VSIMALLOC_STATS if (nMaxCumulAllocSize > 0 && (GIntBig)nCurrentTotalAllocs + (GIntBig)nSize > nMaxCumulAllocSize) return NULL; #endif // DEBUG_VSIMALLOC_STATS #ifdef DEBUG_VSIMALLOC_MPROTECT char* ptr = NULL; size_t nPageSize = getpagesize(); posix_memalign((void**)&ptr, nPageSize, (3 * sizeof(void*) + nSize + nPageSize - 1) & ~(nPageSize - 1)); #else char* ptr = (char*) malloc(3 * sizeof(void*) + nSize); #endif // DEBUG_VSIMALLOC_MPROTECT if (ptr == NULL) return NULL; ptr[0] = 'V'; ptr[1] = 'S'; ptr[2] = 'I'; ptr[3] = 'M'; memcpy(ptr + sizeof(void*), &nSize, sizeof(void*)); ptr[2 * sizeof(void*) + nSize + 0] = 'E'; ptr[2 * sizeof(void*) + nSize + 1] = 'V'; ptr[2 * sizeof(void*) + nSize + 2] = 'S'; ptr[2 * sizeof(void*) + nSize + 3] = 'I'; #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE) { CPLMutexHolderD(&hMemStatMutex); #ifdef DEBUG_VSIMALLOC_VERBOSE if( nSize > THRESHOLD_PRINT ) { fprintf(stderr, "Thread[%p] VSIMalloc(%d) = %p" #ifdef DEBUG_VSIMALLOC_STATS ", current_cumul = " CPL_FRMT_GUIB #ifdef DEBUG_BLOCK_CACHE_USE ", block_cache_used = " CPL_FRMT_GIB #endif ", mal+cal-free = %d" #endif "\n", (void*)CPLGetPID(), (int)nSize, ptr + 2 * sizeof(void*) #ifdef DEBUG_VSIMALLOC_STATS , (GUIntBig)(nCurrentTotalAllocs + nSize), #ifdef DEBUG_BLOCK_CACHE_USE , GDALGetCacheUsed64() #endif ,(int)(nVSIMallocs + nVSICallocs - nVSIFrees) #endif ); } #endif // DEBUG_VSIMALLOC_VERBOSE #ifdef DEBUG_VSIMALLOC_STATS nVSIMallocs ++; if (nMaxTotalAllocs == 0) atexit(VSIShowMemStats); nCurrentTotalAllocs += nSize; if (nCurrentTotalAllocs > nMaxTotalAllocs) nMaxTotalAllocs = nCurrentTotalAllocs; #endif // DEBUG_VSIMALLOC_STATS }
int GetRecCounter() { return oRecOpenCount[CPLGetPID()]; }
int NITFUncompressBILEVEL( NITFImage *psImage, GByte *pabyInputData, int nInputBytes, GByte *pabyOutputImage ) { int nOutputBytes= (psImage->nBlockWidth * psImage->nBlockHeight + 7)/8; /* -------------------------------------------------------------------- */ /* Write memory TIFF with the bilevel data. */ /* -------------------------------------------------------------------- */ CPLString osFilename; osFilename.Printf( "/vsimem/nitf-wrk-%ld.tif", (long) CPLGetPID() ); VSILFILE* fpL = VSIFOpenL(osFilename, "w+"); if( fpL == NULL ) return FALSE; TIFF *hTIFF = VSI_TIFFOpen( osFilename, "w+", fpL ); if (hTIFF == NULL) { VSIFCloseL(fpL); return FALSE; } TIFFSetField( hTIFF, TIFFTAG_IMAGEWIDTH, psImage->nBlockWidth ); TIFFSetField( hTIFF, TIFFTAG_IMAGELENGTH, psImage->nBlockHeight ); TIFFSetField( hTIFF, TIFFTAG_BITSPERSAMPLE, 1 ); TIFFSetField( hTIFF, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT ); TIFFSetField( hTIFF, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG ); TIFFSetField( hTIFF, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB ); TIFFSetField( hTIFF, TIFFTAG_ROWSPERSTRIP, psImage->nBlockHeight ); TIFFSetField( hTIFF, TIFFTAG_SAMPLESPERPIXEL, 1 ); TIFFSetField( hTIFF, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK ); TIFFSetField( hTIFF, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX3 ); if( psImage->szCOMRAT[0] == '2' ) TIFFSetField( hTIFF, TIFFTAG_GROUP3OPTIONS, GROUP3OPT_2DENCODING ); TIFFWriteRawStrip( hTIFF, 0, pabyInputData, nInputBytes ); TIFFWriteDirectory( hTIFF ); TIFFClose( hTIFF ); /* -------------------------------------------------------------------- */ /* Now open and read it back. */ /* -------------------------------------------------------------------- */ int bResult = TRUE; hTIFF = VSI_TIFFOpen( osFilename, "r", fpL ); if (hTIFF == NULL) { VSIFCloseL(fpL); return FALSE; } if( TIFFReadEncodedStrip( hTIFF, 0, pabyOutputImage, nOutputBytes ) == -1 ) { memset( pabyOutputImage, 0, nOutputBytes ); bResult = FALSE; } TIFFClose( hTIFF ); VSIFCloseL(fpL); VSIUnlink( osFilename ); return bResult; }
int ForkAndPipe(const char * const argv[], VSILFILE* fin, VSILFILE* fout) { pid_t pid; int pipe_in[2] = { -1, -1 }; int pipe_out[2] = { -1, -1 }; int pipe_err[2] = { -1, -1 }; int i; if (pipe(pipe_in) || pipe(pipe_out) || pipe(pipe_err)) goto err_pipe; pid = fork(); if (pid == 0) { /* Close unused end of pipe */ close(pipe_in[OUT_FOR_PARENT]); close(pipe_out[IN_FOR_PARENT]); close(pipe_err[IN_FOR_PARENT]); dup2(pipe_in[IN_FOR_PARENT], fileno(stdin)); dup2(pipe_out[OUT_FOR_PARENT], fileno(stdout)); dup2(pipe_err[OUT_FOR_PARENT], fileno(stderr)); execvp(argv[0], (char* const*) argv); char* pszErr = strerror(errno); fprintf(stderr, "An error occured while forking process %s : %s", argv[0], pszErr); exit(1); } else if (pid < 0) { CPLError(CE_Failure, CPLE_AppDefined, "fork() failed"); goto err; } else { /* Close unused end of pipe */ close(pipe_in[IN_FOR_PARENT]); close(pipe_out[OUT_FOR_PARENT]); close(pipe_err[OUT_FOR_PARENT]); /* Ignore SIGPIPE */ #ifdef SIGPIPE signal (SIGPIPE, SIG_IGN); #endif if (fin != NULL) WriteToPipe(fin, pipe_in[OUT_FOR_PARENT]); close(pipe_in[OUT_FOR_PARENT]); if (fout != NULL) ReadFromPipe(pipe_out[IN_FOR_PARENT], fout); close(pipe_out[IN_FOR_PARENT]); CPLString osName; osName.Printf("/vsimem/child_stderr_" CPL_FRMT_GIB, CPLGetPID()); VSILFILE* ferr = VSIFOpenL(osName.c_str(), "w"); ReadFromPipe(pipe_err[IN_FOR_PARENT], ferr); close(pipe_err[IN_FOR_PARENT]); VSIFCloseL(ferr); vsi_l_offset nDataLength = 0; GByte* pData = VSIGetMemFileBuffer(osName.c_str(), &nDataLength, TRUE); if (pData) CPLError(CE_Failure, CPLE_AppDefined, "[%s error] %s", argv[0], pData); CPLFree(pData); while(1) { int status; int ret = waitpid (pid, &status, 0); if (ret < 0) { if (errno != EINTR) { break; } } else break; } return pData == NULL; } err_pipe: CPLError(CE_Failure, CPLE_AppDefined, "Could not create pipe"); err: for(i=0; i<2; i++) { if (pipe_in[i] >= 0) close(pipe_in[i]); if (pipe_out[i] >= 0) close(pipe_out[i]); if (pipe_err[i] >= 0) close(pipe_err[i]); } return FALSE; }
void DecRecCounter() { oRecOpenCount[CPLGetPID()] --; }
int ForkAndPipe(const char * const argv[], VSILFILE* fin, VSILFILE* fout) { HANDLE pipe_in[2] = {NULL, NULL}; HANDLE pipe_out[2] = {NULL, NULL}; HANDLE pipe_err[2] = {NULL, NULL}; SECURITY_ATTRIBUTES saAttr; PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo; CPLString osCommandLine; int i; CPLString osName; VSILFILE* ferr; vsi_l_offset nDataLength = 0; GByte* pData; saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; if (!CreatePipe(&pipe_in[IN_FOR_PARENT],&pipe_in[OUT_FOR_PARENT],&saAttr, 0)) goto err_pipe; /* The child must not inherit from the write side of the pipe_in */ if (!SetHandleInformation(pipe_in[OUT_FOR_PARENT],HANDLE_FLAG_INHERIT,0)) goto err_pipe; if (!CreatePipe(&pipe_out[IN_FOR_PARENT],&pipe_out[OUT_FOR_PARENT],&saAttr, 0)) goto err_pipe; /* The child must not inherit from the read side of the pipe_out */ if (!SetHandleInformation(pipe_out[IN_FOR_PARENT],HANDLE_FLAG_INHERIT,0)) goto err_pipe; if (!CreatePipe(&pipe_err[IN_FOR_PARENT],&pipe_err[OUT_FOR_PARENT],&saAttr, 0)) goto err_pipe; /* The child must not inherit from the read side of the pipe_err */ if (!SetHandleInformation(pipe_err[IN_FOR_PARENT],HANDLE_FLAG_INHERIT,0)) goto err_pipe; memset(&piProcInfo, 0, sizeof(PROCESS_INFORMATION)); memset(&siStartInfo, 0, sizeof(STARTUPINFO)); siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.hStdInput = pipe_in[IN_FOR_PARENT]; siStartInfo.hStdOutput = pipe_out[OUT_FOR_PARENT]; siStartInfo.hStdError = pipe_err[OUT_FOR_PARENT]; siStartInfo.dwFlags |= STARTF_USESTDHANDLES; for(i=0; argv[i] != NULL; i++) { if (i > 0) osCommandLine += " "; osCommandLine += argv[i]; } if (!CreateProcess(NULL, (CHAR*)osCommandLine.c_str(), NULL, // process security attributes NULL, // primary thread security attributes TRUE, // handles are inherited 0, // creation flags NULL, // use parent's environment NULL, // use parent's current directory &siStartInfo, &piProcInfo)) { CPLError(CE_Failure, CPLE_AppDefined, "Could not create process %s", osCommandLine.c_str()); goto err; } CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); CloseHandle(pipe_in[IN_FOR_PARENT]); if (fin != NULL) WriteToPipe(fin, pipe_in[OUT_FOR_PARENT]); CloseHandle(pipe_in[OUT_FOR_PARENT]); CloseHandle(pipe_out[OUT_FOR_PARENT]); if (fout != NULL) ReadFromPipe(pipe_out[IN_FOR_PARENT], fout); osName.Printf("/vsimem/child_stderr_" CPL_FRMT_GIB, CPLGetPID()); ferr = VSIFOpenL(osName.c_str(), "w"); CloseHandle(pipe_err[OUT_FOR_PARENT]); ReadFromPipe(pipe_err[IN_FOR_PARENT], ferr); VSIFCloseL(ferr); pData = VSIGetMemFileBuffer(osName.c_str(), &nDataLength, TRUE); if (pData) CPLError(CE_Failure, CPLE_AppDefined, "[%s error] %s", argv[0], pData); CPLFree(pData); CloseHandle(pipe_out[IN_FOR_PARENT]); CloseHandle(pipe_err[IN_FOR_PARENT]); return pData == NULL; err_pipe: CPLError(CE_Failure, CPLE_AppDefined, "Could not create pipe"); err: for(i=0; i<2; i++) { if (pipe_in[i] != NULL) CloseHandle(pipe_in[i]); if (pipe_out[i] != NULL) CloseHandle(pipe_out[i]); if (pipe_err[i] != NULL) CloseHandle(pipe_err[i]); } return FALSE; }