Changeset 50545 in vbox for trunk/src/VBox
- Timestamp:
- Feb 21, 2014 2:50:41 PM (11 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-all/EventImpl.cpp
r50544 r50545 595 595 HRESULT dequeue(IEvent **aEvent, LONG aTimeout, AutoLockBase &aAlock); 596 596 HRESULT eventProcessed(IEvent *aEvent, PendingEventsMap::iterator &pit); 597 void shutdown(); 597 598 598 599 void addRef() … … 676 677 struct EventSource::Data 677 678 { 678 Data() 679 Data() : fShutdown(false) 679 680 {} 680 681 … … 682 683 EventMap mEvMap; 683 684 PendingEventsMap mPendingMap; 685 bool fShutdown; 684 686 }; 685 687 … … 790 792 791 793 ::RTCritSectDelete(&mcsQLock); 792 ::RTSemEventDestroy(mQEvent);793 }794 } 795 shutdown(); 794 796 } 795 797 … … 910 912 } 911 913 914 void ListenerRecord::shutdown() 915 { 916 if (mQEvent != NIL_RTSEMEVENT) 917 { 918 RTSEMEVENT tmp = mQEvent; 919 mQEvent = NIL_RTSEMEVENT; 920 ::RTSemEventDestroy(tmp); 921 } 922 } 923 912 924 EventSource::EventSource() 913 925 {} … … 943 955 void EventSource::uninit() 944 956 { 957 { 958 // First of all (before even thinking about entering the uninit span): 959 // make sure that all listeners are are shut down (no pending events or 960 // wait calls), because they cannot be alive without the associated 961 // event source. Otherwise API clients which use long-term (or 962 // indefinite) waits will block VBoxSVC termination (just one example) 963 // for a long time or even infinitely long. 964 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 965 if (!m->fShutdown) 966 { 967 m->fShutdown = true; 968 for (Listeners::iterator it = m->mListeners.begin(); 969 it != m->mListeners.end(); 970 ++it) 971 { 972 it->second.obj()->shutdown(); 973 } 974 } 975 } 976 945 977 AutoUninitSpan autoUninitSpan(this); 946 978 if (autoUninitSpan.uninitDone()) … … 964 996 { 965 997 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 998 999 if (m->fShutdown) 1000 return setError(VBOX_E_INVALID_OBJECT_STATE, 1001 tr("This event source is already shut down")); 966 1002 967 1003 Listeners::const_iterator it = m->mListeners.find(aListener); … … 998 1034 if (it != m->mListeners.end()) 999 1035 { 1036 it->second.obj()->shutdown(); 1000 1037 m->mListeners.erase(it); 1001 1038 // destructor removes refs from the event map … … 1036 1073 do { 1037 1074 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1075 1076 if (m->fShutdown) 1077 return setError(VBOX_E_INVALID_OBJECT_STATE, 1078 tr("This event source is already shut down")); 1038 1079 1039 1080 VBoxEventType_T evType; … … 1083 1124 Listeners::iterator lit = m->mListeners.find(record.obj()->mListener); 1084 1125 if (lit != m->mListeners.end()) 1126 { 1127 lit->second.obj()->shutdown(); 1085 1128 m->mListeners.erase(lit); 1129 } 1086 1130 } 1087 1131 // anything else to do with cbRc? … … 1111 1155 1112 1156 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 1157 1158 if (m->fShutdown) 1159 return setError(VBOX_E_INVALID_OBJECT_STATE, 1160 tr("This event source is already shut down")); 1113 1161 1114 1162 Listeners::iterator it = m->mListeners.find(aListener); … … 1138 1186 1139 1187 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 1188 1189 if (m->fShutdown) 1190 return setError(VBOX_E_INVALID_OBJECT_STATE, 1191 tr("This event source is already shut down")); 1140 1192 1141 1193 Listeners::iterator it = m->mListeners.find(aListener); -
trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp
r50544 r50545 803 803 if (m->pEventSource) 804 804 { 805 // we don't perform uninit() as it's possible that some pending event refers to this source 805 // Must uninit the event source here, because it makes no sense that 806 // it survives longer than the base object. If someone gets an event 807 // with such an event source then that's life and it has to be dealt 808 // with appropriately on the API client side. 809 m->pEventSource->uninit(); 806 810 unconst(m->pEventSource).setNull(); 807 811 }
Note:
See TracChangeset
for help on using the changeset viewer.