int VDIoBackendMemDestroy(PVDIOBACKENDMEM pIoBackend)
{
    ASMAtomicXchgBool(&pIoBackend->fRunning, false);
    vdIoBackendMemThreadPoke(pIoBackend);

    RTThreadWait(pIoBackend->hThreadIo, RT_INDEFINITE_WAIT, NULL);
    RTSemEventDestroy(pIoBackend->EventSem);
    RTCircBufDestroy(pIoBackend->pRequestRing);
    RTMemFree(pIoBackend);

    return VINF_SUCCESS;
}
Example #2
0
/**
 * Block the main thread until the service shuts down.
 */
void VBoxServiceMainWait(void)
{
    int rc;

    VBoxServiceReportStatus(VBoxGuestFacilityStatus_Active);

#ifdef RT_OS_WINDOWS
    /*
     * Wait for the semaphore to be signalled.
     */
    VBoxServiceVerbose(1, "Waiting in main thread\n");
    rc = RTSemEventCreate(&g_hEvtWindowsService);
    AssertRC(rc);
    while (!ASMAtomicReadBool(&g_fWindowsServiceShutdown))
    {
        rc = RTSemEventWait(g_hEvtWindowsService, RT_INDEFINITE_WAIT);
        AssertRC(rc);
    }
    RTSemEventDestroy(g_hEvtWindowsService);
    g_hEvtWindowsService = NIL_RTSEMEVENT;
#else
    /*
     * Wait explicitly for a HUP, INT, QUIT, ABRT or TERM signal, blocking
     * all important signals.
     *
     * The annoying EINTR/ERESTART loop is for the benefit of Solaris where
     * sigwait returns when we receive a SIGCHLD.  Kind of makes sense since
     */
    sigset_t signalMask;
    sigemptyset(&signalMask);
    sigaddset(&signalMask, SIGHUP);
    sigaddset(&signalMask, SIGINT);
    sigaddset(&signalMask, SIGQUIT);
    sigaddset(&signalMask, SIGABRT);
    sigaddset(&signalMask, SIGTERM);
    pthread_sigmask(SIG_BLOCK, &signalMask, NULL);

    int iSignal;
    do
    {
        iSignal = -1;
        rc = sigwait(&signalMask, &iSignal);
    }
    while (   rc == EINTR
# ifdef ERESTART
              || rc == ERESTART
# endif
          );

    VBoxServiceVerbose(3, "VBoxServiceMainWait: Received signal %d (rc=%d)\n", iSignal, rc);
#endif /* !RT_OS_WINDOWS */
}
Example #3
0
/**
 * Stop all service threads and free the device chain.
 */
