Example #1
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;
}
CPLErr GDALRasterBlock::Internalize()

{
    CPLMutexHolderD(&hRBMutex);
    void    *pNewData;
    int     nSizeInBytes;
    GIntBig nCurCacheMax = GDALGetCacheMax64();

    /* No risk of overflow as it is checked in GDALRasterBand::InitBlockInfo() */
    nSizeInBytes = nXSize * nYSize * (GDALGetDataTypeSize(eType) / 8);

    pNewData = VSIMalloc(nSizeInBytes);
    if (pNewData == NULL)
    {
        CPLError(CE_Failure, CPLE_OutOfMemory,
                 "GDALRasterBlock::Internalize : Out of memory allocating %d bytes.",
                 nSizeInBytes);
        return(CE_Failure);
    }

    if (pData != NULL)
        memcpy(pNewData, pData, nSizeInBytes);

    pData = pNewData;

/* -------------------------------------------------------------------- */
/*      Flush old blocks if we are nearing our memory limit.            */
/* -------------------------------------------------------------------- */
    AddLock(); /* don't flush this block! */

    nCacheUsed += nSizeInBytes;

    while (nCacheUsed > nCurCacheMax)
    {
        GIntBig nOldCacheUsed = nCacheUsed;

        GDALFlushCacheBlock();

        if (nCacheUsed == nOldCacheUsed)
            break;
    }

/* -------------------------------------------------------------------- */
/*      Add this block to the list.                                     */
/* -------------------------------------------------------------------- */
    Touch();
    DropLock();

    return(CE_None);
}