VirtualBox

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


Ignore:
Timestamp:
Apr 15, 2010 9:18:31 AM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
60109
Message:

Main/HostHardwareLinux: generalised the VBoxMainHotplugWaiter class to allow for runtime implementation selection

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/HostHardwareLinux.h

    r25728 r28349  
    4444        /** The device node of the drive. */
    4545        iprt::MiniString mDevice;
    46         /** The hal unique device identifier, if available. */
     46        /** A unique identifier for the device, if available.  This should be
     47         * kept consistant accross different probing methods of a given
     48         * platform if at all possible. */
    4749        iprt::MiniString mUdi;
    4850        /** A textual description of the drive. */
     
    124126        /** The device node of the device. */
    125127        iprt::MiniString mDevice;
    126         /** The sysfs path of the device. */
     128        /** The system identifier of the device.  Specific to the probing
     129         * method. */
    127130        iprt::MiniString mSysfsPath;
    128131        /** Type for the list of interfaces. */
    129132        typedef std::vector<iprt::MiniString> InterfaceList;
    130         /** The sysfs paths of the device's interfaces. */
     133        /** The system IDs of the device's interfaces. */
    131134        InterfaceList mInterfaces;
    132135
    133136        /** Constructors */
    134137        USBDeviceInfo(const iprt::MiniString &aDevice,
    135                       const iprt::MiniString &aSysfsPath)
     138                      const iprt::MiniString &aSystemID)
    136139            : mDevice(aDevice),
    137               mSysfsPath(aSysfsPath)
     140              mSysfsPath(aSystemID)
    138141        { }
    139142    };
     
    172175/** Convenience typedef. */
    173176typedef VBoxMainUSBDeviceInfo::USBDeviceInfo::InterfaceList USBInterfaceList;
     177
     178/** Implementation of the hotplug waiter class below */
     179class VBoxMainHotplugWaiterImpl
     180{
     181public:
     182    VBoxMainHotplugWaiterImpl (void) {}
     183    virtual ~VBoxMainHotplugWaiterImpl (void) {}
     184    /** @copydoc VBoxMainHotplugWaiter::Wait */
     185    virtual int Wait (RTMSINTERVAL cMillies) = 0;
     186    /** @copydoc VBoxMainHotplugWaiter::Interrupt */
     187    virtual void Interrupt (void) = 0;
     188};
    174189
    175190/**
     
    181196class VBoxMainHotplugWaiter
    182197{
    183     /** Opaque context struct. */
    184     struct Context;
    185 
    186     /** Opaque waiter context. */
    187     Context *mContext;
    188 public:
    189     /** Constructor */
     198    /** Class implementation. */
     199    VBoxMainHotplugWaiterImpl *mImpl;
     200public:
     201    /** Constructor.  Responsible for selecting the implementation. */
    190202    VBoxMainHotplugWaiter (void);
    191203    /** Destructor. */
    192     ~VBoxMainHotplugWaiter (void);
     204    ~VBoxMainHotplugWaiter (void)
     205    {
     206        delete mImpl;
     207    }
    193208    /**
    194209     * Wait for a hotplug event.
     
    202217     * @param    cMillies   How long to wait for at most.
    203218     */
    204     int Wait (RTMSINTERVAL cMillies);
     219    int Wait (RTMSINTERVAL cMillies)
     220    {
     221        return mImpl->Wait(cMillies);
     222    }
    205223    /**
    206224     * Interrupts an active wait.  In the current implementation, the wait
    207225     * may not return until up to two seconds after calling this method.
    208226     */
    209     void Interrupt (void);
     227    void Interrupt (void)
     228    {
     229        mImpl->Interrupt();
     230    }
    210231};
    211232
  • trunk/src/VBox/Main/linux/HostHardwareLinux.cpp

    r28315 r28349  
    10531053}
    10541054
    1055 struct VBoxMainHotplugWaiter::Context
    1056 {
    10571055#if defined RT_OS_LINUX && defined VBOX_WITH_DBUS
     1056class hotplugDBusImpl : public VBoxMainHotplugWaiterImpl
     1057{
    10581058    /** The connection to DBus */
    10591059    RTMemAutoPtr <DBusConnection, VBoxHalShutdownPrivate> mConnection;
     
    10631063    /** A flag to say that we wish to interrupt the current wait. */
    10641064    volatile bool mInterrupt;
     1065
     1066public:
     1067    /** Test whether this implementation can be used on the current system */
     1068    static bool HalAvailable(void)
     1069    {
     1070        RTMemAutoPtr<DBusConnection, VBoxHalShutdown> dbusConnection;
     1071
     1072        /* Try to open a test connection to hal */
     1073        if (RT_SUCCESS(RTDBusLoadLib()) && RT_SUCCESS(halInit (&dbusConnection)))
     1074            return !!dbusConnection;
     1075        return false;
     1076    }
     1077
    10651078    /** Constructor */
    1066     Context() : mTriggered(false), mInterrupt(false) {}
    1067 #endif  /* defined RT_OS_LINUX && defined VBOX_WITH_DBUS */
     1079    hotplugDBusImpl (void);
     1080    virtual ~hotplugDBusImpl (void);
     1081    /** @copydoc VBoxMainHotplugWaiter::Wait */
     1082    virtual int Wait (RTMSINTERVAL cMillies);
     1083    /** @copydoc VBoxMainHotplugWaiter::Interrupt */
     1084    virtual void Interrupt (void);
    10681085};
    10691086
     
    10721089 * the Context structure when a device (not necessarily USB) is added or
    10731090 * removed. */
    1074 VBoxMainHotplugWaiter::VBoxMainHotplugWaiter ()
    1075 {
    1076 #if defined RT_OS_LINUX && defined VBOX_WITH_DBUS
     1091hotplugDBusImpl::hotplugDBusImpl (void) : mTriggered(false), mInterrupt(false)
     1092{
    10771093    int rc = VINF_SUCCESS;
    10781094
    1079     mContext = new Context;
    10801095    if (RT_SUCCESS(RTDBusLoadLib()))
    10811096    {
    1082         for (unsigned i = 0; RT_SUCCESS(rc) && i < 5 && !mContext->mConnection; ++i)
    1083         {
    1084             rc = halInitPrivate (&mContext->mConnection);
    1085         }
    1086         if (!mContext->mConnection)
     1097        for (unsigned i = 0; RT_SUCCESS(rc) && i < 5 && !mConnection; ++i)
     1098        {
     1099            rc = halInitPrivate (&mConnection);
     1100        }
     1101        if (!mConnection)
    10871102            rc = VERR_NOT_SUPPORTED;
    10881103        DBusMessage *pMessage;
    10891104        while (   RT_SUCCESS(rc)
    1090                && (pMessage = dbus_connection_pop_message (mContext->mConnection.get())) != NULL)
     1105               && (pMessage = dbus_connection_pop_message (mConnection.get())) != NULL)
    10911106            dbus_message_unref (pMessage); /* empty the message queue. */
    10921107        if (   RT_SUCCESS(rc)
    1093             && !dbus_connection_add_filter (mContext->mConnection.get(),
     1108            && !dbus_connection_add_filter (mConnection.get(),
    10941109                                            dbusFilterFunction,
    1095                                             (void *) &mContext->mTriggered, NULL))
     1110                                            (void *) &mTriggered, NULL))
    10961111            rc = VERR_NO_MEMORY;
    10971112        if (RT_FAILURE(rc))
    1098             mContext->mConnection.reset();
    1099     }
    1100 #endif /* defined RT_OS_LINUX && defined VBOX_WITH_DBUS */
     1113            mConnection.reset();
     1114    }
    11011115}
    11021116
    11031117/* Destructor */
    1104 VBoxMainHotplugWaiter::~VBoxMainHotplugWaiter ()
    1105 {
    1106 #if defined RT_OS_LINUX && defined VBOX_WITH_DBUS
    1107     if (!!mContext->mConnection)
    1108         dbus_connection_remove_filter (mContext->mConnection.get(), dbusFilterFunction,
    1109                                        (void *) &mContext->mTriggered);
    1110     delete mContext;
    1111 #endif /* defined RT_OS_LINUX && defined VBOX_WITH_DBUS */
     1118hotplugDBusImpl::~hotplugDBusImpl ()
     1119{
     1120    if (!!mConnection)
     1121        dbus_connection_remove_filter (mConnection.get(), dbusFilterFunction,
     1122                                       (void *) &mTriggered);
    11121123}
    11131124
     
    11151126 * connection.  Because the connection is private we don't have to worry about
    11161127 * blocking other users. */
    1117 int VBoxMainHotplugWaiter::Wait(RTMSINTERVAL cMillies)
     1128int hotplugDBusImpl::Wait(RTMSINTERVAL cMillies)
    11181129{
    11191130    int rc = VINF_SUCCESS;
    1120 #if defined RT_OS_LINUX && defined VBOX_WITH_DBUS
    1121     if (!mContext->mConnection)
     1131    if (!mConnection)
    11221132        rc = VERR_NOT_SUPPORTED;
    11231133    bool connected = true;
    1124     mContext->mTriggered = false;
    1125     mContext->mInterrupt = false;
     1134    mTriggered = false;
     1135    mInterrupt = false;
    11261136    unsigned cRealMillies;
    11271137    if (cMillies != RT_INDEFINITE_WAIT)
     
    11291139    else
    11301140        cRealMillies = DBUS_POLL_TIMEOUT;
    1131     while (   RT_SUCCESS(rc) && connected && !mContext->mTriggered
    1132            && !mContext->mInterrupt)
    1133     {
    1134         connected = dbus_connection_read_write_dispatch (mContext->mConnection.get(),
     1141    while (   RT_SUCCESS(rc) && connected && !mTriggered
     1142           && !mInterrupt)
     1143    {
     1144        connected = dbus_connection_read_write_dispatch (mConnection.get(),
    11351145                                                         cRealMillies);
    1136         if (mContext->mInterrupt)
     1146        if (mInterrupt)
    11371147            LogFlowFunc(("wait loop interrupted\n"));
    11381148        if (cMillies != RT_INDEFINITE_WAIT)
    1139             mContext->mInterrupt = true;
     1149            mInterrupt = true;
    11401150    }
    11411151    if (!connected)
    11421152        rc = VERR_TRY_AGAIN;
    1143 #else  /* !(defined RT_OS_LINUX && defined VBOX_WITH_DBUS) */
    1144     rc = VERR_NOT_IMPLEMENTED;
     1153    return rc;
     1154}
     1155
     1156/* Set a flag to tell the Wait not to resume next time it times out. */
     1157void hotplugDBusImpl::Interrupt()
     1158{
     1159    LogFlowFunc(("\n"));
     1160    mInterrupt = true;
     1161}
    11451162#endif  /* !(defined RT_OS_LINUX && defined VBOX_WITH_DBUS) */
    1146     return rc;
    1147 }
    1148 
    1149 /* Set a flag to tell the Wait not to resume next time it times out. */
    1150 void VBoxMainHotplugWaiter::Interrupt()
     1163
     1164class hotplugNullImpl : public VBoxMainHotplugWaiterImpl
     1165{
     1166public:
     1167    hotplugNullImpl (void) {}
     1168    virtual ~hotplugNullImpl (void) {}
     1169    /** @copydoc VBoxMainHotplugWaiter::Wait */
     1170    virtual int Wait (RTMSINTERVAL)
     1171    {
     1172        return VERR_NOT_SUPPORTED;
     1173    }
     1174    /** @copydoc VBoxMainHotplugWaiter::Interrupt */
     1175    virtual void Interrupt (void) {}
     1176};
     1177
     1178VBoxMainHotplugWaiter::VBoxMainHotplugWaiter(void)
    11511179{
    11521180#if defined RT_OS_LINUX && defined VBOX_WITH_DBUS
    1153     LogFlowFunc(("\n"));
    1154     mContext->mInterrupt = true;
    1155 #endif  /* defined RT_OS_LINUX && defined VBOX_WITH_DBUS */
    1156 }
    1157 
     1181    if (hotplugDBusImpl::HalAvailable())
     1182    {
     1183        mImpl = new hotplugDBusImpl;
     1184        return;
     1185    }
     1186#endif  /* !(defined RT_OS_LINUX && defined VBOX_WITH_DBUS) */
     1187    mImpl = new hotplugNullImpl;
     1188}
    11581189
    11591190class sysfsPathHandler
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