Changeset 79048 in vbox for trunk/src/VBox/Main
- Timestamp:
- Jun 8, 2019 2:11:28 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-all/EventImpl.cpp
r76592 r79048 118 118 m->mProcessed = !aWaitable; 119 119 120 do { 120 do 121 { 121 122 if (aWaitable) 122 123 { … … 806 807 mQueue.pop_front(); 807 808 808 BOOL aWaitable = FALSE;809 aEvent->COMGETTER(Waitable)(& aWaitable);810 if ( aWaitable)809 BOOL fWaitable = FALSE; 810 aEvent->COMGETTER(Waitable)(&fWaitable); 811 if (fWaitable) 811 812 { 812 813 PendingEventsMap::iterator pit = aPem->find(aEvent); … … 1114 1115 BOOL *aResult) 1115 1116 { 1116 1117 HRESULT hrc = S_OK; 1118 BOOL aWaitable = FALSE; 1119 aEvent->COMGETTER(Waitable)(&aWaitable); 1120 1121 do { 1117 /* Get event attributes before take the source lock: */ 1118 BOOL fWaitable = FALSE; 1119 HRESULT hrc = aEvent->COMGETTER(Waitable)(&fWaitable); 1120 AssertComRC(hrc); 1121 1122 VBoxEventType_T evType; 1123 hrc = aEvent->COMGETTER(Type)(&evType); 1124 AssertComRCReturn(hrc, hrc); 1125 1126 { 1122 1127 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1123 1128 … … 1126 1131 tr("This event source is already shut down")); 1127 1132 1128 VBoxEventType_T evType;1129 hrc = aEvent->COMGETTER(Type)(&evType);1130 AssertComRCReturn(hrc, hrc);1131 1132 1133 EventMapList &listeners = m->mEvMap[(int)evType - FirstEvent]; 1133 1134 … … 1137 1138 { 1138 1139 aEvent->SetProcessed(); 1139 break; // just leave the lock and update event object state 1140 } 1141 1142 PendingEventsMap::iterator pit; 1143 1144 if (aWaitable) 1145 { 1146 m->mPendingMap.insert(PendingEventsMap::value_type(aEvent, cListeners)); 1147 // we keep iterator here to allow processing active listeners without 1148 // pending events lookup 1149 pit = m->mPendingMap.find(aEvent); 1150 } 1151 for (EventMapList::iterator it = listeners.begin(); 1152 it != listeners.end(); 1153 ++it) 1154 { 1155 HRESULT cbRc; 1156 // keep listener record reference, in case someone will remove it while in callback 1157 RecordHolder<ListenerRecord> record(*it); 1158 1159 /* 1160 * We pass lock here to allow modifying ops on EventSource inside callback 1161 * in active mode. Note that we expect list iterator stability as 'alock' 1162 * could be temporary released when calling event handler. 1163 */ 1164 cbRc = record.obj()->process(aEvent, aWaitable, pit, alock); 1165 1166 /* Note that E_ABORT is used above to signal that a passive 1167 * listener was unregistered due to not picking up its event. 1168 * This overlaps with XPCOM specific use of E_ABORT to signal 1169 * death of an active listener, but that's irrelevant here. */ 1170 if (FAILED_DEAD_INTERFACE(cbRc) || cbRc == E_ABORT) 1140 // just leave the lock and update event object state 1141 } 1142 else 1143 { 1144 PendingEventsMap::iterator pit; 1145 if (fWaitable) 1171 1146 { 1172 Listeners::iterator lit = m->mListeners.find(record.obj()->mListener); 1173 if (lit != m->mListeners.end()) 1147 m->mPendingMap.insert(PendingEventsMap::value_type(aEvent, cListeners)); 1148 // we keep iterator here to allow processing active listeners without 1149 // pending events lookup 1150 pit = m->mPendingMap.find(aEvent); 1151 } 1152 1153 for (EventMapList::iterator it = listeners.begin(); 1154 it != listeners.end(); 1155 ++it) 1156 { 1157 // keep listener record reference, in case someone will remove it while in callback 1158 RecordHolder<ListenerRecord> record(*it); 1159 1160 /* 1161 * We pass lock here to allow modifying ops on EventSource inside callback 1162 * in active mode. Note that we expect list iterator stability as 'alock' 1163 * could be temporary released when calling event handler. 1164 */ 1165 HRESULT cbRc = record.obj()->process(aEvent, fWaitable, pit, alock); 1166 1167 /* Note that E_ABORT is used above to signal that a passive 1168 * listener was unregistered due to not picking up its event. 1169 * This overlaps with XPCOM specific use of E_ABORT to signal 1170 * death of an active listener, but that's irrelevant here. */ 1171 if (FAILED_DEAD_INTERFACE(cbRc) || cbRc == E_ABORT) 1174 1172 { 1175 lit->second.obj()->shutdown(); 1176 m->mListeners.erase(lit); 1173 Listeners::iterator lit = m->mListeners.find(record.obj()->mListener); 1174 if (lit != m->mListeners.end()) 1175 { 1176 lit->second.obj()->shutdown(); 1177 m->mListeners.erase(lit); 1178 } 1177 1179 } 1180 // anything else to do with cbRc? 1178 1181 } 1179 // anything else to do with cbRc? 1180 } 1181 } while (0); 1182 } 1183 } 1182 1184 /* We leave the lock here */ 1183 1185 1184 if ( aWaitable)1186 if (fWaitable) 1185 1187 hrc = aEvent->WaitProcessed(aTimeout, aResult); 1186 1188 else … … 1218 1220 const ComPtr<IEvent> &aEvent) 1219 1221 { 1222 BOOL fWaitable = FALSE; 1223 HRESULT hrc = aEvent->COMGETTER(Waitable)(&fWaitable); 1224 AssertComRC(hrc); 1225 1220 1226 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 1221 1227 … … 1225 1231 1226 1232 Listeners::iterator it = m->mListeners.find(aListener); 1227 HRESULT rc;1228 1229 BOOL aWaitable = FALSE;1230 aEvent->COMGETTER(Waitable)(&aWaitable);1231 1233 1232 1234 if (it != m->mListeners.end()) … … 1238 1240 tr("Only applicable to passive listeners")); 1239 1241 1240 if ( aWaitable)1242 if (fWaitable) 1241 1243 { 1242 1244 PendingEventsMap::iterator pit = m->mPendingMap.find(aEvent); … … 1245 1247 { 1246 1248 AssertFailed(); 1247 rc = setError(VBOX_E_OBJECT_NOT_FOUND,1248 tr("Unknown event"));1249 hrc = setError(VBOX_E_OBJECT_NOT_FOUND, 1250 tr("Unknown event")); 1249 1251 } 1250 1252 else 1251 rc = aRecord->eventProcessed(aEvent, pit);1253 hrc = aRecord->eventProcessed(aEvent, pit); 1252 1254 } 1253 1255 else 1254 1256 { 1255 1257 // for non-waitable events we're done 1256 rc = S_OK;1258 hrc = S_OK; 1257 1259 } 1258 1260 } 1259 1261 else 1260 { 1261 rc = setError(VBOX_E_OBJECT_NOT_FOUND, 1262 tr("Listener was never registered")); 1263 } 1264 1265 return rc; 1262 hrc = setError(VBOX_E_OBJECT_NOT_FOUND, 1263 tr("Listener was never registered")); 1264 1265 return hrc; 1266 1266 } 1267 1267
Note:
See TracChangeset
for help on using the changeset viewer.