Changeset 44155 in vbox for trunk/src/VBox/HostServices/GuestProperties
- Timestamp:
- Dec 18, 2012 8:13:37 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/GuestProperties/service.cpp
r43697 r44155 139 139 /** The function that was requested */ 140 140 uint32_t mFunction; 141 /** Number of call parameters. */ 142 uint32_t mParmsCnt; 141 143 /** The call parameters */ 142 144 VBOXHGCMSVCPARM *mParms; … … 145 147 146 148 /** The standard constructor */ 147 GuestCall( ) : u32ClientId(0), mFunction(0) {}149 GuestCall(void) : u32ClientId(0), mFunction(0), mParmsCnt(0) {} 148 150 /** The normal constructor */ 149 151 GuestCall(uint32_t aClientId, VBOXHGCMCALLHANDLE aHandle, uint32_t aFunction, 150 VBOXHGCMSVCPARM aParms[], int aRc)151 : u32ClientId(aClientId), mHandle(aHandle), mFunction(aFunction), mParms(aParms),152 m Rc(aRc) {}152 uint32_t aParmsCnt, VBOXHGCMSVCPARM aParms[], int aRc) 153 : u32ClientId(aClientId), mHandle(aHandle), mFunction(aFunction), 154 mParmsCnt(aParmsCnt), mParms(aParms), mRc(aRc) {} 153 155 }; 154 156 /** The guest call list type */ … … 171 173 /** The number of properties. */ 172 174 unsigned mcProperties; 173 /** The list of property changes for guest notifications */ 175 /** The list of property changes for guest notifications; 176 * only used for timestamp tracking in notifications at the moment */ 174 177 PropertyList mGuestNotifications; 175 178 /** The list of outstanding guest notification calls */ … … 376 379 int getOldNotificationInternal(const char *pszPattern, 377 380 uint64_t u64Timestamp, Property *pProp); 378 int getNotificationWriteOut( VBOXHGCMSVCPARM paParms[], Property prop);379 voiddoNotifications(const char *pszProperty, uint64_t u64Timestamp);381 int getNotificationWriteOut(uint32_t cParms, VBOXHGCMSVCPARM paParms[], Property prop); 382 int doNotifications(const char *pszProperty, uint64_t u64Timestamp); 380 383 int notifyHost(const char *pszName, const char *pszValue, 381 384 uint64_t u64Timestamp, const char *pszFlags); … … 702 705 else if (mcProperties < MAX_PROPS) 703 706 { 704 /* Create a new string space record. */ 705 pProp = new Property(pcszName, pcszValue, u64TimeNano, fFlags); 706 if (pProp) 707 try 707 708 { 709 /* Create a new string space record. */ 710 pProp = new Property(pcszName, pcszValue, u64TimeNano, fFlags); 711 AssertPtr(pProp); 712 708 713 if (RTStrSpaceInsert(&mhProperties, &pProp->mStrCore)) 709 714 mcProperties++; … … 712 717 AssertFailed(); 713 718 delete pProp; 714 rc = VERR_INTERNAL_ERROR_3; 719 720 rc = VERR_ALREADY_EXISTS; 715 721 } 716 722 } 717 else 723 catch (std::bad_alloc) 724 { 718 725 rc = VERR_NO_MEMORY; 726 } 719 727 } 720 728 else … … 722 730 723 731 /* 724 * Send a notification to the host and return.732 * Send a notification to the guest and host and return. 725 733 */ 726 734 // if (isGuest) /* Notify the host even for properties that the host 727 735 // * changed. Less efficient, but ensures consistency. */ 728 doNotifications(pcszName, u64TimeNano); 729 Log2(("Set string %s, rc=%Rrc, value=%s\n", pcszName, rc, pcszValue)); 730 } 731 732 LogFlowThisFunc(("rc = %Rrc (%s = %s)\n", rc, pcszName, pcszValue)); 736 int rc2 = doNotifications(pcszName, u64TimeNano); 737 if (RT_SUCCESS(rc)) 738 rc = rc2; 739 } 740 741 LogFlowThisFunc(("%s=%s, rc=%Rrc\n", pcszName, pcszValue, rc)); 733 742 return rc; 734 743 } … … 764 773 if (RT_FAILURE(rc)) 765 774 { 766 LogFlowThisFunc(("rc =%Rrc\n", rc));775 LogFlowThisFunc(("rc=%Rrc\n", rc)); 767 776 return rc; 768 777 } … … 788 797 // if (isGuest) /* Notify the host even for properties that the host 789 798 // * changed. Less efficient, but ensures consistency. */ 790 doNotifications(pcszName, u64Timestamp); 791 } 792 793 LogFlowThisFunc(("rc = %Rrc (%s)\n", rc, pcszName)); 799 int rc2 = doNotifications(pcszName, u64Timestamp); 800 if (RT_SUCCESS(rc)) 801 rc = rc2; 802 } 803 804 LogFlowThisFunc(("%s: rc=%Rrc\n", pcszName, rc)); 794 805 return rc; 795 806 } … … 968 979 969 980 /** Helper query used by getNotification */ 970 int Service::getNotificationWriteOut(VBOXHGCMSVCPARM paParms[], Property prop) 971 { 972 int rc = VINF_SUCCESS; 981 int Service::getNotificationWriteOut(uint32_t cParms, VBOXHGCMSVCPARM paParms[], Property prop) 982 { 983 AssertReturn(cParms == 4, VERR_INVALID_PARAMETER); /* Basic sanity checking. */ 984 973 985 /* Format the data to write to the buffer. */ 974 986 std::string buffer; … … 976 988 char *pchBuf; 977 989 uint32_t cbBuf; 978 rc = paParms[2].getBuffer((void **)&pchBuf, &cbBuf); 990 991 int rc = paParms[2].getBuffer((void **)&pchBuf, &cbBuf); 979 992 if (RT_SUCCESS(rc)) 980 993 { … … 1015 1028 * @throws can throw std::bad_alloc 1016 1029 */ 1017 int Service::getNotification(uint32_t u32ClientId, VBOXHGCMCALLHANDLE callHandle, uint32_t cParms,1018 VBOXHGCMSVCPARM paParms[])1030 int Service::getNotification(uint32_t u32ClientId, VBOXHGCMCALLHANDLE callHandle, 1031 uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 1019 1032 { 1020 1033 int rc = VINF_SUCCESS; … … 1035 1048 ) 1036 1049 rc = VERR_INVALID_PARAMETER; 1050 1037 1051 if (RT_SUCCESS(rc)) 1038 LogFlow((" pszPatterns=%s, u64Timestamp=%llu\n", pszPatterns, 1039 u64Timestamp)); 1052 LogFlow(("pszPatterns=%s, u64Timestamp=%llu\n", pszPatterns, u64Timestamp)); 1040 1053 1041 1054 /* … … 1046 1059 if (RT_SUCCESS(rc) && u64Timestamp != 0) 1047 1060 rc = getOldNotification(pszPatterns, u64Timestamp, &prop); 1048 if (RT_SUCCESS(rc) && prop.isNull()) 1049 { 1061 if (RT_SUCCESS(rc)) 1062 { 1063 if (prop.isNull()) 1064 { 1065 /* 1066 * Check if the client already had the same request. 1067 * Complete the old request with an error in this case. 1068 * Protection against clients, which cancel and resubmits requests. 1069 */ 1070 CallList::iterator it = mGuestWaiters.begin(); 1071 while (it != mGuestWaiters.end()) 1072 { 1073 const char *pszPatternsExisting; 1074 uint32_t cchPatternsExisting; 1075 int rc3 = it->mParms[0].getString(&pszPatternsExisting, &cchPatternsExisting); 1076 1077 if ( RT_SUCCESS(rc3) 1078 && u32ClientId == it->u32ClientId 1079 && RTStrCmp(pszPatterns, pszPatternsExisting) == 0) 1080 { 1081 /* Complete the old request. */ 1082 mpHelpers->pfnCallComplete(it->mHandle, VERR_INTERRUPTED); 1083 it = mGuestWaiters.erase(it); 1084 } 1085 else 1086 ++it; 1087 } 1088 1089 mGuestWaiters.push_back(GuestCall(u32ClientId, callHandle, GET_NOTIFICATION, 1090 cParms, paParms, rc)); 1091 rc = VINF_HGCM_ASYNC_EXECUTE; 1092 } 1050 1093 /* 1051 * Check if the client already had the same request. 1052 * Complete the old request with an error in this case. 1053 * Protection against clients, which cancel and resubmits requests. 1094 * Otherwise reply at once with the enqueued notification we found. 1054 1095 */ 1055 CallList::iterator it = mGuestWaiters.begin(); 1056 while (it != mGuestWaiters.end()) 1057 { 1058 const char *pszPatternsExisting; 1059 uint32_t cchPatternsExisting; 1060 int rc3 = it->mParms[0].getString(&pszPatternsExisting, &cchPatternsExisting); 1061 1062 if ( RT_SUCCESS(rc3) 1063 && u32ClientId == it->u32ClientId 1064 && RTStrCmp(pszPatterns, pszPatternsExisting) == 0) 1065 { 1066 /* Complete the old request. */ 1067 mpHelpers->pfnCallComplete(it->mHandle, VERR_INTERRUPTED); 1068 it = mGuestWaiters.erase(it); 1069 } 1070 else 1071 ++it; 1072 } 1073 1074 mGuestWaiters.push_back(GuestCall(u32ClientId, callHandle, GET_NOTIFICATION, 1075 paParms, rc)); 1076 rc = VINF_HGCM_ASYNC_EXECUTE; 1077 } 1078 /* 1079 * Otherwise reply at once with the enqueued notification we found. 1080 */ 1081 else 1082 { 1083 int rc2 = getNotificationWriteOut(paParms, prop); 1084 if (RT_FAILURE(rc2)) 1085 rc = rc2; 1086 } 1096 else 1097 { 1098 int rc2 = getNotificationWriteOut(cParms, paParms, prop); 1099 if (RT_SUCCESS(rc)) 1100 rc = rc2; 1101 } 1102 } 1103 1104 LogFlowThisFunc(("returning rc=%Rrc\n", rc)); 1087 1105 return rc; 1088 1106 } … … 1097 1115 * @thread HGCM service 1098 1116 */ 1099 voidService::doNotifications(const char *pszProperty, uint64_t u64Timestamp)1100 { 1101 AssertPtrReturn Void(pszProperty);1102 LogFlowThisFunc 1117 int Service::doNotifications(const char *pszProperty, uint64_t u64Timestamp) 1118 { 1119 AssertPtrReturn(pszProperty, VERR_INVALID_POINTER); 1120 LogFlowThisFunc(("pszProperty=%s, u64Timestamp=%llu\n", pszProperty, u64Timestamp)); 1103 1121 /* Ensure that our timestamp is different to the last one. */ 1104 1122 if ( !mGuestNotifications.empty() … … 1122 1140 } 1123 1141 1124 /* Release waiters if applicable and add the event to the queue for1125 * guest notifications */1142 /* Release guest waiters if applicable and add the event 1143 * to the queue for guest notifications */ 1126 1144 int rc = VINF_SUCCESS; 1127 1145 try … … 1136 1154 { 1137 1155 GuestCall curCall = *it; 1138 int rc2 = getNotificationWriteOut(curCall.mParms , prop);1156 int rc2 = getNotificationWriteOut(curCall.mParmsCnt, curCall.mParms, prop); 1139 1157 if (RT_SUCCESS(rc2)) 1140 1158 rc2 = curCall.mRc; … … 1145 1163 ++it; 1146 1164 } 1165 1147 1166 mGuestNotifications.push_back(prop); 1167 1168 /** @todo r=andy This list does not have a purpose but for tracking 1169 * the timestamps ... 1170 if (mGuestNotifications.size() > MAX_GUEST_NOTIFICATIONS) 1171 mGuestNotifications.pop_front(); 1148 1172 } 1149 1173 catch (std::bad_alloc) … … 1151 1175 rc = VERR_NO_MEMORY; 1152 1176 } 1153 if (mGuestNotifications.size() > MAX_GUEST_NOTIFICATIONS) 1154 mGuestNotifications.pop_front();1155 1156 /*1157 * Host notifications - first case: if the property exists then send its1158 * current value1159 */1160 if (pProp && mpfnHostCallback != NULL)1161 {1162 char szFlags[MAX_FLAGS_LEN];1163 /* Send out a host notification */1164 const char *pszValue = prop.mValue.c_str();1165 if (RT_SUCCESS(rc))1177 1178 if ( RT_SUCCESS(rc) 1179 && mpfnHostCallback) 1180 { 1181 /* 1182 * Host notifications - first case: if the property exists then send its 1183 * current value 1184 */ 1185 if (pProp) 1186 { 1187 char szFlags[MAX_FLAGS_LEN]; 1188 /* Send out a host notification */ 1189 const char *pszValue = prop.mValue.c_str(); 1166 1190 rc = writeFlags(prop.mFlags, szFlags); 1167 if (RT_SUCCESS(rc)) 1168 rc = notifyHost(pszProperty, pszValue, u64Timestamp, szFlags); 1169 } 1170 1171 /* 1172 * Host notifications - second case: if the property does not exist then 1173 * send the host an empty value 1174 */ 1175 if (!pProp && mpfnHostCallback != NULL) 1176 { 1177 /* Send out a host notification */ 1178 if (RT_SUCCESS(rc)) 1191 if (RT_SUCCESS(rc)) 1192 rc = notifyHost(pszProperty, pszValue, u64Timestamp, szFlags); 1193 } 1194 /* 1195 * Host notifications - second case: if the property does not exist then 1196 * send the host an empty value 1197 */ 1198 else 1199 { 1200 /* Send out a host notification */ 1179 1201 rc = notifyHost(pszProperty, "", u64Timestamp, ""); 1180 } 1181 LogFlowThisFunc(("returning\n")); 1202 } 1203 } 1204 1205 LogFlowThisFunc(("returning rc=%Rrc\n", rc)); 1206 return rc; 1182 1207 } 1183 1208 … … 1201 1226 HostCallbackData.u64Timestamp = u64Timestamp; 1202 1227 HostCallbackData.pcszFlags = pszFlags; 1203 int rc = mpfnHostCallback 1204 (void *)(&HostCallbackData),1205 sizeof(HostCallbackData));1206 LogFlowFunc (("returning%Rrc\n", rc));1228 int rc = mpfnHostCallback(mpvHostData, 0 /*u32Function*/, 1229 (void *)(&HostCallbackData), 1230 sizeof(HostCallbackData)); 1231 LogFlowFunc(("returning rc=%Rrc\n", rc)); 1207 1232 return rc; 1208 1233 }
Note:
See TracChangeset
for help on using the changeset viewer.