Changeset 24828 in vbox for trunk/src/VBox/Main
- Timestamp:
- Nov 20, 2009 2:57:25 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/xpcom/server.cpp
r24823 r24828 20 20 */ 21 21 22 /* Make sure all the stdint.h macros are included - must come first! */23 #ifndef __STDC_LIMIT_MACROS24 # define __STDC_LIMIT_MACROS25 #endif26 #ifndef __STDC_CONSTANT_MACROS27 # define __STDC_CONSTANT_MACROS28 #endif29 30 22 #include <ipcIService.h> 31 23 #include <ipcCID.h> … … 33 25 #include <nsIComponentRegistrar.h> 34 26 35 #if defined(XPCOM_GLUE)36 # include <nsXPCOMGlue.h>27 #ifdef XPCOM_GLUE 28 # include <nsXPCOMGlue.h> 37 29 #endif 38 30 … … 48 40 49 41 #include <iprt/initterm.h> 42 #include <iprt/critsect.h> 43 #include <iprt/getopt.h> 50 44 #include <iprt/path.h> 51 #include <iprt/critsect.h>52 45 #include <iprt/timer.h> 53 46 … … 57 50 #include <unistd.h> 58 51 #include <errno.h> 59 #include <getopt.h>60 52 #include <fcntl.h> 61 53 #include <sys/stat.h> 62 #ifndef RT_OS_OS2 63 # include <sys/resource.h> 64 #endif 54 #include <sys/resource.h> 65 55 66 56 ///////////////////////////////////////////////////////////////////////////// … … 212 202 static bool gAutoShutdown = false; 213 203 214 static nsIEventQueue * gEventQ= nsnull;204 static nsIEventQueue *gEventQ = nsnull; 215 205 static PRBool volatile gKeepRunning = PR_TRUE; 216 206 … … 238 228 * either case. 239 229 */ 240 nsresult postTo 230 nsresult postTo(nsIEventQueue *aEventQ) 241 231 { 242 232 AssertReturn(mEv.that == NULL, NS_ERROR_FAILURE); 243 233 AssertReturn(aEventQ, NS_ERROR_FAILURE); 244 nsresult rv = aEventQ->InitEvent 245 234 nsresult rv = aEventQ->InitEvent(&mEv.e, NULL, 235 eventHandler, eventDestructor); 246 236 if (NS_SUCCEEDED(rv)) 247 237 { 248 238 mEv.that = this; 249 rv = aEventQ->PostEvent 239 rv = aEventQ->PostEvent(&mEv.e); 250 240 if (NS_SUCCEEDED(rv)) 251 241 return rv; … … 265 255 } mEv; 266 256 267 static void *PR_CALLBACK eventHandler 268 { 269 return reinterpret_cast <Ev *>(self)->that->handler();270 } 271 272 static void PR_CALLBACK eventDestructor 273 { 274 delete reinterpret_cast <Ev *>(self)->that;257 static void *PR_CALLBACK eventHandler(PLEvent *self) 258 { 259 return reinterpret_cast<Ev *>(self)->that->handler(); 260 } 261 262 static void PR_CALLBACK eventDestructor(PLEvent *self) 263 { 264 delete reinterpret_cast<Ev *>(self)->that; 275 265 } 276 266 }; … … 289 279 virtual ~VirtualBoxClassFactory() 290 280 { 291 LogFlowFunc 281 LogFlowFunc(("Deleting VirtualBox...\n")); 292 282 293 283 FinalRelease(); 294 284 sInstance = NULL; 295 285 296 LogFlowFunc 297 printf 286 LogFlowFunc(("VirtualBox object deleted.\n")); 287 printf("Informational: VirtualBox object deleted.\n"); 298 288 } 299 289 … … 312 302 PRBool onMainThread = PR_TRUE; 313 303 if (gEventQ) 314 gEventQ->IsOnCurrentThread 304 gEventQ->IsOnCurrentThread(&onMainThread); 315 305 316 306 PRBool timerStarted = PR_FALSE; … … 319 309 if (sTimer != NULL) 320 310 { 321 LogFlowFunc 322 LogFlowFunc 323 311 LogFlowFunc(("Last VirtualBox instance was released.\n")); 312 LogFlowFunc(("Scheduling server shutdown in %d ms...\n", 313 VBoxSVC_ShutdownDelay)); 324 314 325 315 /* make sure the previous timer (if any) is stopped; 326 316 * otherwise RTTimerStart() will definitely fail. */ 327 RTTimerLRStop 328 329 int vrc = RTTimerLRStart (sTimer, uint64_t(VBoxSVC_ShutdownDelay) * 1000000);330 AssertRC 317 RTTimerLRStop(sTimer); 318 319 int vrc = RTTimerLRStart(sTimer, uint64_t(VBoxSVC_ShutdownDelay) * 1000000); 320 AssertRC(vrc); 331 321 timerStarted = SUCCEEDED(vrc); 332 322 } 333 323 else 334 324 { 335 LogFlowFunc 336 337 Assert 325 LogFlowFunc(("Last VirtualBox instance was released " 326 "on XPCOM shutdown.\n")); 327 Assert(onMainThread); 338 328 } 339 329 … … 344 334 /* Failed to start the timer, post the shutdown event 345 335 * manually if not on the main thread alreay. */ 346 ShutdownTimer 336 ShutdownTimer(NULL, NULL, 0); 347 337 } 348 338 else … … 366 356 */ 367 357 368 Assert 358 Assert(gEventQ == NULL); 369 359 } 370 360 } … … 379 369 void *handler() 380 370 { 381 LogFlowFunc 382 383 Assert (RTCritSectIsInitialized(&sLock));371 LogFlowFunc(("\n")); 372 373 Assert(RTCritSectIsInitialized(&sLock)); 384 374 385 375 /* stop accepting GetInstance() requests on other threads during 386 376 * possible destruction */ 387 RTCritSectEnter 377 RTCritSectEnter(&sLock); 388 378 389 379 nsrefcnt count = 0; … … 401 391 if (gAutoShutdown) 402 392 { 403 Assert 404 LogFlowFunc 393 Assert(sInstance == NULL); 394 LogFlowFunc(("Terminating the server process...\n")); 405 395 /* make it leave the event loop */ 406 396 gKeepRunning = PR_FALSE; … … 412 402 * connect after this event has been posted to the main queue 413 403 * but before it started to process it. */ 414 LogFlowFunc 415 } 416 417 RTCritSectLeave 404 LogFlowFunc(("Destruction is canceled (refcnt=%d).\n", count)); 405 } 406 407 RTCritSectLeave(&sLock); 418 408 419 409 return NULL; … … 421 411 }; 422 412 423 static void ShutdownTimer 424 { 425 NOREF 426 NOREF 413 static void ShutdownTimer(RTTIMERLR hTimerLR, void *pvUser, uint64_t /*iTick*/) 414 { 415 NOREF(hTimerLR); 416 NOREF(pvUser); 427 417 428 418 /* A "too late" event is theoretically possible if somebody … … 430 420 * and this method was so lucky that it got a chance to run before 431 421 * the timer was killed. */ 432 AssertReturnVoid 422 AssertReturnVoid(gEventQ); 433 423 434 424 /* post a quit event to the main queue */ 435 425 MaybeQuitEvent *ev = new MaybeQuitEvent(); 436 nsresult rv = ev->postTo 437 NOREF 426 nsresult rv = ev->postTo(gEventQ); 427 NOREF(rv); 438 428 439 429 /* A failure above means we've been already stopped (for example … … 444 434 static NS_IMETHODIMP FactoryConstructor() 445 435 { 446 LogFlowFunc 436 LogFlowFunc(("\n")); 447 437 448 438 /* create a critsect to protect object construction */ 449 if (RT_FAILURE(RTCritSectInit 439 if (RT_FAILURE(RTCritSectInit(&sLock))) 450 440 return NS_ERROR_OUT_OF_MEMORY; 451 441 452 int vrc = RTTimerLRCreateEx 442 int vrc = RTTimerLRCreateEx(&sTimer, 0, 0, ShutdownTimer, NULL); 453 443 if (RT_FAILURE(vrc)) 454 444 { 455 LogFlowFunc 445 LogFlowFunc(("Failed to create a timer! (vrc=%Rrc)\n", vrc)); 456 446 return NS_ERROR_FAILURE; 457 447 } … … 462 452 static NS_IMETHODIMP FactoryDestructor() 463 453 { 464 LogFlowFunc 465 466 RTTimerLRDestroy 454 LogFlowFunc(("\n")); 455 456 RTTimerLRDestroy(sTimer); 467 457 sTimer = NULL; 468 458 469 RTCritSectDelete 459 RTCritSectDelete(&sLock); 470 460 471 461 if (sInstance != NULL) … … 482 472 } 483 473 484 static nsresult GetInstance 485 { 486 LogFlowFunc 487 488 RTCritSectEnter 474 static nsresult GetInstance(VirtualBox **inst) 475 { 476 LogFlowFunc(("Getting VirtualBox object...\n")); 477 478 RTCritSectEnter(&sLock); 489 479 490 480 if (!gKeepRunning) 491 481 { 492 LogFlowFunc 493 494 RTCritSectLeave 482 LogFlowFunc(("Process termination requested first. Refusing.\n")); 483 484 RTCritSectLeave(&sLock); 495 485 496 486 /* this rv is what CreateInstance() on the client side returns … … 515 505 sInstance->AddRef(); /* protect FinalConstruct() */ 516 506 rv = sInstance->FinalConstruct(); 517 printf 518 if (NS_FAILED 507 printf("Informational: VirtualBox object created (rc=%08X).\n", rv); 508 if (NS_FAILED(rv)) 519 509 { 520 510 /* On failure diring VirtualBox initialization, delete it … … 529 519 sInstance->Release(); 530 520 sInstance->Release(); 531 Assert 521 Assert(sInstance == NULL); 532 522 } 533 523 else … … 535 525 /* On success, make sure the previous timer is stopped to 536 526 * cancel a scheduled server termination (if any). */ 537 RTTimerLRStop 527 RTTimerLRStop(sTimer); 538 528 } 539 529 } … … 545 535 else 546 536 { 547 LogFlowFunc 537 LogFlowFunc(("Using existing VirtualBox object...\n")); 548 538 nsrefcnt count = sInstance->AddRef(); 549 Assert 539 Assert(count > 1); 550 540 551 541 if (count == 2) 552 542 { 553 LogFlowFunc (("Another client has requested a reference to VirtualBox, " 554 "canceling detruction...\n")); 543 LogFlowFunc(("Another client has requested a reference to VirtualBox, canceling detruction...\n")); 555 544 556 545 /* make sure the previous timer is stopped */ 557 RTTimerLRStop 546 RTTimerLRStop(sTimer); 558 547 } 559 548 } … … 561 550 *inst = sInstance; 562 551 563 RTCritSectLeave 552 RTCritSectLeave(&sLock); 564 553 565 554 return rv; … … 581 570 582 571 VirtualBoxClassFactory *VirtualBoxClassFactory::sInstance = NULL; 583 RTCRITSECT VirtualBoxClassFactory::sLock = {0};572 RTCRITSECT VirtualBoxClassFactory::sLock; 584 573 585 574 RTTIMERLR VirtualBoxClassFactory::sTimer = NIL_RTTIMERLR; 586 575 587 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR_WITH_RC 588 (VirtualBox, VirtualBoxClassFactory::GetInstance) 576 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR_WITH_RC(VirtualBox, VirtualBoxClassFactory::GetInstance) 589 577 590 578 //////////////////////////////////////////////////////////////////////////////// … … 601 589 struct nsModuleComponentInfoEx : nsModuleComponentInfo 602 590 { 603 nsModuleComponentInfoEx 604 nsModuleComponentInfoEx 605 606 nsModuleComponentInfoEx 591 nsModuleComponentInfoEx() {} 592 nsModuleComponentInfoEx(int) {} 593 594 nsModuleComponentInfoEx( 607 595 const char* aDescription, 608 596 const nsCID& aCID, … … 640 628 static const nsModuleComponentInfoEx components[] = 641 629 { 642 nsModuleComponentInfoEx 630 nsModuleComponentInfoEx( 643 631 "VirtualBox component", 644 632 (nsCID) NS_VIRTUALBOX_CID, … … 664 652 */ 665 653 nsresult 666 NS_NewGenericFactoryEx 667 654 NS_NewGenericFactoryEx(nsIGenericFactory **result, 655 const nsModuleComponentInfoEx *info) 668 656 { 669 657 AssertReturn(result, NS_ERROR_INVALID_POINTER); 670 658 671 nsresult rv = NS_NewGenericFactory 659 nsresult rv = NS_NewGenericFactory(result, info); 672 660 if (NS_SUCCEEDED(rv) && info && info->mFactoryConstructor) 673 661 { 674 662 rv = info->mFactoryConstructor(); 675 if (NS_FAILED 676 NS_RELEASE 663 if (NS_FAILED(rv)) 664 NS_RELEASE(*result); 677 665 } 678 666 … … 687 675 */ 688 676 static nsresult 689 RegisterSelfComponents 690 691 677 RegisterSelfComponents(nsIComponentRegistrar *registrar, 678 const nsModuleComponentInfoEx *components, 679 PRUint32 count) 692 680 { 693 681 nsresult rc = NS_OK; … … 696 684 { 697 685 /* skip components w/o a constructor */ 698 if (!info->mConstructor) continue; 686 if (!info->mConstructor) 687 continue; 699 688 /* create a new generic factory for a component and register it */ 700 689 nsIGenericFactory *factory; 701 rc = NS_NewGenericFactoryEx 690 rc = NS_NewGenericFactoryEx(&factory, info); 702 691 if (NS_SUCCEEDED(rc)) 703 692 { 704 rc = registrar->RegisterFactory 705 706 707 693 rc = registrar->RegisterFactory(info->mCID, 694 info->mDescription, 695 info->mContractID, 696 factory); 708 697 factory->Release(); 709 698 } … … 715 704 716 705 static ipcIService *gIpcServ = nsnull; 717 static c har *pszPidFile = NULL;706 static const char *g_pszPidFile = NULL; 718 707 719 708 class ForceQuitEvent : public MyEvent … … 721 710 void *handler() 722 711 { 723 LogFlowFunc 712 LogFlowFunc(("\n")); 724 713 725 714 gKeepRunning = PR_FALSE; 726 715 727 if ( pszPidFile)728 RTFileDelete( pszPidFile);716 if (g_pszPidFile) 717 RTFileDelete(g_pszPidFile); 729 718 730 719 return NULL; … … 732 721 }; 733 722 734 static void signal_handler 723 static void signal_handler(int /* sig */) 735 724 { 736 725 if (gEventQ && gKeepRunning) … … 738 727 /* post a quit event to the queue */ 739 728 ForceQuitEvent *ev = new ForceQuitEvent(); 740 ev->postTo 729 ev->postTo(gEventQ); 741 730 } 742 731 } 743 732 744 int main 733 int main(int argc, char **argv) 745 734 { 746 const struct option options[] = 747 { 748 { "automate", no_argument, NULL, 'a' }, 749 { "auto-shutdown", no_argument, NULL, 'A' }, 750 { "daemonize", no_argument, NULL, 'd' }, 751 { "pidfile", required_argument, NULL, 'p' }, 752 { "pipe", required_argument, NULL, 'P' }, 753 { NULL, 0, NULL, 0 } 735 /* 736 * Initialize the VBox runtime without loading 737 * the support driver 738 */ 739 RTR3Init(); 740 741 static const RTGETOPTDEF s_aOptions[] = 742 { 743 { "--automate", 'a', RTGETOPT_REQ_NOTHING }, 744 { "--auto-shutdown", 'A', RTGETOPT_REQ_NOTHING }, 745 { "--daemonize", 'd', RTGETOPT_REQ_NOTHING }, 746 { "--pidfile", 'p', RTGETOPT_REQ_STRING }, 747 { "--pipe", 'P', RTGETOPT_REQ_UINT32 }, 754 748 }; 755 int c; 756 bool fDaemonize = false; 757 int daemon_pipe_wr = -1; 758 759 for (;;) 760 { 761 c = getopt_long(argc, argv, "", options, NULL); 762 if (c == -1) 763 break; 764 switch (c) 749 750 bool fDaemonize = false; 751 int daemon_pipe_wr = -1; 752 753 RTGETOPTSTATE GetOptState; 754 int vrc = RTGetOptInit(&GetOptState, argc, argv, &s_aOptions[0], RT_ELEMENTS(s_aOptions), 1, 0 /*fFlags*/); 755 AssertRC(vrc); 756 757 RTGETOPTUNION ValueUnion; 758 while ((vrc = RTGetOpt(&GetOptState, &ValueUnion))) 759 { 760 switch (vrc) 765 761 { 766 762 case 'a': … … 789 785 case 'p': 790 786 { 791 pszPidFile = optarg;787 g_pszPidFile = ValueUnion.psz; 792 788 break; 793 789 } 794 790 795 /* we need to exec on darwin, this is just an internal796 * hack for passing the pipe fd along to the final child. */791 /* This is just an internal hack for passing the pipe write fd 792 along to the final child. Internal use only. */ 797 793 case 'P': 798 794 { 799 daemon_pipe_wr = atoi(optarg);795 daemon_pipe_wr = ValueUnion.u32; 800 796 break; 801 797 } 802 798 803 799 default: 804 { 805 /* exit on invalid options */ 806 return 1; 807 } 808 } 809 } 810 811 static RTFILE pidFile = NIL_RTFILE; 812 813 #ifdef RT_OS_OS2 800 return RTGetOptPrintError(vrc, &ValueUnion); 801 } 802 } 803 804 #ifdef RT_OS_OS2 /** @todo There is almost no need to make a special case of OS/2 here. Just the execv call needs to be told to create a background process... */ 814 805 815 806 /* nothing to do here, the process is supposed to be already … … 854 845 fSuccess = true; 855 846 else 856 printf 847 printf("ERROR: Unknown message from child process (%s)\n", msg); 857 848 } 858 849 else 859 printf 850 printf("ERROR: 0 bytes read from child process\n"); 860 851 861 852 /* close the reading end of the pipe as well and exit */ … … 931 922 apszArgs[i++] = "--pipe"; 932 923 char szPipeArg[32]; 933 RTStrPrintf (szPipeArg, sizeof(szPipeArg), "%d", daemon_pipe_wr);924 RTStrPrintf(szPipeArg, sizeof(szPipeArg), "%d", daemon_pipe_wr); 934 925 apszArgs[i++] = szPipeArg; 935 if ( pszPidFile)926 if (g_pszPidFile) 936 927 { 937 928 apszArgs[i++] = "--pidfile"; 938 apszArgs[i++] = pszPidFile;929 apszArgs[i++] = g_pszPidFile; 939 930 } 940 931 if (gAutoShutdown) 941 932 apszArgs[i++] = "--auto-shutdown"; 942 apszArgs[i++] = NULL; Assert(i <= RT_ELEMENTS(apszArgs));943 execv 944 exit 933 apszArgs[i++] = NULL; Assert(i <= RT_ELEMENTS(apszArgs)); 934 execv(apszArgs[0], (char * const *)apszArgs); 935 exit(126); 945 936 } 946 937 947 938 #endif // !RT_OS_OS2 948 939 949 /* 950 * Initialize the VBox runtime without loading 951 * the support driver 952 */ 953 RTR3Init(); 954 955 nsresult rc; 940 nsresult rc; 956 941 957 942 do 958 943 { 959 944 rc = com::Initialize(); 960 if (NS_FAILED 961 { 962 printf 945 if (NS_FAILED(rc)) 946 { 947 printf("ERROR: Failed to initialize XPCOM! (rc=%08X)\n", rc); 963 948 break; 964 949 } 965 950 966 951 nsCOMPtr <nsIComponentRegistrar> registrar; 967 rc = NS_GetComponentRegistrar (getter_AddRefs(registrar));968 if (NS_FAILED 969 { 970 printf 952 rc = NS_GetComponentRegistrar(getter_AddRefs(registrar)); 953 if (NS_FAILED(rc)) 954 { 955 printf("ERROR: Failed to get component registrar! (rc=%08X)\n", rc); 971 956 break; 972 957 } 973 958 974 registrar->AutoRegister 975 rc = RegisterSelfComponents 976 977 if (NS_FAILED 978 { 979 printf 959 registrar->AutoRegister(nsnull); 960 rc = RegisterSelfComponents(registrar, components, 961 NS_ARRAY_LENGTH (components)); 962 if (NS_FAILED(rc)) 963 { 964 printf("ERROR: Failed to register server components! (rc=%08X)\n", rc); 980 965 break; 981 966 } … … 984 969 * gets created upon XPCOM startup, so it will use the main (this) 985 970 * thread's event queue to receive IPC events) */ 986 rc = NS_GetMainEventQ 987 if (NS_FAILED 988 { 989 printf 971 rc = NS_GetMainEventQ(&gEventQ); 972 if (NS_FAILED(rc)) 973 { 974 printf("ERROR: Failed to get the main event queue! (rc=%08X)\n", rc); 990 975 break; 991 976 } … … 994 979 if (NS_FAILED (rc)) 995 980 { 996 printf 981 printf("ERROR: Failed to get IPC service! (rc=%08X)\n", rc); 997 982 break; 998 983 } 999 984 1000 NS_ADDREF 1001 1002 LogFlowFunc 1003 1004 rc = gIpcServ->AddName 1005 if (NS_FAILED 1006 { 1007 LogFlowFunc (("Failed to register the server name (rc=%08X)!\n"1008 "Is another server already running?\n", rc));1009 1010 printf 1011 1012 1013 NS_RELEASE 985 NS_ADDREF(gIpcServ = ipcServ); 986 987 LogFlowFunc(("Will use \"%s\" as server name.\n", VBOXSVC_IPC_NAME)); 988 989 rc = gIpcServ->AddName(VBOXSVC_IPC_NAME); 990 if (NS_FAILED(rc)) 991 { 992 LogFlowFunc(("Failed to register the server name (rc=%Rhrc (%08X))!\n" 993 "Is another server already running?\n", rc, rc)); 994 995 printf("ERROR: Failed to register the server name \"%s\" (rc=%08X)!\n" 996 "Is another server already running?\n", 997 VBOXSVC_IPC_NAME, rc); 998 NS_RELEASE(gIpcServ); 1014 999 break; 1015 1000 } … … 1019 1004 struct sigaction sa; 1020 1005 sa.sa_handler = signal_handler; 1021 sigemptyset 1006 sigemptyset(&sa.sa_mask); 1022 1007 sa.sa_flags = 0; 1023 sigaction 1024 sigaction 1025 sigaction 1026 sigaction 1008 sigaction(SIGINT, &sa, NULL); 1009 sigaction(SIGQUIT, &sa, NULL); 1010 sigaction(SIGTERM, &sa, NULL); 1011 sigaction(SIGTRAP, &sa, NULL); 1027 1012 } 1028 1013 … … 1031 1016 int iSize; 1032 1017 1033 iSize = snprintf(szBuf, sizeof(szBuf),1034 "Sun VirtualBox XPCOM Server Version "1035 VBOX_VERSION_STRING);1036 for (int i =iSize; i>0; i--)1018 iSize = RTStrPrintf(szBuf, sizeof(szBuf), 1019 "Sun VirtualBox XPCOM Server Version " 1020 VBOX_VERSION_STRING); 1021 for (int i = iSize; i > 0; i--) 1037 1022 putchar('*'); 1038 printf 1039 printf 1040 1023 printf("\n%s\n", szBuf); 1024 printf("(C) 2008-2009 Sun Microsystems, Inc.\n" 1025 "All rights reserved.\n"); 1041 1026 #ifdef DEBUG 1042 printf 1027 printf("Debug version.\n"); 1043 1028 #endif 1044 #if 01045 /* in my opinion two lines enclosing the text look better */1046 for (int i=iSize; i>0; i--)1047 putchar('*');1048 putchar('\n');1049 #endif1050 1029 } 1051 1030 1052 1031 if (daemon_pipe_wr >= 0) 1053 1032 { 1054 printf 1033 printf("\nStarting event loop....\n[send TERM signal to quit]\n"); 1055 1034 /* now we're ready, signal the parent process */ 1056 1035 write(daemon_pipe_wr, "READY", strlen("READY")); 1057 1036 } 1058 1037 else 1059 { 1060 printf ("\nStarting event loop....\n[press Ctrl-C to quit]\n"); 1061 } 1062 1063 if (pszPidFile) 1064 { 1065 char szBuf[32]; 1066 const char *lf = "\n"; 1067 RTFileOpen(&pidFile, pszPidFile, RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE); 1068 RTStrFormatNumber(szBuf, getpid(), 10, 0, 0, 0); 1069 RTFileWrite(pidFile, szBuf, strlen(szBuf), NULL); 1070 RTFileWrite(pidFile, lf, strlen(lf), NULL); 1071 RTFileClose(pidFile); 1072 } 1073 1074 #ifndef RT_OS_OS2 1038 printf("\nStarting event loop....\n[press Ctrl-C to quit]\n"); 1039 1040 if (g_pszPidFile) 1041 { 1042 RTFILE pidFile = NIL_RTFILE; 1043 vrc = RTFileOpen(&pidFile, g_pszPidFile, RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE); 1044 if (RT_SUCCESS(vrc)) 1045 { 1046 char szBuf[32]; 1047 const char *lf = "\n"; 1048 RTStrFormatNumber(szBuf, getpid(), 10, 0, 0, 0); 1049 RTFileWrite(pidFile, szBuf, strlen(szBuf), NULL); 1050 RTFileWrite(pidFile, lf, strlen(lf), NULL); 1051 RTFileClose(pidFile); 1052 } 1053 } 1054 1075 1055 // Increase the file table size to 10240 or as high as possible. 1076 1056 struct rlimit lim; … … 1087 1067 else 1088 1068 printf("WARNING: failed to obtain per-process file-descriptor limit (%d).\n", errno); 1089 #endif1090 1069 1091 1070 PLEvent *ev; 1092 1071 while (gKeepRunning) 1093 1072 { 1094 gEventQ->WaitForEvent 1095 gEventQ->HandleEvent 1073 gEventQ->WaitForEvent(&ev); 1074 gEventQ->HandleEvent(ev); 1096 1075 } 1097 1076 … … 1104 1083 /* unregister ourselves. After this point, clients will start a new 1105 1084 * process because they won't be able to resolve the server name.*/ 1106 gIpcServ->RemoveName 1085 gIpcServ->RemoveName(VBOXSVC_IPC_NAME); 1107 1086 1108 1087 /* process any remaining events. These events may include … … 1112 1091 gEventQ->ProcessPendingEvents(); 1113 1092 1114 printf 1093 printf("Terminated event loop.\n"); 1115 1094 } 1116 1095 while (0); // this scopes the nsCOMPtrs 1117 1096 1118 NS_IF_RELEASE 1119 NS_IF_RELEASE 1097 NS_IF_RELEASE(gIpcServ); 1098 NS_IF_RELEASE(gEventQ); 1120 1099 1121 1100 /* no nsCOMPtrs are allowed to be alive when you call com::Shutdown(). */ 1122 1101 1123 LogFlowFunc 1102 LogFlowFunc(("Calling com::Shutdown()...\n")); 1124 1103 rc = com::Shutdown(); 1125 LogFlowFunc (("Finished com::Shutdown() (rc=%08X)\n", rc));1104 LogFlowFunc(("Finished com::Shutdown() (rc=%Rhrc)\n", rc)); 1126 1105 1127 1106 if (NS_FAILED (rc)) 1128 printf ("ERROR: Failed to shutdown XPCOM! (rc=%08X)\n", rc); 1129 1130 printf ("XPCOM server has shutdown.\n"); 1131 1132 if (pszPidFile) 1133 { 1134 RTFileDelete(pszPidFile); 1135 } 1136 1107 printf("ERROR: Failed to shutdown XPCOM! (rc=%08X)\n", rc); 1108 1109 printf("XPCOM server has shutdown.\n"); 1110 1111 if (g_pszPidFile) 1112 RTFileDelete(g_pszPidFile); 1113 1114 /* close writing end of the pipe as well */ 1137 1115 if (daemon_pipe_wr >= 0) 1138 {1139 /* close writing end of the pipe as well */1140 1116 close(daemon_pipe_wr); 1141 }1142 1117 1143 1118 return 0;
Note:
See TracChangeset
for help on using the changeset viewer.