VirtualBox

Changeset 8055 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Apr 16, 2008 5:50:24 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
29733
Message:

Main/Settigs: Redone semi-faulty r29679: When reading from settings files, reopen them instead of reusing the existing hande to allow for concurrent multithreaded reads. Provided libxml2/libxslt reentrance (using global serialization) when parsing settings files.

Location:
trunk/src/VBox/Main
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/MachineImpl.cpp

    r8029 r8055  
    20132013    CheckComRCReturnRC (autoCaller.rc());
    20142014
     2015    /* serialize file access (prevent writes) */
    20152016    AutoReaderLock alock (this);
    20162017
     
    20312032        using namespace settings;
    20322033
    2033         /* load the config file */
    2034         File file (File::ReadWrite, mData->mHandleCfgFile,
    2035                   Utf8Str (mData->mConfigFileFull));
     2034        /* load the settings file (we don't reuse the existing handle but
     2035         * request a new one to allow for concurrent multithreaded reads) */
     2036        File file (File::Mode_Read, Utf8Str (mData->mConfigFileFull));
    20362037        XmlTreeBackend tree;
    20372038
     
    21172118    CheckComRCReturnRC (autoCaller.rc());
    21182119
     2120    /* serialize file access (prevent writes) */
    21192121    AutoReaderLock alock (this);
    21202122
     
    21332135        using namespace settings;
    21342136
    2135         /* load the config file */
    2136         File file (File::ReadWrite, mData->mHandleCfgFile,
    2137                   Utf8Str (mData->mConfigFileFull));
     2137        /* load the settings file (we don't reuse the existing handle but
     2138         * request a new one to allow for concurrent multithreaded reads) */
     2139        File file (File::Mode_Read, Utf8Str (mData->mConfigFileFull));
    21382140        XmlTreeBackend tree;
    21392141
     
    21822184
    21832185    /* VirtualBox::onExtraDataCanChange() and saveSettings() need mParent
    2184      * lock (saveSettings() needs a write one) */
     2186     * lock (saveSettings() needs a write one). This object's write lock is
     2187     * also necessary to serialize file access (prevent concurrent reads and
     2188     * writes). */
    21852189    AutoMultiWriteLock2 alock (mParent, this);
    21862190
     
    22062210        using namespace settings;
    22072211
    2208         /* load the config file */
    2209         File file (File::ReadWrite, mData->mHandleCfgFile,
    2210                    Utf8Str (mData->mConfigFileFull));
     2212        /* load the settings file */
     2213        File file (mData->mHandleCfgFile, Utf8Str (mData->mConfigFileFull));
    22112214        XmlTreeBackend tree;
    22122215
     
    40054008        using namespace settings;
    40064009
    4007         File file (File::Read, mData->mHandleCfgFile,
    4008                   Utf8Str (mData->mConfigFileFull));
     4010        /* no concurrent file access is possible in init() so open by handle */
     4011        File file (mData->mHandleCfgFile, Utf8Str (mData->mConfigFileFull));
    40094012        XmlTreeBackend tree;
    40104013
     
    51415144        using namespace settings;
    51425145
    5143         File file (File::ReadWrite, mData->mHandleCfgFile,
    5144                   Utf8Str (mData->mConfigFileFull));
     5146        /* this object is locked for writing to prevent concurrent reads and writes */
     5147        File file (mData->mHandleCfgFile, Utf8Str (mData->mConfigFileFull));
    51455148        XmlTreeBackend tree;
    51465149
     
    53375340    AssertReturn (mType == IsMachine || mType == IsSessionMachine, E_FAIL);
    53385341
     5342    /* This object's write lock is also necessary to serialize file access
     5343     * (prevent concurrent reads and writes) */
    53395344    AutoLock alock (this);
    53405345
     
    53475352        using namespace settings;
    53485353
    5349         /* load the config file */
    5350         File file (File::ReadWrite, mData->mHandleCfgFile,
    5351                    Utf8Str (mData->mConfigFileFull));
     5354        /* load the settings file */
     5355        File file (mData->mHandleCfgFile, Utf8Str (mData->mConfigFileFull));
    53525356        XmlTreeBackend tree;
    53535357
     
    59145918    AssertComRCReturn (autoCaller.rc(), autoCaller.rc());
    59155919
     5920    /* This object's write lock is also necessary to serialize file access
     5921     * (prevent concurrent reads and writes) */
    59165922    AutoLock alock (this);
    59175923
     
    59245930        using namespace settings;
    59255931
    5926         /* load the config file */
    5927         File file (File::ReadWrite, mData->mHandleCfgFile,
    5928                    Utf8Str (mData->mConfigFileFull));
     5932        /* load the settings file */
     5933        File file (mData->mHandleCfgFile, Utf8Str (mData->mConfigFileFull));
    59295934        XmlTreeBackend tree;
    59305935
  • trunk/src/VBox/Main/VirtualBoxImpl.cpp

    r8029 r8055  
    206206            using namespace settings;
    207207
    208             File file (File::ReadWrite, mData.mCfgFile.mHandle, vboxConfigFile);
     208            /* no concurrent file access is possible in init() so open by handle */
     209            File file (mData.mCfgFile.mHandle, vboxConfigFile);
    209210            XmlTreeBackend tree;
    210211
     
    17011702    HRESULT rc = S_OK;
    17021703
    1703     /* serialize config file access */
     1704    /* serialize file access (prevent writes) */
    17041705    AutoReaderLock alock (this);
    17051706
     
    17081709        using namespace settings;
    17091710
    1710         /* load the config file */
    1711         File file (File::ReadWrite, mData.mCfgFile.mHandle,
    1712                   Utf8Str (mData.mCfgFile.mName));
     1711        /* load the settings file (we don't reuse the existing handle but
     1712         * request a new one to allow for concurrent multithreaded reads) */
     1713        File file (File::Mode_Read, Utf8Str (mData.mCfgFile.mName));
    17131714        XmlTreeBackend tree;
    17141715
     
    17991800    HRESULT rc = S_OK;
    18001801
    1801     /* serialize file access */
     1802    /* serialize file access (prevent writes) */
    18021803    AutoReaderLock alock (this);
    18031804
     
    18061807        using namespace settings;
    18071808
    1808         /* load the config file */
    1809         File file (File::ReadWrite, mData.mCfgFile.mHandle,
    1810                   Utf8Str (mData.mCfgFile.mName));
     1809        /* load the settings file (we don't reuse the existing handle but
     1810         * request a new one to allow for concurrent multithreaded reads) */
     1811        File file (File::Mode_Read, Utf8Str (mData.mCfgFile.mName));
    18111812        XmlTreeBackend tree;
    18121813
     
    18591860    HRESULT rc = S_OK;
    18601861
    1861     /* serialize file access */
     1862    /* serialize file access (prevent concurrent reads and writes) */
    18621863    AutoLock alock (this);
    18631864
     
    18661867        using namespace settings;
    18671868
    1868         /* load the config file */
    1869         File file (File::ReadWrite, mData.mCfgFile.mHandle,
    1870                    Utf8Str (mData.mCfgFile.mName));
     1869        /* load the settings file */
     1870        File file (mData.mCfgFile.mHandle, Utf8Str (mData.mCfgFile.mName));
    18711871        XmlTreeBackend tree;
    18721872
     
    37043704 *  Helper function to write out the configuration tree.
    37053705 *
    3706  *  @note Locks objects for reading!
     3706 *  @note Locks this object for writing and child objects for reading/writing!
    37073707 */
    37083708HRESULT VirtualBox::saveSettings()
     
    37153715    HRESULT rc = S_OK;
    37163716
    3717     AutoReaderLock alock (this);
     3717    /* serialize file access (prevent concurrent reads and writes) */
     3718    AutoLock alock (this);
    37183719
    37193720    try
     
    37213722        using namespace settings;
    37223723
    3723         File file (File::ReadWrite, mData.mCfgFile.mHandle,
    3724                   Utf8Str (mData.mCfgFile.mName));
     3724        /* load the settings file */
     3725        File file (mData.mCfgFile.mHandle, Utf8Str (mData.mCfgFile.mName));
    37253726        XmlTreeBackend tree;
    37263727
  • trunk/src/VBox/Main/xml/Settings.cpp

    r8029 r8055  
    2121#include <iprt/err.h>
    2222#include <iprt/file.h>
     23#include <iprt/lock.h>
    2324
    2425#include <libxml/tree.h>
     
    7475    {
    7576        xmlExternalEntityLoader defaultEntityLoader;
     77
     78        /** Used to provide some thread safety missing in libxml2 (see e.g.
     79         *  XmlTreeBackend::read()) */
     80        RTLockMtx lock;
    7681    }
    7782    xml;
     
    347352        : fileName (NULL), handle (NIL_RTFILE), opened (false) {}
    348353
    349     Mode mode;
    350354    char *fileName;
    351355    RTFILE handle;
     
    356360    : m (new Data())
    357361{
    358     m->mode = aMode;
    359 
    360362    m->fileName = RTStrDup (aFileName);
    361363    if (m->fileName == NULL)
     
    365367    switch (aMode)
    366368    {
    367         case Read:
     369        case Mode_Read:
    368370            flags = RTFILE_O_READ;
    369371            break;
    370         case Write:
     372        case Mode_Write:
    371373            flags = RTFILE_O_WRITE | RTFILE_O_CREATE;
    372374            break;
    373         case ReadWrite:
     375        case Mode_ReadWrite:
    374376            flags = RTFILE_O_READ | RTFILE_O_WRITE;
    375377    }
     
    382384}
    383385
    384 File::File (Mode aMode, RTFILE aHandle, const char *aFileName /* = NULL */ )
     386File::File (RTFILE aHandle, const char *aFileName /* = NULL */)
    385387    : m (new Data())
    386388{
     
    388390        throw EInvalidArg (RT_SRC_POS);
    389391
    390     m->mode = aMode;
    391392    m->handle = aHandle;
    392393
     
    903904    m->trappedErr.reset();
    904905
    905     /* Set up the external entity resolver. Note that we do it in a
    906      * thread-unsafe fashion because this stuff is not thread-safe in libxml2.
    907      * Making it thread-safe would require a) guarding this method with a
    908      * mutex and b) requiring our API caller not to use libxml2 on some other
    909      * thread (which is not practically possible). So, our API is not
    910      * thread-safe for now (note that there are more thread-unsafe assumptions
    911      * below like xsltGenericError which is also a libxslt limitation).*/
     906    /* We use the global lock for the whole duration of this method to serialize
     907     * access to thread-unsafe xmlGetExternalEntityLoader() and some other
     908     * calls. It means that only one thread is able to parse an XML stream at a
     909     * time but another choice would be to patch libxml2/libxslt which is
     910     * unwanted now for several reasons. Search for "thread-safe" to find all
     911     * unsafe cases. */
     912    RTLock alock (gGlobal.xml.lock);
     913
    912914    xmlExternalEntityLoader oldEntityLoader = xmlGetExternalEntityLoader();
    913915    sThat = this;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette