VirtualBox

Changeset 28959 in vbox


Ignore:
Timestamp:
May 2, 2010 7:36:11 PM (15 years ago)
Author:
vboxsync
Message:

ConsoleImpl: Implemented VBOX_E_DONT_CALL_AGAIN for IConsoleCallback.

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

Legend:

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

    r28955 r28959  
    242242};
    243243
     244// ConsoleCallbackRegistration
     245////////////////////////////////////////////////////////////////////////////////
     246
     247/**
     248 * Registered IConsoleCallback, used by Console::CallbackList and
     249 * Console::mCallbacks.
     250 *
     251 * In addition to keeping the interface pointer this also keeps track of the
     252 * methods that asked to not be called again.  The latter is for reducing
     253 * unnecessary IPC.
     254 */
     255class ConsoleCallbackRegistration
     256{
     257public:
     258    ComPtr<IConsoleCallback> ptrICb;
     259    /** Bitmap of disabled callback methods, that is methods that has return
     260     * VBOX_E_DONT_CALL_AGAIN. */
     261    uint32_t                    bmDisabled;
     262    /** Callback bit indexes (for bmDisabled). */
     263    typedef enum
     264    {
     265        kOnMousePointerShapeChange = 0,
     266        kOnMouseCapabilityChange,
     267        kOnKeyboardLedsChange,
     268        kOnStateChange,
     269        kOnAdditionsStateChange,
     270        kOnNetworkAdapterChange,
     271        kOnSerialPortChange,
     272        kOnParallelPortChange,
     273        kOnStorageControllerChange,
     274        kOnMediumChange,
     275        kOnCPUChange,
     276        kOnVRDPServerChange,
     277        kOnRemoteDisplayInfoChange,
     278        kOnUSBControllerChange,
     279        kOnUSBDeviceStateChange,
     280        kOnSharedFolderChange,
     281        kOnRuntimeError,
     282        kOnCanShowWindow,
     283        kOnShowWindow
     284    } CallbackBit;
     285
     286    ConsoleCallbackRegistration(IConsoleCallback *pIConsoleCallback)
     287        : ptrICb(pIConsoleCallback), bmDisabled(0)
     288    {
     289        /* nothing */
     290    }
     291
     292    ~ConsoleCallbackRegistration()
     293    {
     294       /* nothing */
     295    }
     296
     297    /** Equal operator for std::find. */
     298    bool operator==(const ConsoleCallbackRegistration &rThat) const
     299    {
     300        return this->ptrICb == rThat.ptrICb;
     301    }
     302
     303    /**
     304     * Checks if the callback is wanted, i.e. if the method hasn't yet returned
     305     * VBOX_E_DONT_CALL_AGAIN.
     306     * @returns @c true if it is wanted, @c false if not.
     307     * @param   enmBit      The callback, be sure to get this one right!
     308     */
     309    inline bool isWanted(CallbackBit enmBit) const
     310    {
     311        return !ASMBitTest(&bmDisabled, enmBit);
     312    }
     313
     314    /**
     315     * Called in response to VBOX_E_DONT_CALL_AGAIN.
     316     * @param   enmBit      The callback, be sure to get this one right!
     317     */
     318    inline void setDontCallAgain(CallbackBit enmBit)
     319    {
     320        ASMAtomicBitSet(&bmDisabled, enmBit);
     321    }
     322
     323    /**
     324     * Handle a callback return code, picking up VBOX_E_DONT_CALL_AGAIN.
     325     *
     326     * @returns hrc or S_OK if VBOX_E_DONT_CALL_AGAIN.
     327     * @param   enmBit      The callback, be sure to get this one right!
     328     * @param   hrc         The status code returned by the callback.
     329     */
     330    inline HRESULT handleResult(CallbackBit enmBit, HRESULT hrc)
     331    {
     332        if (hrc == VBOX_E_DONT_CALL_AGAIN)
     333        {
     334            setDontCallAgain(enmBit);
     335            hrc = S_OK;
     336        }
     337        return hrc;
     338    }
     339};
     340
     341/**
     342 * Macro for iterating the callback list (Console::mCallbacks) and invoking the
     343 * given method on each entry.
     344 *
     345 * This handles VBOX_E_DONT_CALL_AGAIN as well as removing dead interfaces
     346 * which.  This makes the code a big and clunky, thus this macro.  It may make
     347 * debugging and selective logging a bit of a pain, but duplicating this code
     348 * some seventeen times is much more of a pain.
     349 *
     350 * The caller must hold the console object lock - read or write, we don't care.
     351 * The caller must be a Console method - the console members accessible thru the
     352 * 'this' pointer.
     353 *
     354 * @param   CallbackMethod      The callback method, like OnKeyboardLedsChange.
     355 * @param   Args                The method arguments enclosed in parentheses.
     356 */
     357#define CONSOLE_DO_CALLBACKS(CallbackMethod, Args) \
     358    do \
     359    { \
     360        CallbackList::iterator it = this->mCallbacks.begin(); \
     361        while (it != this->mCallbacks.end()) \
     362        { \
     363            if (it->isWanted(ConsoleCallbackRegistration::k ## CallbackMethod)) \
     364            { \
     365                HRESULT hrc = it->ptrICb-> CallbackMethod Args; \
     366                hrc = it->handleResult(ConsoleCallbackRegistration::k ## CallbackMethod, hrc); \
     367                if (FAILED_DEAD_INTERFACE(hrc)) \
     368                { \
     369                    it = this->mCallbacks.erase(it); \
     370                    continue; \
     371                } \
     372            } \
     373            ++it; \
     374        } \
     375    } while (0)
     376
     377
    244378// constructor / destructor
    245379/////////////////////////////////////////////////////////////////////////////
     
    26222756
    26232757    /* notify console callbacks after the folder is added to the list */
    2624     {
    2625         CallbackList::iterator it = mCallbacks.begin();
    2626         while (it != mCallbacks.end())
    2627             (*it++)->OnSharedFolderChange(Scope_Session);
    2628     }
     2758    CONSOLE_DO_CALLBACKS(OnSharedFolderChange,(Scope_Session));
    26292759
    26302760    return rc;
     
    26832813
    26842814    /* notify console callbacks after the folder is removed to the list */
    2685     {
    2686         CallbackList::iterator it = mCallbacks.begin();
    2687         while (it != mCallbacks.end())
    2688             (*it++)->OnSharedFolderChange(Scope_Session);
    2689     }
     2815    CONSOLE_DO_CALLBACKS(OnSharedFolderChange,(Scope_Session));
    26902816
    26912817    return rc;
     
    33803506    /* notify console callbacks on success */
    33813507    if (SUCCEEDED(rc))
    3382     {
    3383         CallbackList::iterator it = mCallbacks.begin();
    3384         while (it != mCallbacks.end())
    3385             (*it++)->OnNetworkAdapterChange(aNetworkAdapter);
    3386     }
     3508        CONSOLE_DO_CALLBACKS(OnNetworkAdapterChange,(aNetworkAdapter));
    33873509
    33883510    LogFlowThisFunc(("Leaving rc=%#x\n", rc));
     
    36003722    /* notify console callbacks on success */
    36013723    if (SUCCEEDED(rc))
    3602     {
    3603         CallbackList::iterator it = mCallbacks.begin();
    3604         while (it != mCallbacks.end())
    3605             (*it++)->OnSerialPortChange(aSerialPort);
    3606     }
     3724        CONSOLE_DO_CALLBACKS(OnSerialPortChange,(aSerialPort));
    36073725
    36083726    LogFlowThisFunc(("Leaving rc=%#x\n", rc));
     
    36383756    /* notify console callbacks on success */
    36393757    if (SUCCEEDED(rc))
    3640     {
    3641         CallbackList::iterator it = mCallbacks.begin();
    3642         while (it != mCallbacks.end())
    3643             (*it++)->OnParallelPortChange(aParallelPort);
    3644     }
     3758        CONSOLE_DO_CALLBACKS(OnParallelPortChange,(aParallelPort));
    36453759
    36463760    LogFlowThisFunc(("Leaving rc=%#x\n", rc));
     
    36763790    /* notify console callbacks on success */
    36773791    if (SUCCEEDED(rc))
    3678     {
    3679         CallbackList::iterator it = mCallbacks.begin();
    3680         while (it != mCallbacks.end())
    3681             (*it++)->OnStorageControllerChange();
    3682     }
     3792        CONSOLE_DO_CALLBACKS(OnStorageControllerChange,());
    36833793
    36843794    LogFlowThisFunc(("Leaving rc=%#x\n", rc));
     
    37143824    /* notify console callbacks on success */
    37153825    if (SUCCEEDED(rc))
    3716     {
    3717         CallbackList::iterator it = mCallbacks.begin();
    3718         while (it != mCallbacks.end())
    3719             (*it++)->OnMediumChange(aMediumAttachment);
    3720     }
     3826        CONSOLE_DO_CALLBACKS(OnMediumChange,(aMediumAttachment));
    37213827
    37223828    LogFlowThisFunc(("Leaving rc=%#x\n", rc));
     
    37553861    /* notify console callbacks on success */
    37563862    if (SUCCEEDED(rc))
    3757     {
    3758         CallbackList::iterator it = mCallbacks.begin();
    3759         while (it != mCallbacks.end())
    3760             (*it++)->OnCPUChange(aCPU, aRemove);
    3761     }
     3863        CONSOLE_DO_CALLBACKS(OnCPUChange,(aCPU, aRemove));
    37623864
    37633865    LogFlowThisFunc(("Leaving rc=%#x\n", rc));
     
    38203922    /* notify console callbacks on success */
    38213923    if (SUCCEEDED(rc))
    3822     {
    3823         CallbackList::iterator it = mCallbacks.begin();
    3824         while (it != mCallbacks.end())
    3825             (*it++)->OnVRDPServerChange();
    3826     }
     3924        CONSOLE_DO_CALLBACKS(OnVRDPServerChange,());
    38273925
    38283926    return rc;
     
    38393937    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    38403938
    3841     CallbackList::iterator it = mCallbacks.begin();
    3842     while (it != mCallbacks.end())
    3843         (*it++)->OnRemoteDisplayInfoChange();
     3939    CONSOLE_DO_CALLBACKS(OnRemoteDisplayInfoChange,());
    38443940}
    38453941
     
    38793975    /* notify console callbacks on success */
    38803976    if (SUCCEEDED(rc))
    3881     {
    3882         CallbackList::iterator it = mCallbacks.begin();
    3883         while (it != mCallbacks.end())
    3884             (*it++)->OnUSBControllerChange();
    3885     }
     3977        CONSOLE_DO_CALLBACKS(OnUSBControllerChange,());
    38863978
    38873979    return rc;
     
    39073999    if (SUCCEEDED(rc))
    39084000    {
    3909         CallbackList::iterator it = mCallbacks.begin();
    3910         while (it != mCallbacks.end())
    3911             (*it++)->OnSharedFolderChange(aGlobal ? (Scope_T)Scope_Global
    3912                                                   : (Scope_T)Scope_Machine);
     4001        if (aGlobal)
     4002            CONSOLE_DO_CALLBACKS(OnSharedFolderChange,(Scope_Global));
     4003        else
     4004            CONSOLE_DO_CALLBACKS(OnSharedFolderChange,(Scope_Machine));
    39134005    }
    39144006
     
    45864678    mCallbackData.mpsc.valid = true;
    45874679
    4588     CallbackList::iterator it = mCallbacks.begin();
    4589     while (it != mCallbacks.end())
    4590         (*it++)->OnMousePointerShapeChange(fVisible, fAlpha, xHot, yHot,
    4591                                            width, height, (BYTE *) pShape);
     4680    CONSOLE_DO_CALLBACKS(OnMousePointerShapeChange,(fVisible, fAlpha, xHot, yHot, width, height, (BYTE *) pShape));
    45924681
    45934682#if 0
     
    46164705    mCallbackData.mcc.valid = true;
    46174706
    4618     CallbackList::iterator it = mCallbacks.begin();
    4619     while (it != mCallbacks.end())
    4620     {
    4621         Log2(("Console::onMouseCapabilityChange: calling %p\n", (void*)*it));
    4622         (*it++)->OnMouseCapabilityChange(supportsAbsolute, supportsRelative, needsHostCursor);
    4623     }
     4707    CONSOLE_DO_CALLBACKS(OnMouseCapabilityChange,(supportsAbsolute, supportsRelative, needsHostCursor));
    46244708}
    46254709
     
    46334717
    46344718    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    4635 
    4636     CallbackList::iterator it = mCallbacks.begin();
    4637     while (it != mCallbacks.end())
    4638         (*it++)->OnStateChange(machineState);
     4719    CONSOLE_DO_CALLBACKS(OnStateChange,(machineState));
    46394720}
    46404721
     
    46484729
    46494730    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    4650 
    4651     CallbackList::iterator it = mCallbacks.begin();
    4652     while (it != mCallbacks.end())
    4653         (*it++)->OnAdditionsStateChange();
     4731    CONSOLE_DO_CALLBACKS(OnAdditionsStateChange,());
    46544732}
    46554733
     
    46884766    mCallbackData.klc.valid = true;
    46894767
    4690     CallbackList::iterator it = mCallbacks.begin();
    4691     while (it != mCallbacks.end())
    4692         (*it++)->OnKeyboardLedsChange(fNumLock, fCapsLock, fScrollLock);
     4768    CONSOLE_DO_CALLBACKS(OnKeyboardLedsChange,(fNumLock, fCapsLock, fScrollLock));
    46934769}
    46944770
     
    47034779
    47044780    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    4705 
    4706     CallbackList::iterator it = mCallbacks.begin();
    4707     while (it != mCallbacks.end())
    4708         (*it++)->OnUSBDeviceStateChange(aDevice, aAttached, aError);
     4781    CONSOLE_DO_CALLBACKS(OnUSBDeviceStateChange,(aDevice, aAttached, aError));
    47094782}
    47104783
     
    47184791
    47194792    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    4720 
    4721     CallbackList::iterator it = mCallbacks.begin();
    4722     while (it != mCallbacks.end())
    4723         (*it++)->OnRuntimeError(aFatal, aErrorID, aMessage);
     4793    CONSOLE_DO_CALLBACKS(OnRuntimeError,(aFatal, aErrorID, aMessage));
    47244794}
    47254795
     
    47394809
    47404810    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    4741 
    4742     HRESULT rc = S_OK;
    47434811    CallbackList::iterator it = mCallbacks.begin();
    4744 
    47454812    if (aCheck)
    47464813    {
    47474814        while (it != mCallbacks.end())
    47484815        {
    4749             BOOL canShow = FALSE;
    4750             rc = (*it++)->OnCanShowWindow(&canShow);
    4751             AssertComRC(rc);
    4752             if (FAILED(rc) || !canShow)
    4753                 return rc;
     4816            if (it->isWanted(ConsoleCallbackRegistration::kOnCanShowWindow))
     4817            {
     4818                BOOL canShow = FALSE;
     4819                HRESULT hrc = it->ptrICb->OnCanShowWindow(&canShow);
     4820                hrc = it->handleResult(ConsoleCallbackRegistration::kOnCanShowWindow, hrc);
     4821                if (FAILED_DEAD_INTERFACE(hrc))
     4822                {
     4823                    it = this->mCallbacks.erase(it);
     4824                    continue;
     4825                }
     4826                AssertComRC(hrc);
     4827                if (FAILED(hrc) || !canShow)
     4828                    return hrc;
     4829            }
     4830            ++it;
    47544831        }
    47554832        *aCanShow = TRUE;
     
    47594836        while (it != mCallbacks.end())
    47604837        {
    4761             ULONG64 winId = 0;
    4762             rc = (*it++)->OnShowWindow(&winId);
    4763             AssertComRC(rc);
    4764             if (FAILED(rc))
    4765                 return rc;
    4766             /* only one callback may return non-null winId */
    4767             Assert(*aWinId == 0 || winId == 0);
    4768             if (*aWinId == 0)
    4769                 *aWinId = winId;
     4838            if (it->isWanted(ConsoleCallbackRegistration::kOnShowWindow))
     4839            {
     4840                ULONG64 winId = 0;
     4841                HRESULT hrc = it->ptrICb->OnShowWindow(&winId);
     4842                hrc = it->handleResult(ConsoleCallbackRegistration::kOnCanShowWindow, hrc);
     4843                if (FAILED_DEAD_INTERFACE(hrc))
     4844                {
     4845                    it = this->mCallbacks.erase(it);
     4846                    continue;
     4847                }
     4848                AssertComRC(hrc);
     4849                if (FAILED(hrc))
     4850                    return hrc;
     4851
     4852                /* only one callback may return non-null winId */
     4853                Assert(*aWinId == 0 || winId == 0);
     4854                if (*aWinId == 0)
     4855                    *aWinId = winId;
     4856            }
    47704857        }
    47714858    }
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r28930 r28959  
    61616161        Notification when the guest mouse pointer shape has
    61626162        changed. The new shape data is given.
     6163        <result name="VBOX_E_DONT_CALL_AGAIN">
     6164          Do not call again, this method is a NOP.
     6165        </result>
    61636166      </desc>
    61646167      <param name="visible" type="boolean" dir="in">
     
    62296232        Notification when the mouse capabilities reported by the
    62306233        guest have changed. The new capabilities are passed.
     6234        <result name="VBOX_E_DONT_CALL_AGAIN">
     6235          Do not call again, this method is a NOP.
     6236        </result>
    62316237      </desc>
    62326238      <param name="supportsAbsolute" type="boolean" dir="in"/>
     
    62396245        Notification when the guest OS executes the KBD_CMD_SET_LEDS command
    62406246        to alter the state of the keyboard LEDs.
     6247        <result name="VBOX_E_DONT_CALL_AGAIN">
     6248          Do not call again, this method is a NOP.
     6249        </result>
    62416250      </desc>
    62426251      <param name="numLock" type="boolean" dir="in"/>
     
    62496258        Notification when the execution state of the machine has changed.
    62506259        The new state will be given.
     6260        <result name="VBOX_E_DONT_CALL_AGAIN">
     6261          Do not call again, this method is a NOP.
     6262        </result>
    62516263      </desc>
    62526264      <param name="state" type="MachineState" dir="in"/>
     
    62676279        changes.  Interested callees should use INetworkAdapter methods and
    62686280        attributes to find out what has changed.
     6281        <result name="VBOX_E_DONT_CALL_AGAIN">
     6282          Do not call again, this method is a NOP.
     6283        </result>
    62696284      </desc>
    62706285      <param name="networkAdapter" type="INetworkAdapter" dir="in">
     
    62796294        Interested callees should use ISerialPort methods and attributes
    62806295        to find out what has changed.
     6296        <result name="VBOX_E_DONT_CALL_AGAIN">
     6297          Do not call again, this method is a NOP.
     6298        </result>
    62816299      </desc>
    62826300      <param name="serialPort" type="ISerialPort" dir="in">
     
    62916309        changes.  Interested callees should use ISerialPort methods and
    62926310        attributes to find out what has changed.
     6311        <result name="VBOX_E_DONT_CALL_AGAIN">
     6312          Do not call again, this method is a NOP.
     6313        </result>
    62936314      </desc>
    62946315      <param name="parallelPort" type="IParallelPort" dir="in">
     
    63036324        changes. Interested callees should query the corresponding collections
    63046325        to find out what has changed.
     6326        <result name="VBOX_E_DONT_CALL_AGAIN">
     6327          Do not call again, this method is a NOP.
     6328        </result>
    63056329      </desc>
    63066330    </method>
     
    63116335        <link to="IMachine::mediumAttachments">medium attachment</link>
    63126336        changes.
     6337        <result name="VBOX_E_DONT_CALL_AGAIN">
     6338          Do not call again, this method is a NOP.
     6339        </result>
    63136340      </desc>
    63146341      <param name="mediumAttachment" type="IMediumAttachment" dir="in">
     
    63206347      <desc>
    63216348        Notification when a CPU changes.
     6349        <result name="VBOX_E_DONT_CALL_AGAIN">
     6350          Do not call again, this method is a NOP.
     6351        </result>
    63226352      </desc>
    63236353      <param name="cpu" type="unsigned long" dir="in">
     
    63356365        Interested callees should use IVRDPServer methods and attributes to
    63366366        find out what has changed.
     6367        <result name="VBOX_E_DONT_CALL_AGAIN">
     6368          Do not call again, this method is a NOP.
     6369        </result>
    63376370      </desc>
    63386371    </method>
     
    63436376        should use <link to="IConsole::RemoteDisplayInfo">IRemoteDisplayInfo</link>
    63446377        attributes to find out what is the current status.
     6378        <result name="VBOX_E_DONT_CALL_AGAIN">
     6379          Do not call again, this method is a NOP.
     6380        </result>
    63456381      </desc>
    63466382    </method>
     
    63526388        Interested callees should use IUSBController methods and attributes to
    63536389        find out what has changed.
     6390        <result name="VBOX_E_DONT_CALL_AGAIN">
     6391          Do not call again, this method is a NOP.
     6392        </result>
    63546393      </desc>
    63556394    </method>
     
    63756414        message describing the failure.
    63766415
     6416        <result name="VBOX_E_DONT_CALL_AGAIN">
     6417          Do not call again, this method is a NOP.
     6418        </result>
    63776419      </desc>
    63786420      <param name="device" type="IUSBDevice" dir="in">
     
    64036445        should use query the corresponding collections to find out what has
    64046446        changed.
     6447        <result name="VBOX_E_DONT_CALL_AGAIN">
     6448          Do not call again, this method is a NOP.
     6449        </result>
    64056450      </desc>
    64066451      <param name="scope" type="Scope" dir="in">
     
    64696514        </note>
    64706515
     6516        <result name="VBOX_E_DONT_CALL_AGAIN">
     6517          Do not call again, this method is a NOP.
     6518        </result>
    64716519      </desc>
    64726520      <param name="fatal" type="boolean" dir="in">
     
    65016549          actually manages console window activation.
    65026550        </note>
     6551
     6552        <result name="VBOX_E_DONT_CALL_AGAIN">
     6553          Do not call again, this method is a NOP.
     6554        </result>
    65036555      </desc>
    65046556      <param name="canShow" type="boolean" dir="return">
     
    65456597          manages console window activation.
    65466598        </note>
     6599
     6600        <result name="VBOX_E_DONT_CALL_AGAIN">
     6601          Do not call again, this method is a NOP.
     6602        </result>
    65476603      </desc>
    65486604      <param name="winId" type="unsigned long long" dir="return">
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r28835 r28959  
    3434class AudioSniffer;
    3535class ConsoleVRDPServer;
     36class ConsoleCallbackRegistration;      /* See ConsoleImpl.cpp. */
    3637class VMMDev;
    3738class Progress;
     
    650651    ComObjPtr<Progress> mptrCancelableProgress;
    651652
    652     typedef std::list <ComPtr<IConsoleCallback> > CallbackList;
     653    typedef std::list<ConsoleCallbackRegistration> CallbackList;
    653654    CallbackList mCallbacks;
    654655
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