Changeset 71183 in vbox for trunk/src/VBox/Main/src-all/VirtualBoxClientListImpl.cpp
- Timestamp:
- Mar 3, 2018 12:53:44 AM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 121088
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-all/VirtualBoxClientListImpl.cpp
r71160 r71183 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Global COM Class implementation. 4 */ 3 * VBox Global COM Class implementation. 4 * 5 * @todo r=bird: Why is this file in src-all? Shouldn't it be in src-global/win/?!? 6 */ 5 7 6 8 /* … … 16 18 */ 17 19 20 18 21 #include "Logging.h" 19 22 #include "VirtualBoxClientListImpl.h" … … 25 28 ////////////////// CClientListWatcher implementation ///////////////// 26 29 27 /* 28 * Helper class that tracks existance of registered client processes. 29 * It removes the client process from client list if it shutdowned unexpectedly, 30 * without calling DeRegisterClient(). 31 * Also it notifies VBoxSVC and VBoxSDS that this client process finished. 32 */ 30 /** 31 * Helper class that tracks existance of registered client processes. 32 * 33 * It removes the client process from client list if it shutdowned unexpectedly, 34 * without calling DeRegisterClient(). 35 * 36 * It also notifies VBoxSVC and VBoxSDS that this client process finished. 37 */ 33 38 class CClientListWatcher 34 39 { … … 48 53 }; 49 54 50 volatile RTTHREAD CClientListWatcher::m_WatcherThread = NULL; 55 volatile RTTHREAD CClientListWatcher::m_WatcherThread = NULL; /** @todo r=bird: Wrong prefix for a static variable (s_)*/ 51 56 52 57 CClientListWatcher::CClientListWatcher(TClientSet& list, RTCRITSECTRW& clientListCritSect) … … 57 62 if (ASMAtomicReadPtr((void* volatile*)&CClientListWatcher::m_WatcherThread) != NULL) 58 63 { 59 LogRelFunc(("Error: watcher thread already created.\n"));64 LogRelFunc(("Error: Watcher thread already created!\n")); 60 65 return; 61 66 } … … 64 69 if (RT_FAILURE(rc)) 65 70 { 66 LogRelFunc(("Error: failed to create wake up event for watcher thread. %Rrs\n", rc));71 LogRelFunc(("Error: Failed to create wake up event for watcher thread: %Rrs\n", rc)); 67 72 return; 68 73 } 69 74 75 /** @todo r=bird: Hanging indent on '(', please. */ 70 76 RTTHREAD watcherThread; 71 77 rc = RTThreadCreate(&watcherThread, … … 82 88 } 83 89 else 84 LogRelFunc(("Failed to create client list watcher thread %Rrs\n", rc));90 LogRelFunc(("Failed to create client list watcher thread: %Rrs\n", rc)); 85 91 } 86 92 … … 99 105 rc = RTThreadWait(CClientListWatcher::m_WatcherThread, RT_INDEFINITE_WAIT, NULL); 100 106 if (RT_FAILURE(rc)) 101 LogRelFunc(("Error: watcher thread didn't finished. Possible thread leak. %Rrs 107 LogRelFunc(("Error: watcher thread didn't finished. Possible thread leak. %Rrs\n", rc)); 102 108 else 103 LogRelFunc(("Watcher thread finished. %\n"));109 LogRelFunc(("Watcher thread finished.\n")); 104 110 105 111 ASMAtomicWriteNullPtr((void* volatile*)&CClientListWatcher::m_WatcherThread); … … 108 114 } 109 115 116 /** @todo r=bird: DOXYGEN COMMENTS! DON'T FORGET IT!! */ 117 /** @todo r=bird: DOXYGEN COMMENTS! DON'T FORGET IT!! */ 118 /** @todo r=bird: DOXYGEN COMMENTS! DON'T FORGET IT!! */ 110 119 111 120 /* … … 123 132 */ 124 133 HRESULT hrc = CoCreateInstance(CLSID_VirtualBoxSDS, NULL, CLSCTX_LOCAL_SERVER, IID_IVirtualBoxSDS, 125 (void **)ptrVirtualBoxSDS.asOutParam());134 (void **)ptrVirtualBoxSDS.asOutParam()); 126 135 if (SUCCEEDED(hrc)) 127 136 { 128 LogRelFunc(("Notify SDS that all API clients finished\n"));137 LogRelFunc(("Notifying SDS that all API clients finished...\n")); 129 138 ptrVirtualBoxSDS->NotifyClientsFinished(); 130 139 } … … 132 141 133 142 143 /** @todo r=bird: DOXYGEN COMMENTS! DON'T FORGET IT!! */ 144 /** @todo r=bird: DOXYGEN COMMENTS! DON'T FORGET IT!! */ 145 /** @todo r=bird: DOXYGEN COMMENTS! DON'T FORGET IT!! */ 134 146 /* 135 147 * Deregister all staled VBoxSVC through VBoxSDS and forcebly close VBoxSVC process … … 143 155 LogRelFunc(("Enter watcher thread\n")); 144 156 145 CClientListWatcher * pThis = (CClientListWatcher*)pvUser;157 CClientListWatcher *pThis = (CClientListWatcher *)pvUser; 146 158 Assert(pThis); 147 159 … … 159 171 for (; it != end; ++it) 160 172 { 173 /** @todo r=bird: this is a bit inefficient because RTProcWait will try open 174 * all the process each time. Would be better have registerClient open the 175 * process and just to a WaitForSingleObject here (if you want to be really 176 * performant, you could keep wait arrays of 64 objects each and use 177 * WaitForMultipleObjects on each of them). 178 * 179 * And please, don't give me the portability argument here, because this 180 * RTProcWait call only works on windows. We're not the parent of any of these 181 * clients and can't wait on them. 182 */ 161 183 // check status of client process by his pid 162 184 int rc = RTProcWait(*it, RTPROCWAIT_FLAGS_NOBLOCK, NULL); … … 186 208 * Destructor will wake up it immidietely. 187 209 */ 210 /** @todo r=bird: This is where wait for multiple objects would be really nice, as 211 * you could wait on the first 63 client processes here in addition to the event. 212 * That would speed up the response time. */ 188 213 RTSemEventWait(pThis->m_wakeUpWatcherEvent, 2000); 189 214 } … … 197 222 { 198 223 int rc = RTCritSectRwInit(&m_MapCritSect); 199 Assert(RT_SUCCESS(rc)); 200 if (RT_FAILURE(rc)) 201 { 202 LogRelFunc(("Error: creating client list critical section. %Rrs\n", rc)); 203 return E_FAIL; 204 } 205 206 m_pWatcher = new CClientListWatcher(m_ClientSet, m_MapCritSect); 224 AssertLogRelRCReturn(rc, E_FAIL); 225 226 try 227 { 228 m_pWatcher = new CClientListWatcher(m_ClientSet, m_MapCritSect); 229 } 230 catch (std::bad_alloc) 231 { 232 AssertLogRelFailedReturn(E_OUTOFMEMORY); 233 } 207 234 Assert(m_pWatcher); 208 235 … … 225 252 226 253 int rc = RTCritSectRwDelete(&m_MapCritSect); 227 Assert(RT_SUCCESS(rc)); 228 NOREF(rc); 254 AssertRC(rc); 229 255 230 256 BaseFinalRelease(); 231 LogRelFunc(("VirtualBoxClientList released. res=%d\n", rc)); 232 } 233 257 LogRelFunc(("VirtualBoxClientList released.\n")); 258 } 259 260 /** @todo r=bird: DOXYGEN COMMENTS! DON'T FORGET IT!! */ 261 /** @todo r=bird: DOXYGEN COMMENTS! DON'T FORGET IT!! */ 262 /** @todo r=bird: DOXYGEN COMMENTS! DON'T FORGET IT!! */ 234 263 /* 235 264 * Deregister API client to add it to API client list … … 240 269 { 241 270 int rc = RTCritSectRwEnterExcl(&m_MapCritSect); 242 Assert(RT_SUCCESS(rc)); 243 NOREF(rc); 271 AssertRCReturn(rc, E_FAIL); 244 272 Assert(m_pWatcher); 245 273 246 m_ClientSet.insert(aPid); 274 try 275 { 276 m_ClientSet.insert(aPid); 277 } 278 catch (std::bad_alloc) 279 { 280 RTCritSectRwLeaveExcl(&m_MapCritSect); 281 AssertLogRelFailedReturn(E_OUTOFMEMORY); 282 } 247 283 248 284 rc = RTCritSectRwLeaveExcl(&m_MapCritSect); 249 Assert (RT_SUCCESS(rc));250 LogRelFunc(("VirtualBoxClientList client registered. pid: %d res=%d\n", aPid, rc));285 AssertRC(rc); 286 LogRelFunc(("VirtualBoxClientList client registered. pid: %d\n", aPid, rc)); 251 287 return S_OK; 252 288 } 253 289 254 290 255 /* 256 * Returns list of api client processes. 257 * Result list contains PID of all clients exept VBoxSDS and VBoxSVC 258 * aEnvironment - reference to clients list that should be filled here 259 * 260 */ 291 /** 292 * Returns PIDs of the API client processes. 293 * 294 * @returns COM status code. 295 * @param aEnvironment Reference to vector that is to receive the PID list. 296 * 297 * @todo r=bird: There is no obvious reason why this is called 'aEnvironment', a 298 * more natural name would be 'aPids'. 299 */ 261 300 HRESULT VirtualBoxClientList::getClients(std::vector<LONG> &aEnvironment) 262 301 { 263 302 int rc = RTCritSectRwEnterShared(&m_MapCritSect); 264 Assert(RT_SUCCESS(rc)); 265 NOREF(rc); 266 if (RT_SUCCESS(rc)) 267 { 268 if (!m_ClientSet.empty()) 303 AssertLogRelRCReturn(rc, E_FAIL); 304 if (!m_ClientSet.empty()) 305 { 306 Assert(aEnvironment.empty()); 307 size_t const cClients = m_ClientSet.size(); 308 try 269 309 { 270 Assert(aEnvironment.empty()); 271 aEnvironment.reserve(m_ClientSet.size()); 310 aEnvironment.reserve(cClients); 272 311 aEnvironment.assign(m_ClientSet.begin(), m_ClientSet.end()); 273 Assert(aEnvironment.size());274 312 } 275 else313 catch (std::bad_alloc) 276 314 { 277 LogFunc(("Client list is empty\n")); 315 RTCritSectRwLeaveShared(&m_MapCritSect); 316 AssertLogRelMsgFailedReturn(("cClients=%zu\n", cClients), E_OUTOFMEMORY); 278 317 } 279 280 rc = RTCritSectRwLeaveShared(&m_MapCritSect); 281 Assert(RT_SUCCESS(rc)); 282 } 283 LogRelFunc(("VirtualBoxClientList client list requested. res=%d\n", rc)); 318 Assert(aEnvironment.size() == cClients); 319 } 320 else 321 { 322 LogFunc(("Client list is empty\n")); 323 } 324 325 rc = RTCritSectRwLeaveShared(&m_MapCritSect); 326 AssertRC(rc); 327 328 LogRelFunc(("VirtualBoxClientList client list requested.\n")); 284 329 return S_OK; 285 330 } 331
Note:
See TracChangeset
for help on using the changeset viewer.