Changeset 22686 in vbox
- Timestamp:
- Sep 1, 2009 10:09:14 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 51799
- Location:
- trunk/src/VBox/Frontends/VBoxManage
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
r22562 r22686 1829 1829 * after the session is closed) */ 1830 1830 1831 #ifdef USE_XPCOM_QUEUE1831 #ifdef VBOX_WITH_XPCOM 1832 1832 nsCOMPtr<nsIEventQueue> eventQ; 1833 1833 NS_GetMainEventQ(getter_AddRefs(eventQ)); 1834 1834 #endif 1835 1835 1836 #ifdef USE_XPCOM_QUEUE1836 #ifdef VBOX_WITH_XPCOM 1837 1837 HandlerArg handlerArg = { 0, NULL, eventQ, virtualBox, session }; 1838 1838 #else … … 1917 1917 session->Close(); 1918 1918 1919 #ifdef USE_XPCOM_QUEUE1919 #ifdef VBOX_WITH_XPCOM 1920 1920 eventQ->ProcessPendingEvents(); 1921 1921 #endif -
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h
r22562 r22686 108 108 char **argv; 109 109 110 #ifdef USE_XPCOM_QUEUE110 #ifdef VBOX_WITH_XPCOM 111 111 nsCOMPtr<nsIEventQueue> eventQ; 112 112 #endif -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp
r22305 r22686 35 35 36 36 #include <VBox/log.h> 37 #include <iprt/asm.h> 38 #include <iprt/semaphore.h> 37 39 #include <iprt/stream.h> 40 #include <iprt/string.h> 41 #include <iprt/time.h> 38 42 #include <iprt/thread.h> 39 #include <iprt/time.h>40 43 41 44 #ifdef USE_XPCOM_QUEUE 42 45 # include <sys/select.h> 46 # include <errno.h> 43 47 #endif 44 48 … … 59 63 refcnt = 0; 60 64 #endif 61 } 62 63 virtual ~GuestPropertyCallback() {} 65 #ifndef USE_XPCOM_QUEUE 66 int rc = RTSemEventMultiCreate(&mhEvent); 67 if (RT_FAILURE(rc)) 68 mhEvent = NIL_RTSEMEVENTMULTI; 69 #endif 70 } 71 72 virtual ~GuestPropertyCallback() 73 { 74 #ifndef USE_XPCOM_QUEUE 75 RTSemEventMultiDestroy(mhEvent); 76 mhEvent = NIL_RTSEMEVENTMULTI; 77 #endif 78 } 64 79 65 80 #ifndef VBOX_WITH_XPCOM … … 150 165 IN_BSTR flags) 151 166 { 152 HRESULT rc = S_OK;153 167 Utf8Str utf8Name(name); 154 168 Guid uuid(machineId); 155 if ( SUCCEEDED (rc) 156 && uuid == mUuid 169 if ( uuid == mUuid 157 170 && RTStrSimplePatternMultiMatch(mPatterns, RTSTR_MAX, 158 171 utf8Name.raw(), RTSTR_MAX, NULL)) 159 172 { 160 RTPrintf("Name: %lS, value: %lS, flags: %lS\n", name, value, 161 flags); 162 mSignalled = true; 163 } 164 return rc; 165 } 166 167 bool Signalled(void) { return mSignalled; } 173 RTPrintf("Name: %lS, value: %lS, flags: %lS\n", name, value, flags); 174 ASMAtomicWriteBool(&mSignalled, true); 175 #ifndef USE_XPCOM_QUEUE 176 int rc = RTSemEventMultiSignal(mhEvent); 177 AssertRC(rc); 178 #endif 179 } 180 return S_OK; 181 } 182 183 bool Signalled(void) const 184 { 185 return mSignalled; 186 } 187 188 #ifndef USE_XPCOM_QUEUE 189 /** Wrapper around RTSemEventMultiWait. */ 190 int wait(uint32_t cMillies) 191 { 192 return RTSemEventMultiWait(mhEvent, cMillies); 193 } 194 #endif 168 195 169 196 private: 170 bool mSignalled;197 bool volatile mSignalled; 171 198 const char *mPatterns; 172 199 Guid mUuid; … … 174 201 long refcnt; 175 202 #endif 176 203 #ifndef USE_XPCOM_QUEUE 204 /** Event semaphore to wait on. */ 205 RTSEMEVENTMULTI mhEvent; 206 #endif 177 207 }; 178 208 179 209 #ifdef VBOX_WITH_XPCOM 180 210 NS_DECL_CLASSINFO(GuestPropertyCallback) 181 NS_IMPL_ ISUPPORTS1_CI(GuestPropertyCallback, IVirtualBoxCallback)211 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(GuestPropertyCallback, IVirtualBoxCallback) 182 212 #endif /* VBOX_WITH_XPCOM */ 183 213 … … 194 224 "\n"); 195 225 RTPrintf("VBoxManage guestproperty wait <vmname>|<uuid> <patterns>\n" 196 " [--timeout < timeout>]\n"226 " [--timeout <milliseconds>] [--fail-on-timeout]\n" 197 227 "\n"); 198 228 } … … 395 425 * Handle arguments 396 426 */ 397 const char *pszPatterns = NULL; 398 uint32_t u32Timeout = RT_INDEFINITE_WAIT; 399 bool usageOK = true; 427 bool fFailOnTimeout = false; 428 const char *pszPatterns = NULL; 429 uint32_t cMsTimeout = RT_INDEFINITE_WAIT; 430 bool usageOK = true; 400 431 if (a->argc < 2) 401 432 usageOK = false; … … 418 449 { 419 450 if ( i + 1 >= a->argc 420 || RTStrToUInt32Full(a->argv[i + 1], 10, &u32Timeout) 421 != VINF_SUCCESS 422 ) 451 || RTStrToUInt32Full(a->argv[i + 1], 10, &cMsTimeout) != VINF_SUCCESS) 423 452 usageOK = false; 424 453 else 425 454 ++i; 426 455 } 456 else if (!strcmp(a->argv[i], "--fail-on-timeout")) 457 fFailOnTimeout = true; 427 458 else 428 459 usageOK = false; … … 433 464 /* 434 465 * Set up the callback and wait. 466 * 467 * The waiting is done is 1 sec at the time since there there are races 468 * between the callback and us going to sleep. This also guards against 469 * neglecting XPCOM event queues as well as any select timeout restrictions. 435 470 */ 436 471 Bstr uuid; 437 472 machine->COMGETTER(Id)(uuid.asOutParam()); 438 GuestPropertyCallback *cbImpl = new GuestPropertyCallback(pszPatterns, uuid);473 GuestPropertyCallback *cbImpl = new GuestPropertyCallback(pszPatterns, uuid); 439 474 ComPtr<IVirtualBoxCallback> callback; 440 rc = createCallbackWrapper((IVirtualBoxCallback *)cbImpl, callback.asOutParam());475 rc = createCallbackWrapper((IVirtualBoxCallback *)cbImpl, callback.asOutParam()); 441 476 if (FAILED(rc)) 477 { 478 RTPrintf("Error creating callback wrapper: %Rhrc\n", rc); 442 479 return 1; 443 a->virtualBox->RegisterCallback (callback); 444 bool stop = false; 480 } 481 a->virtualBox->RegisterCallback(callback); 482 445 483 #ifdef USE_XPCOM_QUEUE 446 int max_fd = a->eventQ->GetEventQueueSelectFD(); 447 #endif 448 for (; !stop && u32Timeout > 0; u32Timeout -= RT_MIN(u32Timeout, 1000)) 449 { 484 int const fdQueue = a->eventQ->GetEventQueueSelectFD(); 485 #endif 486 uint64_t const StartMilliTS = RTTimeMilliTS(); 487 for (;;) 488 { 489 #ifdef VBOX_WITH_XPCOM 490 /* Process pending XPCOM events. */ 491 a->eventQ->ProcessPendingEvents(); 492 #endif 493 494 /* Signalled? */ 495 if (cbImpl->Signalled()) 496 break; 497 498 /* Figure out how much we have left to wait and if we've timed out already. */ 499 uint32_t cMsLeft; 500 if (cMsTimeout == RT_INDEFINITE_WAIT) 501 cMsLeft = RT_INDEFINITE_WAIT; 502 else 503 { 504 uint64_t cMsElapsed = RTTimeMilliTS() - StartMilliTS; 505 if (cMsElapsed >= cMsTimeout) 506 break; /* timeout */ 507 cMsLeft = cMsTimeout - (uint32_t)cMsElapsed; 508 } 509 510 /* Wait in a platform specific manner. */ 450 511 #ifdef USE_XPCOM_QUEUE 451 int prc;452 512 fd_set fdset; 513 FD_ZERO(&fdset); 514 FD_SET(fdQueue, &fdset); 453 515 struct timeval tv; 454 FD_ZERO (&fdset); 455 FD_SET(max_fd, &fdset); 456 tv.tv_sec = RT_MIN(u32Timeout, 1000); 457 tv.tv_usec = u32Timeout > 1000 ? 0 : u32Timeout * 1000; 458 RTTIMESPEC TimeNow; 459 uint64_t u64Time = RTTimeSpecGetMilli(RTTimeNow(&TimeNow)); 460 prc = select(max_fd + 1, &fdset, NULL, NULL, &tv); 516 if ( cMsLeft == RT_INDEFINITE_WAIT 517 || cMsLeft >= 1000) 518 { 519 tv.tv_sec = 1; 520 tv.tv_usec = 0; 521 } 522 else 523 { 524 tv.tv_sec = 0; 525 tv.tv_usec = cMsLeft * 1000; 526 } 527 int prc = select(fdQueue + 1, &fdset, NULL, NULL, &tv); 461 528 if (prc == -1) 462 529 { 463 RTPrintf("Error waiting for event.\n"); 464 stop = true; 465 } 466 else if (prc != 0) 467 { 468 uint64_t u64NextTime = RTTimeSpecGetMilli(RTTimeNow(&TimeNow)); 469 u32Timeout += (uint32_t)(u64Time + 1000 - u64NextTime); 470 a->eventQ->ProcessPendingEvents(); 471 if (cbImpl->Signalled()) 472 stop = true; 530 RTPrintf("Error waiting for event: %s (%d)\n", strerror(errno), errno); 531 break; 473 532 } 474 533 #else /* !USE_XPCOM_QUEUE */ 475 /** @todo Use a semaphore. But I currently don't have a Windows system 476 * running to test on. */ 477 /**@todo r=bird: get to it!*/ 478 RTThreadSleep(RT_MIN(1000, u32Timeout)); 479 if (cbImpl->Signalled()) 480 stop = true; 534 /** @todo make this faster on Mac OS X (and possible Windows+OS/2 too), we should probably use WaitNextEvent() to wait here. */ 535 int vrc = cbImpl->wait(RT_MIN(cMsLeft, 1000)); 536 if ( vrc != VERR_TIMEOUT 537 && RT_FAILURE(vrc)) 538 { 539 RTPrintf("Error waiting for event: %Rrc\n", vrc); 540 break; 541 } 481 542 #endif /* !USE_XPCOM_QUEUE */ 482 } 483 484 /* 485 * Clean up the callback .543 } /* for (;;) */ 544 545 /* 546 * Clean up the callback and report timeout. 486 547 */ 487 548 a->virtualBox->UnregisterCallback(callback); 549 550 int rcRet = 0; 488 551 if (!cbImpl->Signalled()) 552 { 489 553 RTPrintf("Time out or interruption while waiting for a notification.\n"); 490 /*491 * Done.492 */493 return 0;554 if (fFailOnTimeout) 555 rcRet = 2; 556 } 557 return rcRet; 494 558 } 495 559 … … 522 586 return errorSyntax(USAGE_GUESTPROPERTY, "Incorrect parameters"); 523 587 } 588
Note:
See TracChangeset
for help on using the changeset viewer.