예제 #1
0
int VDIoBackendMemCreate(PPVDIOBACKENDMEM ppIoBackend)
{
    int rc = VINF_SUCCESS;
    PVDIOBACKENDMEM pIoBackend = NULL;

    pIoBackend = (PVDIOBACKENDMEM)RTMemAllocZ(sizeof(VDIOBACKENDMEM));
    if (pIoBackend)
    {
        rc = RTCircBufCreate(&pIoBackend->pRequestRing, VDMEMIOBACKEND_REQS * sizeof(PVDIOBACKENDREQ));
        if (RT_SUCCESS(rc))
        {
            pIoBackend->cReqsRing = VDMEMIOBACKEND_REQS * sizeof(VDIOBACKENDREQ);
            pIoBackend->fRunning  = true;

            rc = RTSemEventCreate(&pIoBackend->EventSem);
            if (RT_SUCCESS(rc))
            {
                rc = RTThreadCreate(&pIoBackend->hThreadIo, vdIoBackendMemThread, pIoBackend, 0, RTTHREADTYPE_IO,
                                    RTTHREADFLAGS_WAITABLE, "MemIo");
                if (RT_SUCCESS(rc))
                {
                    *ppIoBackend = pIoBackend;

                    LogFlowFunc(("returns success\n"));
                    return VINF_SUCCESS;
                }
                RTSemEventDestroy(pIoBackend->EventSem);
            }

            RTCircBufDestroy(pIoBackend->pRequestRing);
        }

        RTMemFree(pIoBackend);
    }
    else
        rc = VERR_NO_MEMORY;

    return rc;
}
예제 #2
0
/**
 * Basic API checks.
 */
