Changeset 34417 in vbox
- Timestamp:
- Nov 26, 2010 5:18:18 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 68188
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/VirtualBoxClientImpl.cpp
r34215 r34417 5 5 6 6 /* 7 * Copyright (C) 20 06-2008Oracle Corporation7 * Copyright (C) 2010 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 16 16 */ 17 17 18 #include " USBDeviceImpl.h"18 #include "VirtualBoxClientImpl.h" 19 19 20 20 #include "AutoCaller.h" 21 #include "VBoxEvents.h" 21 22 #include "Logging.h" 22 23 24 #include <iprt/thread.h> 25 #include <iprt/critsect.h> 26 #include <iprt/semaphore.h> 23 27 #include <iprt/cpp/utils.h> 24 28 29 30 /** Waiting time between probing whether VBoxSVC is alive. */ 31 #define VBOXCLIENT_DEFAULT_INTERVAL 30000 32 33 25 34 // constructor / destructor 26 35 ///////////////////////////////////////////////////////////////////////////// 27 36 28 DEFINE_EMPTY_CTOR_DTOR (OUSBDevice)29 30 HRESULT OUSBDevice::FinalConstruct()31 { 32 return S_OK;33 } 34 35 void OUSBDevice::FinalRelease()36 { 37 uninit 37 DEFINE_EMPTY_CTOR_DTOR(VirtualBoxClient) 38 39 HRESULT VirtualBoxClient::FinalConstruct() 40 { 41 return init(); 42 } 43 44 void VirtualBoxClient::FinalRelease() 45 { 46 uninit(); 38 47 } 39 48 … … 42 51 43 52 /** 44 * Initializes the USB deviceobject.53 * Initializes the VirtualBoxClient object. 45 54 * 46 55 * @returns COM result indicator 47 * @param aUSBDevice The USB device (interface) to clone. 48 */ 49 HRESULT OUSBDevice::init(IUSBDevice *aUSBDevice) 50 { 51 LogFlowThisFunc(("aUSBDevice=%p\n", aUSBDevice)); 52 53 ComAssertRet(aUSBDevice, E_INVALIDARG); 54 56 */ 57 HRESULT VirtualBoxClient::init() 58 { 59 LogFlowThisFunc(("\n")); 60 61 HRESULT rc; 55 62 /* Enclose the state transition NotReady->InInit->Ready */ 56 63 AutoInitSpan autoInitSpan(this); 57 64 AssertReturn(autoInitSpan.isOk(), E_FAIL); 58 65 59 HRESULT hrc = aUSBDevice->COMGETTER(VendorId)(&unconst(mData.vendorId)); 60 ComAssertComRCRet(hrc, hrc); 61 ComAssertRet(mData.vendorId, E_INVALIDARG); 62 63 hrc = aUSBDevice->COMGETTER(ProductId)(&unconst(mData.productId)); 64 ComAssertComRCRet(hrc, hrc); 65 66 hrc = aUSBDevice->COMGETTER(Revision)(&unconst(mData.revision)); 67 ComAssertComRCRet(hrc, hrc); 68 69 hrc = aUSBDevice->COMGETTER(Manufacturer)(unconst(mData.manufacturer).asOutParam()); 70 ComAssertComRCRet(hrc, hrc); 71 72 hrc = aUSBDevice->COMGETTER(Product)(unconst(mData.product).asOutParam()); 73 ComAssertComRCRet(hrc, hrc); 74 75 hrc = aUSBDevice->COMGETTER(SerialNumber)(unconst(mData.serialNumber).asOutParam()); 76 ComAssertComRCRet(hrc, hrc); 77 78 hrc = aUSBDevice->COMGETTER(Address)(unconst(mData.address).asOutParam()); 79 ComAssertComRCRet(hrc, hrc); 80 81 hrc = aUSBDevice->COMGETTER(Port)(&unconst(mData.port)); 82 ComAssertComRCRet(hrc, hrc); 83 84 hrc = aUSBDevice->COMGETTER(Port)(&unconst(mData.version)); 85 ComAssertComRCRet(hrc, hrc); 86 87 hrc = aUSBDevice->COMGETTER(Port)(&unconst(mData.portVersion)); 88 ComAssertComRCRet(hrc, hrc); 89 90 hrc = aUSBDevice->COMGETTER(Remote)(&unconst(mData.remote)); 91 ComAssertComRCRet(hrc, hrc); 92 93 Bstr uuid; 94 hrc = aUSBDevice->COMGETTER(Id)(uuid.asOutParam()); 95 ComAssertComRCRet(hrc, hrc); 96 unconst(mData.id) = Guid(uuid); 66 rc = unconst(mData.m_pVirtualBox).createLocalObject(CLSID_VirtualBox); 67 AssertComRCReturnRC(rc); 68 69 rc = unconst(mData.m_pEventSource).createObject(); 70 AssertComRCReturnRC(rc); 71 rc = mData.m_pEventSource->init(static_cast<IVirtualBoxClient *>(this)); 72 AssertComRCReturnRC(rc); 73 74 /* Setting up the VBoxSVC watcher thread. If anything goes wrong here it 75 * is not considered important enough to cause any sort of visible 76 * failure. The monitoring will not be done, but that's all. */ 77 mData.m_ThreadWatcher = NIL_RTTHREAD; 78 int vrc = RTSemEventCreate(&mData.m_SemEvWatcher); 79 AssertRC(vrc); 80 if (RT_SUCCESS(rc)) 81 { 82 vrc = RTThreadCreate(&mData.m_ThreadWatcher, SVCWatcherThread, 83 this, 0, RTTHREADTYPE_INFREQUENT_POLLER, 84 RTTHREADFLAGS_WAITABLE, "VBoxSVCWatcher"); 85 AssertRC(vrc); 86 } 87 else 88 { 89 RTSemEventDestroy(mData.m_SemEvWatcher); 90 mData.m_SemEvWatcher = NIL_RTSEMEVENT; 91 } 97 92 98 93 /* Confirm a successful initialization */ 99 94 autoInitSpan.setSucceeded(); 100 95 101 return S_OK;96 return rc; 102 97 } 103 98 … … 106 101 * Called either from FinalRelease() or by the parent when it gets destroyed. 107 102 */ 108 void OUSBDevice::uninit()103 void VirtualBoxClient::uninit() 109 104 { 110 105 LogFlowThisFunc(("\n")); … … 115 110 return; 116 111 117 unconst(mData.id).clear(); 118 119 unconst(mData.vendorId) = 0; 120 unconst(mData.productId) = 0; 121 unconst(mData.revision) = 0; 122 123 unconst(mData.manufacturer).setNull(); 124 unconst(mData.product).setNull(); 125 unconst(mData.serialNumber).setNull(); 126 127 unconst(mData.address).setNull(); 128 129 unconst(mData.port) = 0; 130 unconst(mData.version) = 1; 131 unconst(mData.portVersion) = 1; 132 133 unconst(mData.remote) = FALSE; 134 } 135 136 // IUSBDevice properties 137 ///////////////////////////////////////////////////////////////////////////// 138 139 /** 140 * Returns the GUID. 112 unconst(mData.m_pVirtualBox).setNull(); 113 114 if (mData.m_ThreadWatcher != NIL_RTTHREAD) 115 { 116 /* Signal the event semaphore and wait for the thread to terminate. 117 * if it hangs for some reason exit anyway, this can cause a crash 118 * though as the object will no longer be available. */ 119 RTSemEventSignal(mData.m_SemEvWatcher); 120 RTThreadWait(mData.m_ThreadWatcher, 30000, NULL); 121 mData.m_ThreadWatcher = NIL_RTTHREAD; 122 RTSemEventDestroy(mData.m_SemEvWatcher); 123 mData.m_SemEvWatcher = NIL_RTSEMEVENT; 124 } 125 } 126 127 // IVirtualBoxClient properties 128 ///////////////////////////////////////////////////////////////////////////// 129 130 /** 131 * Returns a reference to the VirtualBox object. 141 132 * 142 133 * @returns COM status code 143 * @param a IdAddress of result variable.144 */ 145 STDMETHODIMP OUSBDevice::COMGETTER(Id)(BSTR *aId)146 { 147 CheckComArgOutPointerValid(a Id);134 * @param aVirtualBox Address of result variable. 135 */ 136 STDMETHODIMP VirtualBoxClient::COMGETTER(VirtualBox)(IVirtualBox **aVirtualBox) 137 { 138 CheckComArgOutPointerValid(aVirtualBox); 148 139 149 140 AutoCaller autoCaller(this); … … 151 142 152 143 /* this is const, no need to lock */ 153 Guid(mData.id).toUtf16().detachTo(aId); 154 144 mData.m_pVirtualBox.queryInterfaceTo(aVirtualBox); 155 145 return S_OK; 156 146 } 157 147 158 159 /** 160 * Returns the vendor Id. 148 /** 149 * Create a new Session object and return a reference to it. 161 150 * 162 151 * @returns COM status code 163 * @param aVendorId Where to store the vendor id. 164 */ 165 STDMETHODIMP OUSBDevice::COMGETTER(VendorId)(USHORT *aVendorId) 166 { 167 CheckComArgOutPointerValid(aVendorId); 152 * @param aSession Address of result variable. 153 */ 154 STDMETHODIMP VirtualBoxClient::COMGETTER(Session)(ISession **aSession) 155 { 156 HRESULT rc; 157 CheckComArgOutPointerValid(aSession); 168 158 169 159 AutoCaller autoCaller(this); 170 160 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 171 161 172 /* this is const, no need to lock */ 173 *aVendorId = mData.vendorId; 174 175 return S_OK; 176 } 177 178 179 /** 180 * Returns the product Id. 162 /* this is not stored in this object, no need to lock */ 163 ComPtr<ISession> pSession; 164 rc = pSession.createInprocObject(CLSID_Session); 165 if (SUCCEEDED(rc)) 166 pSession.queryInterfaceTo(aSession); 167 168 return rc; 169 } 170 171 /** 172 * Return reference to the EventSource associated with this object. 181 173 * 182 174 * @returns COM status code 183 * @param a ProductId Where to store the product id.184 */ 185 STDMETHODIMP OUSBDevice::COMGETTER(ProductId)(USHORT *aProductId)186 { 187 CheckComArgOutPointerValid(a ProductId);175 * @param aEventSource Address of result variable. 176 */ 177 STDMETHODIMP VirtualBoxClient::COMGETTER(EventSource)(IEventSource **aEventSource) 178 { 179 CheckComArgOutPointerValid(aEventSource); 188 180 189 181 AutoCaller autoCaller(this); … … 191 183 192 184 /* this is const, no need to lock */ 193 *aProductId = mData.productId; 194 195 return S_OK; 196 } 197 198 199 /** 200 * Returns the revision BCD. 201 * 202 * @returns COM status code 203 * @param aRevision Where to store the revision BCD. 204 */ 205 STDMETHODIMP OUSBDevice::COMGETTER(Revision)(USHORT *aRevision) 206 { 207 CheckComArgOutPointerValid(aRevision); 208 209 AutoCaller autoCaller(this); 210 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 211 212 /* this is const, no need to lock */ 213 *aRevision = mData.revision; 214 215 return S_OK; 216 } 217 218 /** 219 * Returns the manufacturer string. 220 * 221 * @returns COM status code 222 * @param aManufacturer Where to put the return string. 223 */ 224 STDMETHODIMP OUSBDevice::COMGETTER(Manufacturer)(BSTR *aManufacturer) 225 { 226 CheckComArgOutPointerValid(aManufacturer); 227 228 AutoCaller autoCaller(this); 229 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 230 231 /* this is const, no need to lock */ 232 mData.manufacturer.cloneTo(aManufacturer); 233 234 return S_OK; 235 } 236 237 238 /** 239 * Returns the product string. 240 * 241 * @returns COM status code 242 * @param aProduct Where to put the return string. 243 */ 244 STDMETHODIMP OUSBDevice::COMGETTER(Product)(BSTR *aProduct) 245 { 246 CheckComArgOutPointerValid(aProduct); 247 248 AutoCaller autoCaller(this); 249 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 250 251 /* this is const, no need to lock */ 252 mData.product.cloneTo(aProduct); 253 254 return S_OK; 255 } 256 257 258 /** 259 * Returns the serial number string. 260 * 261 * @returns COM status code 262 * @param aSerialNumber Where to put the return string. 263 */ 264 STDMETHODIMP OUSBDevice::COMGETTER(SerialNumber)(BSTR *aSerialNumber) 265 { 266 CheckComArgOutPointerValid(aSerialNumber); 267 268 AutoCaller autoCaller(this); 269 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 270 271 /* this is const, no need to lock */ 272 mData.serialNumber.cloneTo(aSerialNumber); 273 274 return S_OK; 275 } 276 277 278 /** 279 * Returns the host specific device address. 280 * 281 * @returns COM status code 282 * @param aAddress Where to put the return string. 283 */ 284 STDMETHODIMP OUSBDevice::COMGETTER(Address)(BSTR *aAddress) 285 { 286 CheckComArgOutPointerValid(aAddress); 287 288 AutoCaller autoCaller(this); 289 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 290 291 /* this is const, no need to lock */ 292 mData.address.cloneTo(aAddress); 293 294 return S_OK; 295 } 296 297 STDMETHODIMP OUSBDevice::COMGETTER(Port)(USHORT *aPort) 298 { 299 CheckComArgOutPointerValid(aPort); 300 301 AutoCaller autoCaller(this); 302 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 303 304 /* this is const, no need to lock */ 305 *aPort = mData.port; 306 307 return S_OK; 308 } 309 310 STDMETHODIMP OUSBDevice::COMGETTER(Version)(USHORT *aVersion) 311 { 312 CheckComArgOutPointerValid(aVersion); 313 314 AutoCaller autoCaller(this); 315 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 316 317 /* this is const, no need to lock */ 318 *aVersion = mData.version; 319 320 return S_OK; 321 } 322 323 STDMETHODIMP OUSBDevice::COMGETTER(PortVersion)(USHORT *aPortVersion) 324 { 325 CheckComArgOutPointerValid(aPortVersion); 326 327 AutoCaller autoCaller(this); 328 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 329 330 /* this is const, no need to lock */ 331 *aPortVersion = mData.portVersion; 332 333 return S_OK; 334 } 335 336 STDMETHODIMP OUSBDevice::COMGETTER(Remote)(BOOL *aRemote) 337 { 338 CheckComArgOutPointerValid(aRemote); 339 340 AutoCaller autoCaller(this); 341 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 342 343 /* this is const, no need to lock */ 344 *aRemote = mData.remote; 345 346 return S_OK; 185 mData.m_pEventSource.queryInterfaceTo(aEventSource); 186 187 return mData.m_pEventSource.isNull() ? E_FAIL : S_OK; 347 188 } 348 189 349 190 // private methods 350 191 ///////////////////////////////////////////////////////////////////////////// 192 193 /*static*/ 194 DECLCALLBACK(int) VirtualBoxClient::SVCWatcherThread(RTTHREAD ThreadSelf, 195 void *pvUser) 196 { 197 NOREF(ThreadSelf); 198 Assert(pvUser); 199 VirtualBoxClient *pThis = (VirtualBoxClient *)pvUser; 200 RTSEMEVENT sem = pThis->mData.m_SemEvWatcher; 201 RTMSINTERVAL cMillies = VBOXCLIENT_DEFAULT_INTERVAL; 202 int vrc; 203 204 /* The likelihood of early crashes are high, so start with a short wait. */ 205 vrc = RTSemEventWait(sem, cMillies / 2); 206 207 /* As long as the waiting times out keep retrying the wait. */ 208 while (RT_FAILURE(vrc)) 209 { 210 { 211 HRESULT rc = S_OK; 212 ComPtr<IVirtualBox> pV = pThis->mData.m_pVirtualBox; 213 if (!pV.isNull()) 214 { 215 ULONG rev; 216 rc = pV->COMGETTER(Revision)(&rev); 217 if (FAILED_DEAD_INTERFACE(rc)) 218 { 219 LogRel(("VirtualBoxClient: detected unresponsive VBoxSVC (rc=%Rhrc)", rc)); 220 fireVBoxSVCUnavailableEvent(pThis->mData.m_pEventSource); 221 222 /* Throw away the VirtualBox reference, it's no longer 223 * usable as VBoxSVC terminated in the mean time. */ 224 unconst(pThis->mData.m_pVirtualBox).setNull(); 225 } 226 } 227 else 228 { 229 /* Try to get a new VirtualBox reference straight away, and if 230 * this fails use an increased waiting time as very frequent 231 * restart attempts in some wedged config can cause high CPU 232 * and disk load. */ 233 rc = unconst(pThis->mData.m_pVirtualBox).createLocalObject(CLSID_VirtualBox); 234 if (FAILED(rc)) 235 cMillies = 3 * VBOXCLIENT_DEFAULT_INTERVAL; 236 else 237 cMillies = VBOXCLIENT_DEFAULT_INTERVAL; 238 } 239 } 240 vrc = RTSemEventWait(sem, cMillies); 241 } 242 return 0; 243 } 244 351 245 /* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note:
See TracChangeset
for help on using the changeset viewer.