Logo Search packages:      
Sourcecode: virtualbox-ose version File versions

HRESULT MediumBase::queryInfo (  )  [protected, virtual]

Queries information from the image file.

As a result of this call, the accessibility state and data members such as size and description will be updated with the current information.

Note:
This method may block during a system I/O call that checks image file accessibility.

Locks this object for writing.

Reimplemented in HardDisk.

Definition at line 729 of file MediumImpl.cpp.

References Assert, AssertRC, AssertReturn, ComAssertRCRet, util::AutoWriteLock::enter(), util::AutoWriteLock::leave(), LogWarningFunc, NIL_RTSEMEVENTMULTI, RT_FAILURE, RT_INDEFINITE_WAIT, RT_SUCCESS, VirtualBoxSupportTranslation< MediumBase >::tr(), and VINF_SUCCESS.

Referenced by ImageMediumBase::protectedInit().

{
    AutoWriteLock alock (this);

    AssertReturn (m.state == MediaState_Created ||
                  m.state == MediaState_Inaccessible ||
                  m.state == MediaState_LockedRead ||
                  m.state == MediaState_LockedWrite,
                  E_FAIL);

    int vrc = VINF_SUCCESS;

    /* check if a blocking queryInfo() call is in progress on some other thread,
     * and wait for it to finish if so instead of querying data ourselves */
    if (m.queryInfoSem != NIL_RTSEMEVENTMULTI)
    {
        Assert (m.state == MediaState_LockedRead);

        ++ m.queryInfoCallers;
        alock.leave();

        vrc = RTSemEventMultiWait (m.queryInfoSem, RT_INDEFINITE_WAIT);

        alock.enter();
        -- m.queryInfoCallers;

        if (m.queryInfoCallers == 0)
        {
            /* last waiting caller deletes the semaphore */
            RTSemEventMultiDestroy (m.queryInfoSem);
            m.queryInfoSem = NIL_RTSEMEVENTMULTI;
        }

        AssertRC (vrc);

        return S_OK;
    }

    /* lazily create a semaphore for possible callers */
    vrc = RTSemEventMultiCreate (&m.queryInfoSem);
    ComAssertRCRet (vrc, E_FAIL);

    bool tempStateSet = false;
    if (m.state != MediaState_LockedRead &&
        m.state != MediaState_LockedWrite)
    {
        /* Cause other methods to prevent any modifications before leaving the
         * lock. Note that clients will never see this temporary state change
         * directly since any COMGETTER(State) is (or will be) blocked until we
         * finish and restore the actual state. This may be seen only through
         * error messages reported by other methods. */
        m.state = MediaState_LockedRead;
        tempStateSet = true;
    }

    /* leave the lock before a blocking operation */
    alock.leave();

    bool success = false;

    /* get image file info */
    {
        RTFILE file;
        vrc = RTFileOpen (&file, Utf8Str (m.locationFull), RTFILE_O_READ);
        if (RT_SUCCESS (vrc))
        {
            vrc = RTFileGetSize (file, &m.size);

            RTFileClose (file);
        }

        if (RT_FAILURE (vrc))
        {
            m.lastAccessError = Utf8StrFmt (
                tr ("Could not access the image file '%ls' (%Rrc)"),
                m.locationFull.raw(), vrc);
        }

        success = (RT_SUCCESS (vrc));
    }

    alock.enter();

    if (success)
        m.lastAccessError.setNull();
    else
        LogWarningFunc (("'%ls' is not accessible (error='%ls', vrc=%Rrc)\n",
                         m.locationFull.raw(), m.lastAccessError.raw(), vrc));

    /* inform other callers if there are any */
    if (m.queryInfoCallers > 0)
    {
        RTSemEventMultiSignal (m.queryInfoSem);
    }
    else
    {
        /* delete the semaphore ourselves */
        RTSemEventMultiDestroy (m.queryInfoSem);
        m.queryInfoSem = NIL_RTSEMEVENTMULTI;
    }

    if (tempStateSet)
    {
        /* Set the proper state according to the result of the check */
        if (success)
            m.state = MediaState_Created;
        else
            m.state = MediaState_Inaccessible;
    }
    else
    {
        /* we're locked, use a special field to store the result */
        m.accessibleInLock = success;
    }

    return S_OK;
}


Generated by  Doxygen 1.6.0   Back to index