USBProxyBackendFreeBSD::~USBProxyBackendFreeBSD()
{
    LogFlowThisFunc(("\n"));

    /*
     * Stop the service.
     */
    if (isActive())
        stop();

    RTSemEventDestroy(mNotifyEventSem);
    mNotifyEventSem = NULL;
}
VMMDev::~VMMDev()
{
#ifdef VBOX_WITH_HGCM
    if (hgcmIsActive())
    {
        ASMAtomicWriteBool(&m_fHGCMActive, false);
        HGCMHostShutdown();
    }
#endif /* VBOX_WITH_HGCM */
    RTSemEventDestroy (mCredentialsEvent);
    if (mpDrv)
        mpDrv->pVMMDev = NULL;
    mpDrv = NULL;
}
RTDECL(int) RTFileAioCtxDestroy(RTFILEAIOCTX hAioCtx)
{
    PRTFILEAIOCTXINTERNAL pCtxInt = hAioCtx;

    AssertPtrReturn(pCtxInt, VERR_INVALID_HANDLE);

    if (RT_UNLIKELY(pCtxInt->cRequests))
        return VERR_FILE_AIO_BUSY;

    RTSemEventDestroy(pCtxInt->SemEventCancel);
    RTMemFree(pCtxInt);

    return VINF_SUCCESS;
}
Example #6
0
EventQueue::~EventQueue(void)
{
    int rc = RTCritSectDelete(&mCritSect);
    AssertRC(rc);

    rc = RTSemEventDestroy(mSemEvent);
    AssertRC(rc);

    EventQueueListIterator it  = mEvents.begin();
    while (it != mEvents.end())
    {
        (*it)->Release();
        it = mEvents.erase(it);
    }
}
Example #7
0
int vboxVhwaCommandSubmit(PVBOXMP_DEVEXT pDevExt, VBOXVHWACMD* pCmd)
{
#ifdef VBOXVHWA_WITH_SHGSMI
    const VBOXSHGSMIHEADER* pHdr = VBoxSHGSMICommandPrepSynch(&pDevExt->u.primary.hgsmiAdapterHeap, pCmd);
    Assert(pHdr);
    int rc = VERR_GENERAL_FAILURE;
    if (pHdr)
    {
        do
        {
            HGSMIOFFSET offCmd = VBoxSHGSMICommandOffset(&pDevExt->u.primary.hgsmiAdapterHeap, pHdr);
            Assert(offCmd != HGSMIOFFSET_VOID);
            if (offCmd != HGSMIOFFSET_VOID)
            {
                rc = vboxVhwaCommandSubmitHgsmi(pDevExt, offCmd);
                AssertRC(rc);
                if (RT_SUCCESS(rc))
                {
                    VBoxSHGSMICommandDoneSynch(&pDevExt->u.primary.hgsmiAdapterHeap, pHdr);
                    AssertRC(rc);
                    break;
                }
            }
            else
                rc = VERR_INVALID_PARAMETER;
            /* fail to submit, cancel it */
            VBoxSHGSMICommandCancelSynch(&pDevExt->u.primary.hgsmiAdapterHeap, pHdr);
        } while (0);
    }
    else
        rc = VERR_INVALID_PARAMETER;
    return rc;
#else
    RTSEMEVENT hEvent;
    int rc = RTSemEventCreate(&hEvent);
    AssertRC(rc);
    if (RT_SUCCESS(rc))
    {
        pCmd->Flags |= VBOXVHWACMD_FLAG_GH_ASYNCH_IRQ;
        vboxVhwaCommandSubmitAsynchByEvent(pDevExt, pCmd, hEvent);
        rc = RTSemEventWait(hEvent, RT_INDEFINITE_WAIT);
        AssertRC(rc);
        if (RT_SUCCESS(rc))
            RTSemEventDestroy(hEvent);
    }
    return rc;
#endif
}
Example #8
0
UIDnDDataObject::~UIDnDDataObject(void)
{
    if (m_pFormatEtc)
        delete[] m_pFormatEtc;

    if (m_pStgMedium)
        delete[] m_pStgMedium;

    if (m_pvData)
        RTMemFree(m_pvData);

    if (m_SemEvent != NIL_RTSEMEVENT)
        RTSemEventDestroy(m_SemEvent);

    LogFlowFunc(("mRefCount=%RI32\n", m_cRefs));
}
static void vboxNetAdpSlotDestroy(PVBOXNETADP pThis)
{
    Assert(pThis->cRefs == 0);
    Assert(pThis->cBusy == 0);
    Assert(vboxNetAdpGetState(pThis) == kVBoxNetAdpState_Invalid);
    if (pThis->hEventIdle != NIL_RTSEMEVENT)
    {
        RTSemEventDestroy(pThis->hEventIdle);
        pThis->hEventIdle = NIL_RTSEMEVENT;
    }
    if (pThis->hSpinlock != NIL_RTSPINLOCK)
    {
        RTSpinlockDestroy(pThis->hSpinlock);
        pThis->hSpinlock = NIL_RTSPINLOCK;
    }
}
Example #10
0
/**
 * Re-initializes a request when it's being recycled.
 *
 * @returns IRPT status code, the request is freed on failure.
 * @param   pReq                The request.
 * @param   enmType             The request type.
 */
DECLHIDDEN(int) rtReqReInit(PRTREQINT pReq, RTREQTYPE enmType)
{
    Assert(pReq->u32Magic == RTREQ_MAGIC);
    Assert(pReq->enmType  == RTREQTYPE_INVALID);
    Assert(pReq->enmState == RTREQSTATE_FREE);
    Assert(pReq->cRefs    == 0);

    /*
     * Make sure the event sem is not signaled.
     */
    if (!pReq->fEventSemClear)
    {
        int rc = RTSemEventWait(pReq->EventSem, 0);
        if (rc != VINF_SUCCESS && rc != VERR_TIMEOUT)
        {
            /*
             * This shall not happen, but if it does we'll just destroy
             * the semaphore and create a new one.
             */
            AssertMsgFailed(("rc=%Rrc from RTSemEventWait(%#x).\n", rc, pReq->EventSem));
            RTSemEventDestroy(pReq->EventSem);
            rc = RTSemEventCreate(&pReq->EventSem);
            if (RT_FAILURE(rc))
            {
                AssertRC(rc);
                pReq->EventSem = NIL_RTSEMEVENT;
                rtReqFreeIt(pReq);
                return rc;
            }
        }
        pReq->fEventSemClear = true;
    }
    else
        Assert(RTSemEventWait(pReq->EventSem, 0) == VERR_TIMEOUT);

    /*
     * Initialize the packet and return it.
     */
    ASMAtomicWriteNullPtr(&pReq->pNext);
    pReq->iStatusX = VERR_RT_REQUEST_STATUS_STILL_PENDING;
    pReq->enmState = RTREQSTATE_ALLOCATED;
    pReq->fFlags   = RTREQFLAGS_IPRT_STATUS;
    pReq->enmType  = enmType;
    pReq->cRefs    = 1;
    return VINF_SUCCESS;
}
/**
 * Initializes the VirtualBoxClient object.
 *
 * @returns COM result indicator
 */