static void tst1(void)
{
    void *pvBuf;
    size_t cbSize;

    char pcTestPattern1[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9 };
    char pcTestPattern2[] = { 0x8, 0x9, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9 };
    char pcTestPattern3[] = { 0x5, 0x6, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 };

    /* Create */
    RTTestISub("Creation");
    PRTCIRCBUF pBuf;
    RTTESTI_CHECK_RC(RTCircBufCreate(&pBuf, 10), VINF_SUCCESS);
    RTTESTI_CHECK(RTCircBufFree(pBuf) == 10);
    RTTESTI_CHECK(RTCircBufUsed(pBuf) == 0);

    /* Full write */
    RTTestISub("Full write");
    RTCircBufAcquireWriteBlock(pBuf, 10, &pvBuf, &cbSize);
    RTTESTI_CHECK(cbSize == 10);
    memcpy(pvBuf, pcTestPattern1, 10);
    RTCircBufReleaseWriteBlock(pBuf, 10);
    RTTESTI_CHECK(RTCircBufFree(pBuf) == 0);
    RTTESTI_CHECK(RTCircBufUsed(pBuf) == 10);
//    RTTESTI_CHECK(memcmp(pBuf->pvBuf, pcTestPattern1, 10) == 0); /* Check the internal state */

    /* Half read */
    RTTestISub("Half read");
    RTCircBufAcquireReadBlock(pBuf, 5, &pvBuf, &cbSize);
    RTTESTI_CHECK(cbSize == 5);
    RTTESTI_CHECK(memcmp(pvBuf, pcTestPattern1, 5) == 0);
    RTCircBufReleaseReadBlock(pBuf, 5);
    RTTESTI_CHECK(RTCircBufFree(pBuf) == 5);
    RTTESTI_CHECK(RTCircBufUsed(pBuf) == 5);

    /* Sub write */
    RTTestISub("Sub write");
    RTCircBufAcquireWriteBlock(pBuf, 2, &pvBuf, &cbSize);
    RTTESTI_CHECK(cbSize == 2);
    memcpy(pvBuf, &pcTestPattern1[8], 2);
    RTCircBufReleaseWriteBlock(pBuf, 2);
    RTTESTI_CHECK(RTCircBufFree(pBuf) == 3);
    RTTESTI_CHECK(RTCircBufUsed(pBuf) == 7);
//    RTTESTI_CHECK(memcmp(pBuf->pvBuf, pcTestPattern2, 10) == 0); /* Check the internal state */

    /* Split tests */
    /* Split read */
    RTTestISub("Split read");
    RTCircBufAcquireReadBlock(pBuf, 7, &pvBuf, &cbSize);
    RTTESTI_CHECK(cbSize == 5);
    RTTESTI_CHECK(memcmp(pvBuf, &pcTestPattern1[5], 5) == 0);
    RTCircBufReleaseReadBlock(pBuf, 5);
    RTTESTI_CHECK(RTCircBufFree(pBuf) == 8);
    RTTESTI_CHECK(RTCircBufUsed(pBuf) == 2);
    RTCircBufAcquireReadBlock(pBuf, 2, &pvBuf, &cbSize);
    RTTESTI_CHECK(cbSize == 2);
    RTTESTI_CHECK(memcmp(pvBuf, &pcTestPattern1[8], 2) == 0);
    RTCircBufReleaseReadBlock(pBuf, 2);
    RTTESTI_CHECK(RTCircBufFree(pBuf) == 10);
    RTTESTI_CHECK(RTCircBufUsed(pBuf) == 0);

    /* Split write */
    RTTestISub("Split write");
    RTCircBufAcquireWriteBlock(pBuf, 10, &pvBuf, &cbSize);
    RTTESTI_CHECK(cbSize == 8);
    memcpy(pvBuf, pcTestPattern1, 8);
    RTCircBufReleaseWriteBlock(pBuf, 8);
    RTTESTI_CHECK(RTCircBufFree(pBuf) == 2);
    RTTESTI_CHECK(RTCircBufUsed(pBuf) == 8);
    RTCircBufAcquireWriteBlock(pBuf, 2, &pvBuf, &cbSize);
    RTTESTI_CHECK(cbSize == 2);
    memcpy(pvBuf, &pcTestPattern1[5], 2);
    RTCircBufReleaseWriteBlock(pBuf, 2);
    RTTESTI_CHECK(RTCircBufFree(pBuf) == 0);
    RTTESTI_CHECK(RTCircBufUsed(pBuf) == 10);
//    RTTESTI_CHECK(memcmp(pBuf->pvBuf, pcTestPattern3, 10) == 0); /* Check the internal state */

    /* Destroy */
    RTCircBufDestroy(pBuf);
}
예제 #3
0
static int shaOpenCallback(void *pvUser, const char *pszLocation, uint32_t fOpen,
                              PFNVDCOMPLETED pfnCompleted, void **ppInt)
{
    /* Validate input. */
    AssertPtrReturn(pvUser, VERR_INVALID_PARAMETER);
    AssertPtrReturn(pszLocation, VERR_INVALID_POINTER);
    AssertPtrNullReturn(pfnCompleted, VERR_INVALID_PARAMETER);
    AssertPtrReturn(ppInt, VERR_INVALID_POINTER);
    AssertReturn((fOpen & RTFILE_O_READWRITE) != RTFILE_O_READWRITE, VERR_INVALID_PARAMETER); /* No read/write allowed */

    PSHASTORAGE pShaStorage = (PSHASTORAGE)pvUser;
    PVDINTERFACEIO pIfIo = VDIfIoGet(pShaStorage->pVDImageIfaces);
    AssertPtrReturn(pIfIo, VERR_INVALID_PARAMETER);

    DEBUG_PRINT_FLOW();

    PSHASTORAGEINTERNAL pInt = (PSHASTORAGEINTERNAL)RTMemAllocZ(sizeof(SHASTORAGEINTERNAL));
    if (!pInt)
        return VERR_NO_MEMORY;

    int rc = VINF_SUCCESS;
    do
    {
        pInt->pfnCompleted = pfnCompleted;
        pInt->pShaStorage  = pShaStorage;
        pInt->fEOF         = false;
        pInt->fOpenMode    = fOpen;
        pInt->u32Status    = STATUS_WAIT;

        /* Circular buffer in the read case. */
        rc = RTCircBufCreate(&pInt->pCircBuf, _1M * 2);
        if (RT_FAILURE(rc))
            break;

        if (fOpen & RTFILE_O_WRITE)
        {
            /* The zero buffer is used for appending empty parts at the end of the
             * file (or our buffer) in setSize or when uOffset in writeSync is
             * increased in steps bigger than a byte. */
            pInt->cbZeroBuf = _1K;
            pInt->pvZeroBuf = RTMemAllocZ(pInt->cbZeroBuf);
            if (!pInt->pvZeroBuf)
            {
                rc = VERR_NO_MEMORY;
                break;
            }
        }

        /* Create an event semaphore to indicate a state change for the worker
         * thread. */
        rc = RTSemEventCreate(&pInt->newStatusEvent);
        if (RT_FAILURE(rc))
            break;
        /* Create an event semaphore to indicate a finished calculation of the
           worker thread. */
        rc = RTSemEventCreate(&pInt->workFinishedEvent);
        if (RT_FAILURE(rc))
            break;
        /* Create the worker thread. */
        rc = RTThreadCreate(&pInt->pWorkerThread, shaCalcWorkerThread, pInt, 0, RTTHREADTYPE_MAIN_HEAVY_WORKER, RTTHREADFLAGS_WAITABLE, "SHA-Worker");
        if (RT_FAILURE(rc))
            break;

        if (pShaStorage->fCreateDigest)
        {
            /* Create a SHA1/SHA256 context the worker thread will work with. */
            if (pShaStorage->fSha256)
                RTSha256Init(&pInt->ctx.Sha256);
            else
                RTSha1Init(&pInt->ctx.Sha1);
        }

        /* Open the file. */
        rc = vdIfIoFileOpen(pIfIo, pszLocation, fOpen, pInt->pfnCompleted,
                            &pInt->pvStorage);
        if (RT_FAILURE(rc))
            break;

        if (fOpen & RTFILE_O_READ)
        {
            /* Immediately let the worker thread start the reading. */
            rc = shaSignalManifestThread(pInt, STATUS_READ);
        }
    }
    while(0);

    if (RT_FAILURE(rc))
    {
        if (pInt->pWorkerThread)
        {
            shaSignalManifestThread(pInt, STATUS_END);
            RTThreadWait(pInt->pWorkerThread, RT_INDEFINITE_WAIT, 0);
        }
        if (pInt->workFinishedEvent)
            RTSemEventDestroy(pInt->workFinishedEvent);
        if (pInt->newStatusEvent)
            RTSemEventDestroy(pInt->newStatusEvent);
        if (pInt->pCircBuf)
            RTCircBufDestroy(pInt->pCircBuf);
        if (pInt->pvZeroBuf)
            RTMemFree(pInt->pvZeroBuf);
        RTMemFree(pInt);
    }
    else
        *ppInt = pInt;

    return rc;
}