Changeset 1835 in vbox for trunk/src/VBox/Main
- Timestamp:
- Mar 30, 2007 5:18:35 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 20022
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/linux/server.cpp
r1808 r1835 246 246 gEventQ->IsOnCurrentThread (&onMainThread); 247 247 248 if (!onMainThread) 248 LogFlowFunc (("Last VirtualBox instance was released, " 249 "scheduling server shutdown in %d ms...\n", 250 VBoxSVC_ShutdownDelay)); 251 252 int vrc = RTTimerStart (sTimer, uint64_t (VBoxSVC_ShutdownDelay) * 1000000); 253 AssertRC (vrc); 254 if (VBOX_FAILURE (vrc)) 249 255 { 250 LogFlowFunc (("Last VirtualBox instance was released, " 251 "scheduling server shutdown in %d ms...\n", 252 VBoxSVC_ShutdownDelay)); 253 254 /* Start a shutdown timer to provide some delay */ 255 #if 0 /** @todo Doesn't work when the 2nd client attaches while before the timer ticks. Dmitry will debug. */ 256 int vrc = RTTimerStart (sTimer, uint64_t (VBoxSVC_ShutdownDelay) * 1000000); 257 AssertRC (vrc); 258 if (VBOX_FAILURE (vrc)) 259 #endif 256 /* Failed to start the timer, post the shutdown event 257 * manually if not on the main thread alreay. */ 258 if (!onMainThread) 260 259 { 261 /* failed to start the timer, post the shutdown event262 * manually */263 260 ShutdownTimer (NULL, NULL); 264 261 } 262 else 263 { 264 /* Here we come if: 265 * 266 * a) gEventQ is 0 which means either FactoryDestructor() is called 267 * or the IPC/DCONNECT shutdown sequence is initiated by the 268 * XPCOM shutdown routine (NS_ShutdownXPCOM()), which always 269 * happens on the main thread. 270 * 271 * b) gEventQ has reported we're on the main thread. This means 272 * that DestructEventHandler() has been called, but another 273 * client was faster and requested VirtualBox again. 274 * 275 * In either case, since we're on the main thread already, 276 * it's necessary just to release the instance once more 277 * to call its destructor. 278 */ 279 count = VirtualBox::Release(); 280 } 265 281 } 266 else267 {268 /* Here we come if:269 *270 * a) gEventQ is 0 which means either FactoryDestructor() is called271 * or the IPC/DCONNECT shutdown sequence is initiated by the272 * XPCOM shutdown routine (NS_ShutdownXPCOM()), which always273 * happens on the main thread.274 *275 * b) gEventQ has reported we're on the main thread. This means276 * that DestructEventHandler() has been called, but another277 * client was faster and requested VirtualBox again.278 *279 * We have nothing to do in these cases.280 */281 }282 282 } 283 283 … … 285 285 } 286 286 287 /* Returns the current value of the reference counter. */ 288 nsrefcnt GetRefCount() 289 { 290 /* we don't use our own Release() to avoid its "side effect" */ 291 nsrefcnt count = VirtualBox::AddRef(); 292 count = VirtualBox::Release(); 293 return count; 294 } 295 296 /* called on the main thread */ 287 297 static void *PR_CALLBACK DestructEventHandler (PLEvent* self) 288 298 { … … 294 304 Assert (sInstance); 295 305 296 /* release the reference we added in GetInstance() 297 * (will call the destructor if nobody referenced us again) */ 298 nsrefcnt count = sInstance->Release(); 299 if (count != 0) 300 { 301 LogFlowFunc (("Destruction is canceled.\n")); 306 nsrefcnt count = sInstance->GetRefCount(); 307 AssertMsg (count >= 1, ("count=%d\n", count)); 308 309 if (count > 1) 310 { 311 /* This case is very unlikely because we stop the timer when a new 312 * client connects after the instance was scheduled for 313 * destruction, but it's still possible. This is the only reason 314 * for the above GetRefCount() btw. */ 315 LogFlowFunc (("Destruction is canceled (refcnt=%d).\n", count)); 316 } 317 else 318 { 319 /* release the last (first) reference we added in GetInstance() 320 * (this must call the destructor) */ 321 nsrefcnt count = sInstance->Release(); 322 AssertMsg (count == 0, ("count=%d\n", count)); 302 323 } 303 324 … … 314 335 static void ShutdownTimer (PRTTIMER pTimer, void *pvUser) 315 336 { 337 NOREF (pTimer); 316 338 NOREF (pvUser); 339 340 /* A "too late" event is theoretically possible if somebody 341 * manually ended the server after a destruction has been scheduled 342 * and this method was so lucky that it got a chance to run before 343 * the timer was killed. */ 344 AssertReturnVoid (gEventQ); 317 345 318 346 /* post a destruction event to the main thread to safely release the … … 424 452 "a reference of VirtualBox scheduled for destruction, " 425 453 "canceling detruction...\n")); 426 427 /* add a reference to compensate one that DestructEventHandler() 428 * will release */ 429 sInstance->AddRef(); 454 455 /* make sure the previous timer is stopped */ 456 RTTimerStop (sTimer); 430 457 } 431 458 } … … 440 467 private: 441 468 442 static VirtualBox *sInstance; 469 /* Don't be confused that sInstance is of the *ClassFactory type. This is 470 * actually a singleton instance (*ClassFactory inherits the singleton 471 * class; we combined them just for "simplicity" and used "static" for 472 * factory methods. *ClassFactory here is necessary for a couple of extra 473 * methods. */ 474 475 static VirtualBoxClassFactory *sInstance; 443 476 static RTCRITSECT sLock; 444 477 … … 446 479 }; 447 480 448 VirtualBox *VirtualBoxClassFactory::sInstance = 0;481 VirtualBoxClassFactory *VirtualBoxClassFactory::sInstance = 0; 449 482 RTCRITSECT VirtualBoxClassFactory::sLock = {0}; 450 483
Note:
See TracChangeset
for help on using the changeset viewer.