HRESULT VirtualBoxClient::init()
{
    LogFlowThisFunc(("\n"));

    HRESULT rc;
    /* Enclose the state transition NotReady->InInit->Ready */
    AutoInitSpan autoInitSpan(this);
    AssertReturn(autoInitSpan.isOk(), E_FAIL);

    mData.m_ThreadWatcher = NIL_RTTHREAD;
    mData.m_SemEvWatcher = NIL_RTSEMEVENT;

    if (ASMAtomicIncU32(&g_cInstances) != 1)
        AssertFailedReturn(E_FAIL);

    rc = mData.m_pVirtualBox.createLocalObject(CLSID_VirtualBox);
    AssertComRCReturnRC(rc);

    rc = unconst(mData.m_pEventSource).createObject();
    AssertComRCReturnRC(rc);
    rc = mData.m_pEventSource->init(static_cast<IVirtualBoxClient *>(this));
    AssertComRCReturnRC(rc);

    /* Setting up the VBoxSVC watcher thread. If anything goes wrong here it
     * is not considered important enough to cause any sort of visible
     * failure. The monitoring will not be done, but that's all. */
    int vrc = RTSemEventCreate(&mData.m_SemEvWatcher);
    AssertRC(vrc);
    if (RT_SUCCESS(vrc))
    {
        vrc = RTThreadCreate(&mData.m_ThreadWatcher, SVCWatcherThread,
                             this, 0, RTTHREADTYPE_INFREQUENT_POLLER,
                             RTTHREADFLAGS_WAITABLE, "VBoxSVCWatcher");
        AssertRC(vrc);
    }
    else
    {
        RTSemEventDestroy(mData.m_SemEvWatcher);
        mData.m_SemEvWatcher = NIL_RTSEMEVENT;
    }

    /* Confirm a successful initialization */
    autoInitSpan.setSucceeded();

    return rc;
}
Example #12
0
/**
 * Init a Ping-Pong construct.
 *
 * @returns iprt status code.
 * @param   pPP         Pointer to the ping-pong structure which needs initialization.
 */
RTDECL(int) RTSemPingPongInit(PRTPINGPONG pPP)
{
    /*
     * Init the structure.
     */
    pPP->enmSpeaker = RTPINGPONGSPEAKER_PING;

    int rc = RTSemEventCreate(&pPP->Ping);
    if (RT_SUCCESS(rc))
    {
        rc = RTSemEventCreate(&pPP->Pong);
        if (RT_SUCCESS(rc))
            return VINF_SUCCESS;
        RTSemEventDestroy(pPP->Ping);
    }

    return rc;
}
Example #13
0
HostDnsServiceDarwin::~HostDnsServiceDarwin()
{
    if (!m)
        return;

    monitorThreadShutdown();

    CFRelease(m->m_RunLoopRef);

    CFRelease(m->m_DnsWatcher);

    CFRelease(m->m_store);

    RTSemEventDestroy(m->m_evtStop);

    delete m;
    m = NULL;
}
/**
 * Destruct a char driver instance.
 *
 * Most VM resources are freed by the VM. This callback is provided so that
 * any non-VM resources can be freed correctly.
 *
 * @param   pDrvIns     The driver instance data.
 */
