Changeset 29394 in vbox for trunk/src/VBox/HostServices/GuestProperties
- Timestamp:
- May 12, 2010 1:27:04 AM (15 years ago)
- Location:
- trunk/src/VBox/HostServices/GuestProperties
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/GuestProperties/service.cpp
r28800 r29394 97 97 98 98 /** Are two properties equal? */ 99 bool operator== (const Property &prop) 100 { 101 return ( mName == prop.mName 102 && mValue == prop.mValue 103 && mTimestamp == prop.mTimestamp 104 && mFlags == prop.mFlags 105 ); 99 bool operator==(const Property &prop) 100 { 101 if (mTimestamp != prop.mTimestamp) 102 return false; 103 if (mFlags != prop.mFlags) 104 return false; 105 if (mName != prop.mName) 106 return false; 107 if (mValue != prop.mValue) 108 return false; 109 return true; 106 110 } 107 111 … … 164 168 /** User data pointer to be supplied to the host callback function */ 165 169 void *mpvHostData; 170 /** The previous timestamp. 171 * This is used by getCurrentTimestamp() to decrease the chance of 172 * generating duplicate timestamps. */ 173 uint64_t mPrevTimestamp; 174 /** The number of consecutive timestamp adjustments that we've made. 175 * Together with mPrevTimestamp, this defines a set of obsolete timestamp 176 * values: {(mPrevTimestamp - mcTimestampAdjustments), ..., mPrevTimestamp} */ 177 uint64_t mcTimestampAdjustments; 166 178 167 179 /** … … 193 205 * - Matches the pszPatterns 194 206 */ 207 /** @todo r=bird: This incorrectly ASSUMES that mTimestamp is unique. 208 * The timestamp resolution can be very coarse on windows for instance. */ 195 209 PropertyList::const_iterator it = mGuestNotifications.begin(); 196 210 for (; it != mGuestNotifications.end() 197 && it->mTimestamp != u64Timestamp; ++it) {} 211 && it->mTimestamp != u64Timestamp; ++it) 212 {} 198 213 if (it == mGuestNotifications.end()) /* Not found */ 199 214 it = mGuestNotifications.begin(); … … 239 254 , mpfnHostCallback(NULL) 240 255 , mpvHostData(NULL) 256 , mPrevTimestamp(0) 257 , mcTimestampAdjustments(0) 241 258 { } 242 259 … … 319 336 private: 320 337 static DECLCALLBACK(int) reqThreadFn(RTTHREAD ThreadSelf, void *pvUser); 338 uint64_t getCurrentTimestamp(void); 321 339 int validateName(const char *pszName, uint32_t cbName); 322 340 int validateValue(const char *pszValue, uint32_t cbValue); … … 344 362 345 363 /** 364 * Gets the current timestamp. 365 * 366 * Since the RTTimeNow resolution can be very coarse, this method takes some 367 * simple steps to try avoid returning the same timestamp for two consecutive 368 * calls. Code like getOldNotification() more or less assumes unique 369 * timestamps. 370 * 371 * @returns Nanosecond timestamp. 372 */ 373 uint64_t Service::getCurrentTimestamp(void) 374 { 375 RTTIMESPEC time; 376 uint64_t u64NanoTS = RTTimeSpecGetNano(RTTimeNow(&time)); 377 if (mPrevTimestamp - u64NanoTS > mcTimestampAdjustments) 378 mcTimestampAdjustments = 0; 379 else 380 { 381 mcTimestampAdjustments++; 382 u64NanoTS = mPrevTimestamp + 1; 383 } 384 this->mPrevTimestamp = u64NanoTS; 385 return u64NanoTS; 386 } 387 388 /** 346 389 * Check that a string fits our criteria for a property name. 347 390 * … … 572 615 uint32_t cchFlags = 0; 573 616 uint32_t fFlags = NILFLAG; 574 RTTIMESPEC time; 575 uint64_t u64TimeNano = RTTimeSpecGetNano(RTTimeNow(&time)); 617 uint64_t u64TimeNano = getCurrentTimestamp(); 576 618 577 619 LogFlowThisFunc(("\n")); … … 702 744 if (rc == VINF_SUCCESS && found) 703 745 { 704 RTTIMESPEC time; 705 uint64_t u64Timestamp = RTTimeSpecGetNano(RTTimeNow(&time)); 746 uint64_t u64Timestamp = getCurrentTimestamp(); 706 747 mProperties.erase(it); 707 748 // if (isGuest) /* Notify the host even for properties that the host … … 808 849 Property *pProp) 809 850 { 810 int rc = VINF_SUCCESS;811 bool warn = false;812 813 851 /* We count backwards, as the guest should normally be querying the 814 852 * most recent events. */ 853 int rc = VWRN_NOT_FOUND; 815 854 PropertyList::reverse_iterator it = mGuestNotifications.rbegin(); 816 for (; it->mTimestamp != u64Timestamp && it != mGuestNotifications.rend(); 817 ++it) {} 818 /* Warn if the timestamp was not found. */ 819 if (it->mTimestamp != u64Timestamp) 820 warn = true; 855 for (; it != mGuestNotifications.rend(); ++it) 856 if (it->mTimestamp == u64Timestamp) 857 { 858 rc = VINF_SUCCESS; 859 break; 860 } 861 821 862 /* Now look for an event matching the patterns supplied. The base() 822 863 * member conveniently points to the following element. */ 823 864 PropertyList::iterator base = it.base(); 824 for (; !base->Matches(pszPatterns) && base != mGuestNotifications.end(); 825 ++base) {} 826 if (RT_SUCCESS(rc) && base != mGuestNotifications.end()) 827 *pProp = *base; 828 else if (RT_SUCCESS(rc)) 829 *pProp = Property(); 830 if (warn) 831 rc = VWRN_NOT_FOUND; 865 for (; base != mGuestNotifications.end(); ++base) 866 if (base->Matches(pszPatterns)) 867 { 868 *pProp = *base; 869 return rc; 870 } 871 *pProp = Property(); 832 872 return rc; 833 873 } -
trunk/src/VBox/HostServices/GuestProperties/testcase/tstGuestPropSvc.cpp
r28800 r29394 727 727 int rc = VINF_SUCCESS; 728 728 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS }; 729 char chBuffer[MAX_NAME_LEN + MAX_VALUE_LEN + MAX_FLAGS_LEN];729 char achBuffer[MAX_NAME_LEN + MAX_VALUE_LEN + MAX_FLAGS_LEN]; 730 730 static char szPattern[] = ""; 731 731 … … 739 739 paParms[0].setPointer ((void *) szPattern, sizeof(szPattern)); 740 740 paParms[1].setUInt64 (u64Timestamp); 741 paParms[2].setPointer ((void *) chBuffer, getNotifications[0].cchBuffer - 1);741 paParms[2].setPointer ((void *) achBuffer, getNotifications[0].cchBuffer - 1); 742 742 pTable->pfnCall(pTable->pvService, &callHandle, 0, NULL, 743 743 GET_NOTIFICATION, 4, paParms); … … 760 760 paParms[0].setPointer ((void *) szPattern, sizeof(szPattern)); 761 761 paParms[1].setUInt64 (u64Timestamp); 762 paParms[2].setPointer ((void *) chBuffer, sizeof(chBuffer));762 paParms[2].setPointer ((void *) achBuffer, sizeof(achBuffer)); 763 763 pTable->pfnCall(pTable->pvService, &callHandle, 0, NULL, 764 764 GET_NOTIFICATION, 4, paParms); … … 768 768 || RT_FAILURE(paParms[3].getUInt32 (&u32Size)) 769 769 || u32Size != getNotifications[i].cchBuffer 770 || memcmp( chBuffer, getNotifications[i].pchBuffer, u32Size) != 0770 || memcmp(achBuffer, getNotifications[i].pchBuffer, u32Size) != 0 771 771 ) 772 772 { 773 RTPrintf("Failed to get notification for property '%s' .\n",774 getNotifications[i].pchBuffer );773 RTPrintf("Failed to get notification for property '%s' (rc=%Rrc).\n", 774 getNotifications[i].pchBuffer, rc); 775 775 rc = VERR_UNRESOLVED_ERROR; 776 776 }
Note:
See TracChangeset
for help on using the changeset viewer.