示例#1
0
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 */
}
示例#2
0
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;
}
示例#3
0
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
}
示例#5
0
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;
}
示例#7
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
}
示例#9
0
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
}
示例#10
0
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 */
}
示例#11
0
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 */
}
示例#12
0
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 */
}
示例#13
0
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
}
示例#14
0
/***************************************************************************
 * \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;
}
示例#15
0
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;
}
示例#16
0
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
}
示例#17
0
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);
}
示例#18
0
 void             IncRecCounter() { oRecOpenCount[CPLGetPID()] ++; }
示例#19
0
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
}
示例#20
0
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
}
示例#21
0
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
    }
示例#22
0
 int              GetRecCounter() { return oRecOpenCount[CPLGetPID()]; }
示例#23
0
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;
}
示例#24
0
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;
}
示例#25
0
 void             DecRecCounter() { oRecOpenCount[CPLGetPID()] --; }
示例#26
0
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;
}