static DECLCALLBACK(void) drvCharDestruct(PPDMDRVINS pDrvIns)
{
    PDRVCHAR pThis = PDMINS_2_DATA(pDrvIns, PDRVCHAR);
    LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);

    /*
     * Tell the threads to shut down.
     */
    pThis->fShutdown = true;
    if (pThis->SendSem != NIL_RTSEMEVENT)
    {
        RTSemEventSignal(pThis->SendSem);
        pThis->SendSem = NIL_RTSEMEVENT;
    }

    /*
     * Wait for the threads.
     * ASSUMES that PDM destroys the driver chain from the bottom and up.
     */
    if (pThis->ReceiveThread != NIL_RTTHREAD)
    {
        int rc = RTThreadWait(pThis->ReceiveThread, 30000, NULL);
        if (RT_SUCCESS(rc))
            pThis->ReceiveThread = NIL_RTTHREAD;
        else
            LogRel(("Char%d: receive thread did not terminate (%Rrc)\n", pDrvIns->iInstance, rc));
    }

    if (pThis->SendThread != NIL_RTTHREAD)
    {
        int rc = RTThreadWait(pThis->SendThread, 30000, NULL);
        if (RT_SUCCESS(rc))
            pThis->SendThread = NIL_RTTHREAD;
        else
            LogRel(("Char%d: send thread did not terminate (%Rrc)\n", pDrvIns->iInstance, rc));
    }

    if (pThis->SendSem != NIL_RTSEMEVENT)
    {
        RTSemEventDestroy(pThis->SendSem);
        pThis->SendSem = NIL_RTSEMEVENT;
    }
}
/**
 * performs "base" globals deinitialization
 * we separate the globals settings "base" which is actually
 * "general" globals settings except for Idc, and idc.
 * This is needed for windows filter driver, which gets loaded prior to VBoxDrv,
 * thus it's not possible to make idc initialization from the driver startup routine for it,
 * though the "base is still needed for the driver to functions".
 * @param pGlobals
 * @return none
 */
DECLHIDDEN(void) vboxNetAdpDeleteGlobalsBase(PVBOXNETADPGLOBALS pGlobals)
{
    int i;
    /*
     * Release resources.
     */
    for (i = 0; i < (int)RT_ELEMENTS(pGlobals->aAdapters); i++)
        if (RT_SUCCESS(vboxNetAdpDestroy(&pGlobals->aAdapters[i])))
            vboxNetAdpSlotDestroy(&pGlobals->aAdapters[i]);

    RTSemFastMutexDestroy(pGlobals->hFastMtx);
    pGlobals->hFastMtx = NIL_RTSEMFASTMUTEX;

#ifdef VBOXNETADP_STATIC_CONFIG
    RTSemEventDestroy(pGlobals->hTimerEvent);
    pGlobals->hTimerEvent = NIL_RTSEMEVENT;
#endif

}
static int vboxNetAdpSlotCreate(PVBOXNETADPGLOBALS pGlobals, unsigned uUnit, PVBOXNETADP pNew)
{
    int rc;

    pNew->MyPort.u32Version             = INTNETTRUNKIFPORT_VERSION;
    pNew->MyPort.pfnRetain              = vboxNetAdpPortRetain;
    pNew->MyPort.pfnRelease             = vboxNetAdpPortRelease;
    pNew->MyPort.pfnDisconnectAndRelease= vboxNetAdpPortDisconnectAndRelease;
    pNew->MyPort.pfnSetState            = vboxNetAdpPortSetState;
    pNew->MyPort.pfnWaitForIdle         = vboxNetAdpPortWaitForIdle;
    pNew->MyPort.pfnXmit                = vboxNetAdpPortXmit;
    pNew->MyPort.u32VersionEnd          = INTNETTRUNKIFPORT_VERSION;
    pNew->pSwitchPort                   = NULL;
    pNew->pGlobals                      = pGlobals;
    pNew->hSpinlock                     = NIL_RTSPINLOCK;
    pNew->enmState                      = kVBoxNetAdpState_Invalid;
    pNew->cRefs                         = 0;
    pNew->cBusy                         = 0;
    pNew->hEventIdle                    = NIL_RTSEMEVENT;

    rc = RTSpinlockCreate(&pNew->hSpinlock);
    if (RT_SUCCESS(rc))
    {
        rc = RTSemEventCreate(&pNew->hEventIdle);
        if (RT_SUCCESS(rc))
        {
            rc = vboxNetAdpOsInit(pNew);
            if (RT_SUCCESS(rc))
            {
                return rc;
            }
            RTSemEventDestroy(pNew->hEventIdle);
            pNew->hEventIdle = NIL_RTSEMEVENT;
        }
        RTSpinlockDestroy(pNew->hSpinlock);
        pNew->hSpinlock = NIL_RTSPINLOCK;
    }
    return rc;
}
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;
}
VBoxDbgConsole::~VBoxDbgConsole()
{
    Assert(isGUIThread());

    /*
     * Wait for the thread.
     */
    ASMAtomicWriteBool(&m_fTerminate, true);
    RTSemEventSignal(m_EventSem);
    if (m_Thread != NIL_RTTHREAD)
    {
        int rc = RTThreadWait(m_Thread, 15000, NULL);
        AssertRC(rc);
        m_Thread = NIL_RTTHREAD;
    }

    /*
     * Free resources.
     */
    delete m_pTimer;
    m_pTimer = NULL;
    RTCritSectDelete(&m_Lock);
    RTSemEventDestroy(m_EventSem);
    m_EventSem = 0;
    m_pOutput = NULL;
    m_pInput = NULL;
    if (m_pszInputBuf)
    {
        RTMemFree(m_pszInputBuf);
        m_pszInputBuf = NULL;
    }
    m_cbInputBuf = 0;
    m_cbInputBufAlloc = 0;

    delete m_pFocusToInput;
    m_pFocusToInput = NULL;
    delete m_pFocusToOutput;
    m_pFocusToOutput = NULL;
}
/**
 * Stop all service threads and free the device chain.
 */
