VirtualBox

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


Ignore:
Timestamp:
Dec 4, 2009 7:30:50 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
55684
Message:

Main: make SerialPort instance data private and make it use the XML settings struct for simplicity

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

Legend:

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

    r25198 r25203  
    500500
    501501                    /* Apply network adapters defaults */
    502                     for (ULONG slot = 0; slot < RT_ELEMENTS (mNetworkAdapters); ++slot)
    503                         mNetworkAdapters [slot]->applyDefaults (aOsType);
     502                    for (ULONG slot = 0; slot < RT_ELEMENTS(mNetworkAdapters); ++slot)
     503                        mNetworkAdapters[slot]->applyDefaults(aOsType);
    504504
    505505                    /* Apply serial port defaults */
    506                     for (ULONG slot = 0; slot < RT_ELEMENTS (mSerialPorts); ++slot)
    507                         mSerialPorts [slot]->applyDefaults (aOsType);
     506                    for (ULONG slot = 0; slot < RT_ELEMENTS(mSerialPorts); ++slot)
     507                        mSerialPorts[slot]->applyDefaults(aOsType);
    508508                }
    509509            }
  • trunk/src/VBox/Main/ParallelPortImpl.cpp

    r25202 r25203  
    374374}
    375375
     376STDMETHODIMP ParallelPort::COMSETTER(Path) (IN_BSTR aPath)
     377{
     378    AutoCaller autoCaller(this);
     379    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     380
     381    /* the machine needs to be mutable */
     382    Machine::AutoMutableStateDependency adep(m->pMachine);
     383    if (FAILED(adep.rc())) return adep.rc();
     384
     385    AutoWriteLock alock(this);
     386
     387    Utf8Str str(aPath);
     388    if (str != m->bd->strPath)
     389    {
     390        HRESULT rc = checkSetPath(str);
     391        if (FAILED(rc)) return rc;
     392
     393        m->bd.backup();
     394        m->bd->strPath = str;
     395
     396        /* leave the lock before informing callbacks */
     397        alock.unlock();
     398
     399        return m->pMachine->onParallelPortChange(this);
     400    }
     401
     402    return S_OK;
     403}
     404
     405// public methods only for internal purposes
     406////////////////////////////////////////////////////////////////////////////////
     407
     408/**
     409 *  Loads settings from the given port node.
     410 *  May be called once right after this object creation.
     411 *
     412 *  @param aPortNode <Port> node.
     413 *
     414 *  @note Locks this object for writing.
     415 */
     416HRESULT ParallelPort::loadSettings(const settings::ParallelPort &data)
     417{
     418    AutoCaller autoCaller(this);
     419    AssertComRCReturnRC(autoCaller.rc());
     420
     421    AutoWriteLock alock(this);
     422
     423    // simply copy
     424    *m->bd.data() = data;
     425
     426    return S_OK;
     427}
     428
     429/**
     430 *  Saves settings to the given port node.
     431 *
     432 *  Note that the given Port node is comletely empty on input.
     433 *
     434 *  @param aPortNode <Port> node.
     435 *
     436 *  @note Locks this object for reading.
     437 */
     438HRESULT ParallelPort::saveSettings(settings::ParallelPort &data)
     439{
     440    AutoCaller autoCaller(this);
     441    AssertComRCReturnRC(autoCaller.rc());
     442
     443    AutoReadLock alock(this);
     444
     445    // simply copy
     446    data = *m->bd.data();
     447
     448    return S_OK;
     449}
     450
     451bool ParallelPort::isModified()
     452{
     453    AutoWriteLock alock (this);
     454    return m->bd.isBackedUp();
     455}
     456
     457bool ParallelPort::isReallyModified()
     458{
     459    AutoWriteLock alock(this);
     460    return m->bd.hasActualChanges();
     461}
     462
     463/**
     464 *  @note Locks this object for writing.
     465 */
     466bool ParallelPort::rollback()
     467{
     468    /* sanity */
     469    AutoCaller autoCaller(this);
     470    AssertComRCReturn (autoCaller.rc(), false);
     471
     472    AutoWriteLock alock(this);
     473
     474    bool changed = false;
     475
     476    if (m->bd.isBackedUp())
     477    {
     478        /* we need to check all data to see whether anything will be changed
     479         * after rollback */
     480        changed = m->bd.hasActualChanges();
     481        m->bd.rollback();
     482    }
     483
     484    return changed;
     485}
     486
     487/**
     488 *  @note Locks this object for writing, together with the peer object (also
     489 *  for writing) if there is one.
     490 */
     491void ParallelPort::commit()
     492{
     493    /* sanity */
     494    AutoCaller autoCaller(this);
     495    AssertComRCReturnVoid (autoCaller.rc());
     496
     497    /* sanity too */
     498    AutoCaller peerCaller (m->pPeer);
     499    AssertComRCReturnVoid (peerCaller.rc());
     500
     501    /* lock both for writing since we modify both (m->pPeer is "master" so locked
     502     * first) */
     503    AutoMultiWriteLock2 alock (m->pPeer, this);
     504
     505    if (m->bd.isBackedUp())
     506    {
     507        m->bd.commit();
     508        if (m->pPeer)
     509        {
     510            /* attach new data to the peer and reshare it */
     511            m->pPeer->m->bd.attach(m->bd);
     512        }
     513    }
     514}
     515
     516/**
     517 *  @note Locks this object for writing, together with the peer object
     518 *  represented by @a aThat (locked for reading).
     519 */
     520void ParallelPort::copyFrom(ParallelPort *aThat)
     521{
     522    AssertReturnVoid (aThat != NULL);
     523
     524    /* sanity */
     525    AutoCaller autoCaller(this);
     526    AssertComRCReturnVoid (autoCaller.rc());
     527
     528    /* sanity too */
     529    AutoCaller thatCaller (aThat);
     530    AssertComRCReturnVoid (thatCaller.rc());
     531
     532    /* peer is not modified, lock it for reading (aThat is "master" so locked
     533     * first) */
     534    AutoMultiLock2 alock (aThat->rlock(), this->wlock());
     535
     536    /* this will back up current data */
     537    m->bd.assignCopy(aThat->m->bd);
     538}
     539
    376540/**
    377541 *  Validates COMSETTER(Path) arguments.
     
    392556}
    393557
    394 STDMETHODIMP ParallelPort::COMSETTER(Path) (IN_BSTR aPath)
    395 {
    396     AutoCaller autoCaller(this);
    397     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    398 
    399     /* the machine needs to be mutable */
    400     Machine::AutoMutableStateDependency adep(m->pMachine);
    401     if (FAILED(adep.rc())) return adep.rc();
    402 
    403     AutoWriteLock alock(this);
    404 
    405     Utf8Str str(aPath);
    406     if (str != m->bd->strPath)
    407     {
    408         HRESULT rc = checkSetPath(str);
    409         if (FAILED(rc)) return rc;
    410 
    411         m->bd.backup();
    412         m->bd->strPath = str;
    413 
    414         /* leave the lock before informing callbacks */
    415         alock.unlock();
    416 
    417         return m->pMachine->onParallelPortChange (this);
    418     }
    419 
    420     return S_OK;
    421 }
    422 
    423 // public methods only for internal purposes
    424 ////////////////////////////////////////////////////////////////////////////////
    425 
    426 /**
    427  *  Loads settings from the given port node.
    428  *  May be called once right after this object creation.
    429  *
    430  *  @param aPortNode <Port> node.
    431  *
    432  *  @note Locks this object for writing.
    433  */
    434 HRESULT ParallelPort::loadSettings(const settings::ParallelPort &data)
    435 {
    436     AutoCaller autoCaller(this);
    437     AssertComRCReturnRC(autoCaller.rc());
    438 
    439     AutoWriteLock alock(this);
    440 
    441     // simply copy
    442     *m->bd.data() = data;
    443 
    444     return S_OK;
    445 }
    446 
    447 /**
    448  *  Saves settings to the given port node.
    449  *
    450  *  Note that the given Port node is comletely empty on input.
    451  *
    452  *  @param aPortNode <Port> node.
    453  *
    454  *  @note Locks this object for reading.
    455  */
    456 HRESULT ParallelPort::saveSettings(settings::ParallelPort &data)
    457 {
    458     AutoCaller autoCaller(this);
    459     AssertComRCReturnRC(autoCaller.rc());
    460 
    461     AutoReadLock alock(this);
    462 
    463     // simply copy
    464     data = *m->bd.data();
    465 
    466     return S_OK;
    467 }
    468 
    469 bool ParallelPort::isModified()
    470 {
    471     AutoWriteLock alock (this);
    472     return m->bd.isBackedUp();
    473 }
    474 
    475 bool ParallelPort::isReallyModified()
    476 {
    477     AutoWriteLock alock(this);
    478     return m->bd.hasActualChanges();
    479 }
    480 
    481 /**
    482  *  @note Locks this object for writing.
    483  */
    484 bool ParallelPort::rollback()
    485 {
    486     /* sanity */
    487     AutoCaller autoCaller(this);
    488     AssertComRCReturn (autoCaller.rc(), false);
    489 
    490     AutoWriteLock alock(this);
    491 
    492     bool changed = false;
    493 
    494     if (m->bd.isBackedUp())
    495     {
    496         /* we need to check all data to see whether anything will be changed
    497          * after rollback */
    498         changed = m->bd.hasActualChanges();
    499         m->bd.rollback();
    500     }
    501 
    502     return changed;
    503 }
    504 
    505 /**
    506  *  @note Locks this object for writing, together with the peer object (also
    507  *  for writing) if there is one.
    508  */
    509 void ParallelPort::commit()
    510 {
    511     /* sanity */
    512     AutoCaller autoCaller(this);
    513     AssertComRCReturnVoid (autoCaller.rc());
    514 
    515     /* sanity too */
    516     AutoCaller peerCaller (m->pPeer);
    517     AssertComRCReturnVoid (peerCaller.rc());
    518 
    519     /* lock both for writing since we modify both (m->pPeer is "master" so locked
    520      * first) */
    521     AutoMultiWriteLock2 alock (m->pPeer, this);
    522 
    523     if (m->bd.isBackedUp())
    524     {
    525         m->bd.commit();
    526         if (m->pPeer)
    527         {
    528             /* attach new data to the peer and reshare it */
    529             m->pPeer->m->bd.attach(m->bd);
    530         }
    531     }
    532 }
    533 
    534 /**
    535  *  @note Locks this object for writing, together with the peer object
    536  *  represented by @a aThat (locked for reading).
    537  */
    538 void ParallelPort::copyFrom (ParallelPort *aThat)
    539 {
    540     AssertReturnVoid (aThat != NULL);
    541 
    542     /* sanity */
    543     AutoCaller autoCaller(this);
    544     AssertComRCReturnVoid (autoCaller.rc());
    545 
    546     /* sanity too */
    547     AutoCaller thatCaller (aThat);
    548     AssertComRCReturnVoid (thatCaller.rc());
    549 
    550     /* peer is not modified, lock it for reading (aThat is "master" so locked
    551      * first) */
    552     AutoMultiLock2 alock (aThat->rlock(), this->wlock());
    553 
    554     /* this will back up current data */
    555     m->bd.assignCopy(aThat->m->bd);
    556 }
    557 
    558558
    559559/* vi: set tabstop=4 shiftwidth=4 expandtab: */
  • trunk/src/VBox/Main/SerialPortImpl.cpp

    r25149 r25203  
    3131#include <VBox/settings.h>
    3232
     33////////////////////////////////////////////////////////////////////////////////
     34//
     35// SerialPort private data definition
     36//
     37////////////////////////////////////////////////////////////////////////////////
     38
     39struct SerialPort::Data
     40{
     41    Data()
     42    { }
     43
     44    const ComObjPtr<Machine, ComWeakRef>    pMachine;
     45    const ComObjPtr<SerialPort>             pPeer;
     46
     47    Backupable<settings::SerialPort>        bd;
     48};
     49
    3350// constructor / destructor
    3451/////////////////////////////////////////////////////////////////////////////
     
    5471 *  @param aParent  Handle of the parent object.
    5572 */
    56 HRESULT SerialPort::init (Machine *aParent, ULONG aSlot)
     73HRESULT SerialPort::init(Machine *aParent, ULONG aSlot)
    5774{
    5875    LogFlowThisFunc(("aParent=%p, aSlot=%d\n", aParent, aSlot));
     
    6481    AssertReturn(autoInitSpan.isOk(), E_FAIL);
    6582
    66     unconst(mParent) = aParent;
    67     /* mPeer is left null */
    68 
    69     mData.allocate();
     83    m = new Data();
     84
     85    unconst(m->pMachine) = aParent;
     86    /* m->pPeer is left null */
     87
     88    m->bd.allocate();
    7089
    7190    /* initialize data */
    72     mData->mSlot = aSlot;
     91    m->bd->ulSlot = aSlot;
    7392
    7493    /* Confirm a successful initialization */
     
    88107 *  @note Locks @a aThat object for reading.
    89108 */
    90 HRESULT SerialPort::init (Machine *aParent, SerialPort *aThat)
     109HRESULT SerialPort::init(Machine *aParent, SerialPort *aThat)
    91110{
    92111    LogFlowThisFunc(("aParent=%p, aThat=%p\n", aParent, aThat));
     
    98117    AssertReturn(autoInitSpan.isOk(), E_FAIL);
    99118
    100     unconst(mParent) = aParent;
    101     unconst(mPeer) = aThat;
     119    m = new Data();
     120
     121    unconst(m->pMachine) = aParent;
     122    unconst(m->pPeer) = aThat;
    102123
    103124    AutoCaller thatCaller (aThat);
     
    105126
    106127    AutoReadLock thatLock (aThat);
    107     mData.share (aThat->mData);
     128    m->bd.share (aThat->m->bd);
    108129
    109130    /* Confirm a successful initialization */
     
    120141 *  @note Locks @a aThat object for reading.
    121142 */
    122 HRESULT SerialPort::initCopy (Machine *aParent, SerialPort *aThat)
     143HRESULT SerialPort::initCopy(Machine *aParent, SerialPort *aThat)
    123144{
    124145    LogFlowThisFunc(("aParent=%p, aThat=%p\n", aParent, aThat));
     
    130151    AssertReturn(autoInitSpan.isOk(), E_FAIL);
    131152
    132     unconst(mParent) = aParent;
    133     /* mPeer is left null */
     153    m = new Data();
     154
     155    unconst(m->pMachine) = aParent;
     156    /* pPeer is left null */
    134157
    135158    AutoCaller thatCaller (aThat);
     
    137160
    138161    AutoReadLock thatLock (aThat);
    139     mData.attachCopy (aThat->mData);
     162    m->bd.attachCopy (aThat->m->bd);
    140163
    141164    /* Confirm a successful initialization */
     
    158181        return;
    159182
    160     mData.free();
    161 
    162     unconst(mPeer).setNull();
    163     unconst(mParent).setNull();
    164 }
    165 
    166 // public methods only for internal purposes
    167 ////////////////////////////////////////////////////////////////////////////////
    168 
    169 /**
    170  *  Loads settings from the given port node.
    171  *  May be called once right after this object creation.
    172  *
    173  *  @param aPortNode <Port> node.
    174  *
    175  *  @note Locks this object for writing.
    176  */
    177 HRESULT SerialPort::loadSettings(const settings::SerialPort &data)
    178 {
    179     AutoCaller autoCaller(this);
    180     AssertComRCReturnRC(autoCaller.rc());
    181 
    182     AutoWriteLock alock(this);
    183 
    184     /* Note: we assume that the default values for attributes of optional
    185      * nodes are assigned in the Data::Data() constructor and don't do it
    186      * here. It implies that this method may only be called after constructing
    187      * a new BIOSSettings object while all its data fields are in the default
    188      * values. Exceptions are fields whose creation time defaults don't match
    189      * values that should be applied when these fields are not explicitly set
    190      * in the settings file (for backwards compatibility reasons). This takes
    191      * place when a setting of a newly created object must default to A while
    192      * the same setting of an object loaded from the old settings file must
    193      * default to B. */
    194 
    195     /* enabled (required) */
    196     mData->mEnabled = data.fEnabled;
    197     /* I/O base (required) */
    198     mData->mIOBase = data.ulIOBase;
    199     /* IRQ (required) */
    200     mData->mIRQ = data.ulIRQ;
    201     /* host mode (required) */
    202     mData->mHostMode = data.portMode;
    203 
    204     /* pipe/device path (optional, defaults to null) */
    205     Bstr path(data.strPath);
    206     HRESULT rc = checkSetPath(path);
    207     if (FAILED(rc)) return rc;
    208     mData->mPath = path;
    209 
    210     /* server mode (optional, defaults to false) */
    211     mData->mServer = data.fServer;
    212 
    213     return S_OK;
    214 }
    215 
    216 /**
    217  *  Saves the port settings to the given port node.
    218  *
    219  *  Note that the given Port node is comletely empty on input.
    220  *
    221  *  @param aPortNode <Port> node.
    222  *
    223  *  @note Locks this object for reading.
    224  */
    225 HRESULT SerialPort::saveSettings(settings::SerialPort &data)
    226 {
    227     AutoCaller autoCaller(this);
    228     AssertComRCReturnRC(autoCaller.rc());
    229 
    230     AutoReadLock alock(this);
    231 
    232     data.fEnabled = !!mData->mEnabled;
    233     data.ulIOBase = mData->mIOBase;
    234     data.ulIRQ = mData->mIRQ;
    235     data.portMode = mData->mHostMode;
    236 
    237     /* Always save non-null mPath and mServer to preserve the user values for
    238      * later use. Note that 'server' is false by default in XML so we don't
    239      * save it when it's false. */
    240     data.strPath = mData->mPath;
    241     data.fServer = !!mData->mServer;
    242 
    243     return S_OK;
    244 }
    245 
    246 /**
    247  *  @note Locks this object for writing.
    248  */
    249 bool SerialPort::rollback()
    250 {
    251     /* sanity */
    252     AutoCaller autoCaller(this);
    253     AssertComRCReturn (autoCaller.rc(), false);
    254 
    255     AutoWriteLock alock(this);
    256 
    257     bool changed = false;
    258 
    259     if (mData.isBackedUp())
    260     {
    261         /* we need to check all data to see whether anything will be changed
    262          * after rollback */
    263         changed = mData.hasActualChanges();
    264         mData.rollback();
    265     }
    266 
    267     return changed;
    268 }
    269 
    270 /**
    271  *  @note Locks this object for writing, together with the peer object (also
    272  *  for writing) if there is one.
    273  */
    274 void SerialPort::commit()
    275 {
    276     /* sanity */
    277     AutoCaller autoCaller(this);
    278     AssertComRCReturnVoid (autoCaller.rc());
    279 
    280     /* sanity too */
    281     AutoCaller peerCaller (mPeer);
    282     AssertComRCReturnVoid (peerCaller.rc());
    283 
    284     /* lock both for writing since we modify both (mPeer is "master" so locked
    285      * first) */
    286     AutoMultiWriteLock2 alock (mPeer, this);
    287 
    288     if (mData.isBackedUp())
    289     {
    290         mData.commit();
    291         if (mPeer)
    292         {
    293             /* attach new data to the peer and reshare it */
    294             mPeer->mData.attach (mData);
    295         }
    296     }
    297 }
    298 
    299 /**
    300  *  @note Locks this object for writing, together with the peer object
    301  *  represented by @a aThat (locked for reading).
    302  */
    303 void SerialPort::copyFrom (SerialPort *aThat)
    304 {
    305     AssertReturnVoid (aThat != NULL);
    306 
    307     /* sanity */
    308     AutoCaller autoCaller(this);
    309     AssertComRCReturnVoid (autoCaller.rc());
    310 
    311     /* sanity too */
    312     AutoCaller thatCaller (aThat);
    313     AssertComRCReturnVoid (thatCaller.rc());
    314 
    315     /* peer is not modified, lock it for reading (aThat is "master" so locked
    316      * first) */
    317     AutoMultiLock2 alock (aThat->rlock(), this->wlock());
    318 
    319     /* this will back up current data */
    320     mData.assignCopy (aThat->mData);
    321 }
    322 
    323 void SerialPort::applyDefaults (GuestOSType *aOsType)
    324 {
    325     AssertReturnVoid (aOsType != NULL);
    326 
    327     /* sanity */
    328     AutoCaller autoCaller(this);
    329     AssertComRCReturnVoid (autoCaller.rc());
    330 
    331     AutoWriteLock alock(this);
    332 
    333     uint32_t numSerialEnabled = aOsType->numSerialEnabled();
    334 
    335     /* Enable port if requested */
    336     if (mData->mSlot < numSerialEnabled)
    337     {
    338         mData->mEnabled = true;
    339     }
     183    m->bd.free();
     184
     185    unconst(m->pPeer).setNull();
     186    unconst(m->pMachine).setNull();
     187
     188    delete m;
     189    m = NULL;
    340190}
    341191
     
    352202    AutoReadLock alock(this);
    353203
    354     *aEnabled = mData->mEnabled;
     204    *aEnabled = m->bd->fEnabled;
    355205
    356206    return S_OK;
     
    365215
    366216    /* the machine needs to be mutable */
    367     Machine::AutoMutableStateDependency adep(mParent);
     217    Machine::AutoMutableStateDependency adep(m->pMachine);
    368218    if (FAILED(adep.rc())) return adep.rc();
    369219
    370220    AutoWriteLock alock(this);
    371221
    372     if (mData->mEnabled != aEnabled)
    373     {
    374         mData.backup();
    375         mData->mEnabled = aEnabled;
     222    if (m->bd->fEnabled != aEnabled)
     223    {
     224        m->bd.backup();
     225        m->bd->fEnabled = aEnabled;
    376226
    377227        /* leave the lock before informing callbacks */
    378228        alock.unlock();
    379229
    380         mParent->onSerialPortChange (this);
     230        m->pMachine->onSerialPortChange (this);
    381231    }
    382232
     
    393243    AutoReadLock alock(this);
    394244
    395     *aHostMode = mData->mHostMode;
     245    *aHostMode = m->bd->portMode;
    396246
    397247    return S_OK;
     
    404254
    405255    /* the machine needs to be mutable */
    406     Machine::AutoMutableStateDependency adep(mParent);
     256    Machine::AutoMutableStateDependency adep(m->pMachine);
    407257    if (FAILED(adep.rc())) return adep.rc();
    408258
     
    412262    bool emitChangeEvent = false;
    413263
    414     if (mData->mHostMode != aHostMode)
     264    if (m->bd->portMode != aHostMode)
    415265    {
    416266        switch (aHostMode)
    417267        {
    418268            case PortMode_RawFile:
    419                 if (mData->mPath.isEmpty())
     269                if (m->bd->strPath.isEmpty())
    420270                    return setError (E_INVALIDARG,
    421271                        tr ("Cannot set the raw file mode of the serial port %d "
    422272                            "because the file path is empty or null"),
    423                         mData->mSlot);
     273                        m->bd->ulSlot);
    424274                break;
    425275            case PortMode_HostPipe:
    426                 if (mData->mPath.isEmpty())
     276                if (m->bd->strPath.isEmpty())
    427277                    return setError (E_INVALIDARG,
    428278                        tr ("Cannot set the host pipe mode of the serial port %d "
    429279                            "because the pipe path is empty or null"),
    430                         mData->mSlot);
     280                        m->bd->ulSlot);
    431281                break;
    432282            case PortMode_HostDevice:
    433                 if (mData->mPath.isEmpty())
     283                if (m->bd->strPath.isEmpty())
    434284                    return setError (E_INVALIDARG,
    435285                        tr ("Cannot set the host device mode of the serial port %d "
    436286                            "because the device path is empty or null"),
    437                         mData->mSlot);
     287                        m->bd->ulSlot);
    438288                break;
    439289            case PortMode_Disconnected:
     
    441291        }
    442292
    443         mData.backup();
    444         mData->mHostMode = aHostMode;
     293        m->bd.backup();
     294        m->bd->portMode = aHostMode;
    445295
    446296        emitChangeEvent = true;
     
    452302        alock.unlock();
    453303
    454         mParent->onSerialPortChange (this);
     304        m->pMachine->onSerialPortChange (this);
    455305    }
    456306
     
    467317    AutoReadLock alock(this);
    468318
    469     *aSlot = mData->mSlot;
     319    *aSlot = m->bd->ulSlot;
    470320
    471321    return S_OK;
     
    481331    AutoReadLock alock(this);
    482332
    483     *aIRQ = mData->mIRQ;
     333    *aIRQ = m->bd->ulIRQ;
    484334
    485335    return S_OK;
     
    494344            tr ("Invalid IRQ number of the serial port %d: "
    495345                "%lu (must be in range [0, %lu])"),
    496             mData->mSlot, aIRQ, 255);
     346            m->bd->ulSlot, aIRQ, 255);
    497347
    498348    AutoCaller autoCaller(this);
     
    500350
    501351    /* the machine needs to be mutable */
    502     Machine::AutoMutableStateDependency adep(mParent);
     352    Machine::AutoMutableStateDependency adep(m->pMachine);
    503353    if (FAILED(adep.rc())) return adep.rc();
    504354
     
    508358    bool emitChangeEvent = false;
    509359
    510     if (mData->mIRQ != aIRQ)
    511     {
    512         mData.backup();
    513         mData->mIRQ = aIRQ;
     360    if (m->bd->ulIRQ != aIRQ)
     361    {
     362        m->bd.backup();
     363        m->bd->ulIRQ = aIRQ;
    514364        emitChangeEvent = true;
    515365    }
     
    520370        alock.unlock();
    521371
    522         mParent->onSerialPortChange (this);
     372        m->pMachine->onSerialPortChange (this);
    523373    }
    524374
     
    535385    AutoReadLock alock(this);
    536386
    537     *aIOBase = mData->mIOBase;
     387    *aIOBase = m->bd->ulIOBase;
    538388
    539389    return S_OK;
     
    548398            tr ("Invalid I/O port base address of the serial port %d: "
    549399                "%lu (must be in range [0, 0x%X])"),
    550             mData->mSlot, aIOBase, 0, 0xFFFF);
     400            m->bd->ulSlot, aIOBase, 0, 0xFFFF);
    551401
    552402    AutoCaller autoCaller(this);
     
    554404
    555405    /* the machine needs to be mutable */
    556     Machine::AutoMutableStateDependency adep(mParent);
     406    Machine::AutoMutableStateDependency adep(m->pMachine);
    557407    if (FAILED(adep.rc())) return adep.rc();
    558408
     
    562412    bool emitChangeEvent = false;
    563413
    564     if (mData->mIOBase != aIOBase)
    565     {
    566         mData.backup();
    567         mData->mIOBase = aIOBase;
     414    if (m->bd->ulIOBase != aIOBase)
     415    {
     416        m->bd.backup();
     417        m->bd->ulIOBase = aIOBase;
    568418        emitChangeEvent = true;
    569419    }
     
    574424        alock.unlock();
    575425
    576         mParent->onSerialPortChange (this);
     426        m->pMachine->onSerialPortChange (this);
    577427    }
    578428
     
    589439    AutoReadLock alock(this);
    590440
    591     mData->mPath.cloneTo(aPath);
    592 
    593     return S_OK;
    594 }
    595 
    596 /**
    597  *  Validates COMSETTER(Path) arguments.
    598  */
    599 HRESULT SerialPort::checkSetPath (CBSTR aPath)
    600 {
    601     AssertReturn(isWriteLockOnCurrentThread(), E_FAIL);
    602 
    603     if ((mData->mHostMode == PortMode_HostDevice ||
    604          mData->mHostMode == PortMode_HostPipe ||
    605          mData->mHostMode == PortMode_RawFile) &&
    606         (aPath == NULL || *aPath == '\0'))
    607         return setError (E_INVALIDARG,
    608             tr ("Path of the serial port %d may not be empty or null in "
    609                 "host pipe or host device mode"),
    610             mData->mSlot);
     441    m->bd->strPath.cloneTo(aPath);
    611442
    612443    return S_OK;
     
    619450
    620451    /* the machine needs to be mutable */
    621     Machine::AutoMutableStateDependency adep(mParent);
     452    Machine::AutoMutableStateDependency adep(m->pMachine);
    622453    if (FAILED(adep.rc())) return adep.rc();
    623454
     
    628459        aPath = NULL;
    629460
    630     if (mData->mPath != aPath)
    631     {
    632         HRESULT rc = checkSetPath (aPath);
     461    Utf8Str str(aPath);
     462    if (str != m->bd->strPath)
     463    {
     464        HRESULT rc = checkSetPath(str);
    633465        if (FAILED(rc)) return rc;
    634466
    635         mData.backup();
    636         mData->mPath = aPath;
     467        m->bd.backup();
     468        m->bd->strPath = str;
    637469
    638470        /* leave the lock before informing callbacks */
    639471        alock.unlock();
    640472
    641         return mParent->onSerialPortChange (this);
     473        return m->pMachine->onSerialPortChange(this);
    642474    }
    643475
     
    654486    AutoReadLock alock(this);
    655487
    656     *aServer = mData->mServer;
     488    *aServer = m->bd->fServer;
    657489
    658490    return S_OK;
     
    665497
    666498    /* the machine needs to be mutable */
    667     Machine::AutoMutableStateDependency adep(mParent);
     499    Machine::AutoMutableStateDependency adep(m->pMachine);
    668500    if (FAILED(adep.rc())) return adep.rc();
    669501
    670502    AutoWriteLock alock(this);
    671503
    672     if (mData->mServer != aServer)
    673     {
    674         mData.backup();
    675         mData->mServer = aServer;
     504    if (m->bd->fServer != aServer)
     505    {
     506        m->bd.backup();
     507        m->bd->fServer = aServer;
    676508
    677509        /* leave the lock before informing callbacks */
    678510        alock.unlock();
    679511
    680         mParent->onSerialPortChange (this);
    681     }
    682 
    683     return S_OK;
    684 }
     512        m->pMachine->onSerialPortChange (this);
     513    }
     514
     515    return S_OK;
     516}
     517
     518// public methods only for internal purposes
     519////////////////////////////////////////////////////////////////////////////////
     520
     521/**
     522 *  Loads settings from the given port node.
     523 *  May be called once right after this object creation.
     524 *
     525 *  @param aPortNode <Port> node.
     526 *
     527 *  @note Locks this object for writing.
     528 */
     529HRESULT SerialPort::loadSettings(const settings::SerialPort &data)
     530{
     531    AutoCaller autoCaller(this);
     532    AssertComRCReturnRC(autoCaller.rc());
     533
     534    AutoWriteLock alock(this);
     535
     536    // simply copy
     537    *m->bd.data() = data;
     538
     539    return S_OK;
     540}
     541
     542/**
     543 *  Saves the port settings to the given port node.
     544 *
     545 *  Note that the given Port node is comletely empty on input.
     546 *
     547 *  @param aPortNode <Port> node.
     548 *
     549 *  @note Locks this object for reading.
     550 */
     551HRESULT SerialPort::saveSettings(settings::SerialPort &data)
     552{
     553    AutoCaller autoCaller(this);
     554    AssertComRCReturnRC(autoCaller.rc());
     555
     556    AutoReadLock alock(this);
     557
     558    // simply copy
     559    data = *m->bd.data();
     560
     561    return S_OK;
     562}
     563
     564bool SerialPort::isModified()
     565{
     566    AutoWriteLock alock (this);
     567    return m->bd.isBackedUp();
     568}
     569
     570bool SerialPort::isReallyModified()
     571{
     572    AutoWriteLock alock(this);
     573    return m->bd.hasActualChanges();
     574}
     575
     576/**
     577 *  @note Locks this object for writing.
     578 */
     579bool SerialPort::rollback()
     580{
     581    /* sanity */
     582    AutoCaller autoCaller(this);
     583    AssertComRCReturn (autoCaller.rc(), false);
     584
     585    AutoWriteLock alock(this);
     586
     587    bool changed = false;
     588
     589    if (m->bd.isBackedUp())
     590    {
     591        /* we need to check all data to see whether anything will be changed
     592         * after rollback */
     593        changed = m->bd.hasActualChanges();
     594        m->bd.rollback();
     595    }
     596
     597    return changed;
     598}
     599
     600/**
     601 *  @note Locks this object for writing, together with the peer object (also
     602 *  for writing) if there is one.
     603 */
     604void SerialPort::commit()
     605{
     606    /* sanity */
     607    AutoCaller autoCaller(this);
     608    AssertComRCReturnVoid (autoCaller.rc());
     609
     610    /* sanity too */
     611    AutoCaller peerCaller(m->pPeer);
     612    AssertComRCReturnVoid(peerCaller.rc());
     613
     614    /* lock both for writing since we modify both (pPeer is "master" so locked
     615     * first) */
     616    AutoMultiWriteLock2 alock(m->pPeer, this);
     617
     618    if (m->bd.isBackedUp())
     619    {
     620        m->bd.commit();
     621        if (m->pPeer)
     622        {
     623            /* attach new data to the peer and reshare it */
     624            m->pPeer->m->bd.attach(m->bd);
     625        }
     626    }
     627}
     628
     629/**
     630 *  @note Locks this object for writing, together with the peer object
     631 *  represented by @a aThat (locked for reading).
     632 */
     633void SerialPort::copyFrom (SerialPort *aThat)
     634{
     635    AssertReturnVoid (aThat != NULL);
     636
     637    /* sanity */
     638    AutoCaller autoCaller(this);
     639    AssertComRCReturnVoid (autoCaller.rc());
     640
     641    /* sanity too */
     642    AutoCaller thatCaller (aThat);
     643    AssertComRCReturnVoid (thatCaller.rc());
     644
     645    /* peer is not modified, lock it for reading (aThat is "master" so locked
     646     * first) */
     647    AutoMultiLock2 alock (aThat->rlock(), this->wlock());
     648
     649    /* this will back up current data */
     650    m->bd.assignCopy (aThat->m->bd);
     651}
     652
     653void SerialPort::applyDefaults (GuestOSType *aOsType)
     654{
     655    AssertReturnVoid (aOsType != NULL);
     656
     657    /* sanity */
     658    AutoCaller autoCaller(this);
     659    AssertComRCReturnVoid (autoCaller.rc());
     660
     661    AutoWriteLock alock(this);
     662
     663    uint32_t numSerialEnabled = aOsType->numSerialEnabled();
     664
     665    /* Enable port if requested */
     666    if (m->bd->ulSlot < numSerialEnabled)
     667    {
     668        m->bd->fEnabled = true;
     669    }
     670}
     671
     672/**
     673 *  Validates COMSETTER(Path) arguments.
     674 */
     675HRESULT SerialPort::checkSetPath(const Utf8Str &str)
     676{
     677    AssertReturn(isWriteLockOnCurrentThread(), E_FAIL);
     678
     679    if (    (    m->bd->portMode == PortMode_HostDevice
     680              || m->bd->portMode == PortMode_HostPipe
     681              || m->bd->portMode == PortMode_RawFile
     682            ) && str.isEmpty()
     683       )
     684        return setError(E_INVALIDARG,
     685                        tr("Path of the serial port %d may not be empty or null in "
     686                           "host pipe or host device mode"),
     687                        m->bd->ulSlot);
     688
     689    return S_OK;
     690}
     691
    685692/* vi: set tabstop=4 shiftwidth=4 expandtab: */
  • trunk/src/VBox/Main/include/ParallelPortImpl.h

    r25202 r25203  
    9393
    9494private:
    95 
    9695    HRESULT checkSetPath(const Utf8Str &str);
    9796
  • trunk/src/VBox/Main/include/SerialPortImpl.h

    r24989 r25203  
    4242{
    4343public:
    44 
    45     struct Data
    46     {
    47         Data()
    48             : mSlot (0)
    49             , mEnabled (FALSE)
    50             , mIRQ (4)
    51             , mIOBase (0x3f8)
    52             , mHostMode (PortMode_Disconnected)
    53             , mServer (FALSE)
    54         {}
    55 
    56         bool operator== (const Data &that) const
    57         {
    58             return this == &that ||
    59                    (mSlot     == that.mSlot     &&
    60                     mEnabled  == that.mEnabled  &&
    61                     mIRQ      == that.mIRQ      &&
    62                     mIOBase   == that.mIOBase   &&
    63                     mHostMode == that.mHostMode &&
    64                     mPath     == that.mPath     &&
    65                     mServer   == that.mServer);
    66         }
    67 
    68         ULONG mSlot;
    69         BOOL  mEnabled;
    70         ULONG mIRQ;
    71         ULONG mIOBase;
    72         PortMode_T mHostMode;
    73         Bstr  mPath;
    74         BOOL  mServer;
    75     };
    76 
    7744    VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT (SerialPort)
    7845
     
    11885    HRESULT saveSettings(settings::SerialPort &data);
    11986
    120     bool isModified() { AutoWriteLock alock (this); return mData.isBackedUp(); }
    121     bool isReallyModified() { AutoWriteLock alock (this); return mData.hasActualChanges(); }
     87    bool isModified();
     88    bool isReallyModified();
    12289    bool rollback();
    12390    void commit();
    124     void copyFrom (SerialPort *aThat);
     91    void copyFrom(SerialPort *aThat);
     92
    12593    void applyDefaults (GuestOSType *aOsType);
    12694
     
    132100
    133101private:
     102    HRESULT checkSetPath(const Utf8Str &str);
    134103
    135     HRESULT checkSetPath (CBSTR aPath);
    136 
    137     const ComObjPtr<Machine, ComWeakRef> mParent;
    138     const ComObjPtr<SerialPort> mPeer;
    139 
    140     Backupable<Data> mData;
     104    struct Data;
     105    Data *m;
    141106};
    142107
Note: See TracChangeset for help on using the changeset viewer.

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