USBProxyServiceSolaris::~USBProxyServiceSolaris()
{
    LogFlowThisFunc(("destruct\n"));

    /*
     * Stop the service.
     */
    if (isActive())
        stop();

    /*
     * Terminate the USB library
     */
    if (mUSBLibInitialized)
    {
        USBLibTerm();
        mUSBLibInitialized = false;
    }

    RTSemEventDestroy(mNotifyEventSem);
    mNotifyEventSem = NULL;
}
int vboxNetAdpOsCreate(PVBOXNETADP pThis, PCRTMAC pMACAddress)
{
    int rc;
    struct ifnet_init_params Params;
    RTUUID uuid;
    struct sockaddr_dl mac;

    pThis->u.s.hEvtDetached = NIL_RTSEMEVENT;
    rc = RTSemEventCreate(&pThis->u.s.hEvtDetached);
    if (RT_FAILURE(rc))
    {
        printf("vboxNetAdpOsCreate: failed to create semaphore (rc=%d).\n", rc);
        return rc;
    }

    pThis->u.s.nTapMode = BPF_MODE_DISABLED;

    mac.sdl_len = sizeof(mac);
    mac.sdl_family = AF_LINK;
    mac.sdl_alen = ETHER_ADDR_LEN;
    mac.sdl_nlen = 0;
    mac.sdl_slen = 0;
    memcpy(LLADDR(&mac), pMACAddress->au8, mac.sdl_alen);

    RTStrPrintf(pThis->szName, VBOXNETADP_MAX_NAME_LEN, "%s%d", VBOXNETADP_NAME, pThis->iUnit);
    vboxNetAdpDarwinComposeUUID(pThis, &uuid);
    Params.uniqueid = uuid.au8;
    Params.uniqueid_len = sizeof(uuid);
    Params.name = VBOXNETADP_NAME;
    Params.unit = pThis->iUnit;
    Params.family = IFNET_FAMILY_ETHERNET;
    Params.type = IFT_ETHER;
    Params.output = vboxNetAdpDarwinOutput;
    Params.demux = vboxNetAdpDarwinDemux;
    Params.add_proto = vboxNetAdpDarwinAddProto;
    Params.del_proto = vboxNetAdpDarwinDelProto;
    Params.check_multi = ether_check_multi;
    Params.framer = ether_frameout;
    Params.softc = pThis;
    Params.ioctl = (ifnet_ioctl_func)ether_ioctl;
    Params.set_bpf_tap = NULL;
    Params.detach = vboxNetAdpDarwinDetach;
    Params.event = NULL;
    Params.broadcast_addr = "\xFF\xFF\xFF\xFF\xFF\xFF";
    Params.broadcast_len = ETHER_ADDR_LEN;

    errno_t err = ifnet_allocate(&Params, &pThis->u.s.pIface);
    if (!err)
    {
        err = ifnet_attach(pThis->u.s.pIface, &mac);
        if (!err)
        {
            err = bpf_attach(pThis->u.s.pIface, DLT_EN10MB, ETHER_HDR_LEN,
                      vboxNetAdpDarwinBpfSend, vboxNetAdpDarwinBpfTap);
            if (err)
            {
                LogRel(("vboxnetadp: bpf_attach failed with %d\n", err));
            }
            err = ifnet_set_flags(pThis->u.s.pIface, IFF_RUNNING | IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST, 0xFFFF);
            if (!err)
            {
                ifnet_set_mtu(pThis->u.s.pIface, VBOXNETADP_MTU);
                return VINF_SUCCESS;
            }
            else
                Log(("vboxNetAdpDarwinRegisterDevice: Failed to set flags (err=%d).\n", err));
            ifnet_detach(pThis->u.s.pIface);
        }
        else
            Log(("vboxNetAdpDarwinRegisterDevice: Failed to attach to interface (err=%d).\n", err));
        ifnet_release(pThis->u.s.pIface);
    }
    else
        Log(("vboxNetAdpDarwinRegisterDevice: Failed to allocate interface (err=%d).\n", err));

    RTSemEventDestroy(pThis->u.s.hEvtDetached);
    pThis->u.s.hEvtDetached = NIL_RTSEMEVENT;

    return RTErrConvertFromErrno(err);
}
Example #21
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;
}
GuestDnDCallbackEvent::~GuestDnDCallbackEvent(void)
{
    if (NIL_RTSEMEVENT != mSemEvent)
        RTSemEventDestroy(mSemEvent);
}
Example #23
0
RTDECL(int) RTSemRWCreateEx(PRTSEMRW phRWSem, uint32_t fFlags,
                            RTLOCKVALCLASS hClass, uint32_t uSubClass, const char *pszNameFmt, ...)
{
    AssertReturn(!(fFlags & ~RTSEMRW_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER);

    /*
     * Allocate memory.
     */
    int rc;
    struct RTSEMRWINTERNAL *pThis = (struct RTSEMRWINTERNAL *)RTMemAlloc(sizeof(struct RTSEMRWINTERNAL));
    if (pThis)
    {
        /*
         * Create the semaphores.
         */
        rc = RTSemEventCreateEx(&pThis->WriteEvent, RTSEMEVENT_FLAGS_NO_LOCK_VAL, NIL_RTLOCKVALCLASS, NULL);
        if (RT_SUCCESS(rc))
        {
            rc = RTSemEventMultiCreateEx(&pThis->ReadEvent, RTSEMEVENT_FLAGS_NO_LOCK_VAL, NIL_RTLOCKVALCLASS, NULL);
            if (RT_SUCCESS(rc))
            {
                rc = RTCritSectInitEx(&pThis->CritSect, RTCRITSECT_FLAGS_NO_LOCK_VAL,
                                      NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
                if (RT_SUCCESS(rc))
                {
                    /*
                     * Signal the read semaphore and initialize other variables.
                     */
                    rc = RTSemEventMultiSignal(pThis->ReadEvent);
                    if (RT_SUCCESS(rc))
                    {
                        pThis->u32Padding           = UINT32_C(0xa5a55a5a);
                        pThis->cReads               = 0;
                        pThis->cWrites              = 0;
                        pThis->cWriterReads         = 0;
                        pThis->cWritesWaiting       = 0;
                        pThis->hWriter              = NIL_RTNATIVETHREAD;
                        pThis->fNeedResetReadEvent  = true;
                        pThis->u32Magic             = RTSEMRW_MAGIC;
#ifdef RTSEMRW_STRICT
                        bool const fLVEnabled = !(fFlags & RTSEMRW_FLAGS_NO_LOCK_VAL);
                        if (!pszNameFmt)
                        {
                            static uint32_t volatile s_iSemRWAnon = 0;
                            uint32_t i = ASMAtomicIncU32(&s_iSemRWAnon) - 1;
                            RTLockValidatorRecExclInit(&pThis->ValidatorWrite, hClass, uSubClass, pThis,
                                                       fLVEnabled, "RTSemRW-%u", i);
                            RTLockValidatorRecSharedInit(&pThis->ValidatorRead, hClass, uSubClass, pThis,
                                                         false /*fSignaller*/, fLVEnabled, "RTSemRW-%u", i);
                        }
                        else
                        {
                            va_list va;
                            va_start(va, pszNameFmt);
                            RTLockValidatorRecExclInitV(&pThis->ValidatorWrite, hClass, uSubClass, pThis,
                                                        fLVEnabled, pszNameFmt, va);
                            va_end(va);
                            va_start(va, pszNameFmt);
                            RTLockValidatorRecSharedInitV(&pThis->ValidatorRead, hClass, uSubClass, pThis,
                                                          false /*fSignaller*/, fLVEnabled, pszNameFmt, va);
                            va_end(va);
                        }
                        RTLockValidatorRecMakeSiblings(&pThis->ValidatorWrite.Core, &pThis->ValidatorRead.Core);
#endif
                        *phRWSem = pThis;
                        return VINF_SUCCESS;
                    }
                    RTCritSectDelete(&pThis->CritSect);
                }
                RTSemEventMultiDestroy(pThis->ReadEvent);
            }
            RTSemEventDestroy(pThis->WriteEvent);
        }
        RTMemFree(pThis);
    }
    else
        rc = VERR_NO_MEMORY;

    return rc;
}
Example #24
0
/**
 * Destructor for objects created by SUPSemEventCreate.
 *
 * @param   pvObj               The object handle.
 * @param   pvUser1             The IPRT event handle.
 * @param   pvUser2             NULL.
 */
static DECLCALLBACK(void) supR0SemEventDestructor(void *pvObj, void *pvUser1, void *pvUser2)
{
    Assert(pvUser2 == NULL);
    NOREF(pvObj);
    RTSemEventDestroy((RTSEMEVENT)pvUser1);
}
Example #25
0
RTDECL(int) RTSemRWDestroy(RTSEMRW hRWSem)
{
    struct RTSEMRWINTERNAL *pThis = hRWSem;

    /*
     * Validate handle.
     */
    if (pThis == NIL_RTSEMRW)
        return VINF_SUCCESS;
    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE);

    /*
     * Check if busy.
     */
    int rc = RTCritSectTryEnter(&pThis->CritSect);
    if (RT_SUCCESS(rc))
    {
        if (!pThis->cReads && !pThis->cWrites)
        {
            /*
             * Make it invalid and unusable.
             */
            ASMAtomicWriteU32(&pThis->u32Magic, ~RTSEMRW_MAGIC);
            pThis->cReads = ~0;

            /*
             * Do actual cleanup. None of these can now fail.
             */
            rc = RTSemEventMultiDestroy(pThis->ReadEvent);
            AssertMsgRC(rc, ("RTSemEventMultiDestroy failed! rc=%Rrc\n", rc));
            pThis->ReadEvent = NIL_RTSEMEVENTMULTI;

            rc = RTSemEventDestroy(pThis->WriteEvent);
            AssertMsgRC(rc, ("RTSemEventDestroy failed! rc=%Rrc\n", rc));
            pThis->WriteEvent = NIL_RTSEMEVENT;

            RTCritSectLeave(&pThis->CritSect);
            rc = RTCritSectDelete(&pThis->CritSect);
            AssertMsgRC(rc, ("RTCritSectDelete failed! rc=%Rrc\n", rc));

#ifdef RTSEMRW_STRICT
            RTLockValidatorRecSharedDelete(&pThis->ValidatorRead);
            RTLockValidatorRecExclDelete(&pThis->ValidatorWrite);
#endif
            RTMemFree(pThis);
            rc = VINF_SUCCESS;
        }
        else
        {
            rc = VERR_SEM_BUSY;
            RTCritSectLeave(&pThis->CritSect);
        }
    }
    else
    {
        AssertMsgRC(rc, ("RTCritSectTryEnter failed! rc=%Rrc\n", rc));
        rc = VERR_SEM_BUSY;
    }

    return rc;
}
Example #26
0
/**
 * Creates a new async I/O manager.
 *
 * @returns VBox status code.
 * @param   pEpClass    Pointer to the endpoint class data.
 * @param   ppAioMgr    Where to store the pointer to the new async I/O manager on success.
 * @param   enmMgrType  Wanted manager type - can be overwritten by the global override.
 */
int pdmacFileAioMgrCreate(PPDMASYNCCOMPLETIONEPCLASSFILE pEpClass, PPPDMACEPFILEMGR ppAioMgr,
                          PDMACEPFILEMGRTYPE enmMgrType)
{
    LogFlowFunc((": Entered\n"));

    PPDMACEPFILEMGR pAioMgrNew;
    int rc = MMR3HeapAllocZEx(pEpClass->Core.pVM, MM_TAG_PDM_ASYNC_COMPLETION, sizeof(PDMACEPFILEMGR), (void **)&pAioMgrNew);
    if (RT_SUCCESS(rc))
    {
        if (enmMgrType < pEpClass->enmMgrTypeOverride)
            pAioMgrNew->enmMgrType = enmMgrType;
        else
            pAioMgrNew->enmMgrType = pEpClass->enmMgrTypeOverride;

        pAioMgrNew->msBwLimitExpired = RT_INDEFINITE_WAIT;

        rc = RTSemEventCreate(&pAioMgrNew->EventSem);
        if (RT_SUCCESS(rc))
        {
            rc = RTSemEventCreate(&pAioMgrNew->EventSemBlock);
            if (RT_SUCCESS(rc))
            {
                rc = RTCritSectInit(&pAioMgrNew->CritSectBlockingEvent);
                if (RT_SUCCESS(rc))
                {
                    /* Init the rest of the manager. */
                    if (pAioMgrNew->enmMgrType != PDMACEPFILEMGRTYPE_SIMPLE)
                        rc = pdmacFileAioMgrNormalInit(pAioMgrNew);

                    if (RT_SUCCESS(rc))
                    {
                        pAioMgrNew->enmState = PDMACEPFILEMGRSTATE_RUNNING;

                        rc = RTThreadCreateF(&pAioMgrNew->Thread,
                                             pAioMgrNew->enmMgrType == PDMACEPFILEMGRTYPE_SIMPLE
                                             ? pdmacFileAioMgrFailsafe
                                             : pdmacFileAioMgrNormal,
                                             pAioMgrNew,
                                             0,
                                             RTTHREADTYPE_IO,
                                             0,
                                             "AioMgr%d-%s", pEpClass->cAioMgrs,
                                             pAioMgrNew->enmMgrType == PDMACEPFILEMGRTYPE_SIMPLE
                                             ? "F"
                                             : "N");
                        if (RT_SUCCESS(rc))
                        {
                            /* Link it into the list. */
                            RTCritSectEnter(&pEpClass->CritSect);
                            pAioMgrNew->pNext = pEpClass->pAioMgrHead;
                            if (pEpClass->pAioMgrHead)
                                pEpClass->pAioMgrHead->pPrev = pAioMgrNew;
                            pEpClass->pAioMgrHead = pAioMgrNew;
                            pEpClass->cAioMgrs++;
                            RTCritSectLeave(&pEpClass->CritSect);

                            *ppAioMgr = pAioMgrNew;

                            Log(("PDMAC: Successfully created new file AIO Mgr {%s}\n", RTThreadGetName(pAioMgrNew->Thread)));
                            return VINF_SUCCESS;
                        }
                        pdmacFileAioMgrNormalDestroy(pAioMgrNew);
                    }
                    RTCritSectDelete(&pAioMgrNew->CritSectBlockingEvent);
                }
                RTSemEventDestroy(pAioMgrNew->EventSem);
            }
            RTSemEventDestroy(pAioMgrNew->EventSemBlock);
        }
        MMR3HeapFree(pAioMgrNew);
    }

    LogFlowFunc((": Leave rc=%Rrc\n", rc));

    return rc;
}
Example #27
0
/**
 * Destroy a (binary) semaphore.
 */
void sys_sem_free(sys_sem_t sem)
{
    int rc;
    rc = RTSemEventDestroy(sem);
    AssertRC(rc);
}
Example #28
0
static int shaCloseCallback(void *pvUser, void *pvStorage)
{
    /* Validate input. */
    AssertPtrReturn(pvUser, VERR_INVALID_POINTER);
    AssertPtrReturn(pvStorage, VERR_INVALID_POINTER);

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

    PSHASTORAGEINTERNAL pInt = (PSHASTORAGEINTERNAL)pvStorage;

    DEBUG_PRINT_FLOW();

    int rc = VINF_SUCCESS;

    /* Make sure all pending writes are flushed */
    rc = shaFlushCurBuf(pInt);

    if (pInt->pWorkerThread)
    {
        /* Signal the worker thread to end himself */
        rc = shaSignalManifestThread(pInt, STATUS_END);
        /* Worker thread stopped? */
        rc = RTThreadWait(pInt->pWorkerThread, RT_INDEFINITE_WAIT, 0);
    }

    if (   RT_SUCCESS(rc)
        && pShaStorage->fCreateDigest)
    {
        /* Finally calculate & format the SHA1/SHA256 sum */
        unsigned char auchDig[RTSHA256_HASH_SIZE];
        char *pszDigest;
        size_t cbDigest;
        if (pShaStorage->fSha256)
        {
            RTSha256Final(&pInt->ctx.Sha256, auchDig);
            cbDigest = RTSHA256_DIGEST_LEN;
        }
        else
        {
            RTSha1Final(&pInt->ctx.Sha1, auchDig);
            cbDigest = RTSHA1_DIGEST_LEN;
        }
        rc = RTStrAllocEx(&pszDigest, cbDigest + 1);
        if (RT_SUCCESS(rc))
        {
            if (pShaStorage->fSha256)
                rc = RTSha256ToString(auchDig, pszDigest, cbDigest + 1);
            else
                rc = RTSha1ToString(auchDig, pszDigest, cbDigest + 1);
            if (RT_SUCCESS(rc))
                pShaStorage->strDigest = pszDigest;
            RTStrFree(pszDigest);
        }
    }

    /* Close the file */
    rc = vdIfIoFileClose(pIfIo, pInt->pvStorage);

//    RTPrintf("%lu %lu\n", pInt->calls, pInt->waits);

    /* Cleanup */
    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);

    return rc;
}