Changeset 29762 in vbox for trunk/src/VBox/Additions/common
- Timestamp:
- May 24, 2010 4:21:41 PM (15 years ago)
- Location:
- trunk/src/VBox/Additions/common/VBoxService
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxService-win.cpp
r28800 r29762 31 31 DWORD g_rcWinService = 0; 32 32 SERVICE_STATUS_HANDLE g_hWinServiceStatus = NULL; 33 /** The semaphore for the dummy Windows service. */ 34 static RTSEMEVENT g_WindowsEvent = NIL_RTSEMEVENT; 33 35 34 36 void WINAPI VBoxServiceWinMain (DWORD argc, LPTSTR *argv); … … 331 333 VBoxServiceWinSetStatus (SERVICE_RUNNING, 0); 332 334 333 /* 334 * Check that at least one service is enabled. 335 */ 336 unsigned iMain = VBoxServiceGetStartedServices(); 337 rc = VBoxServiceStartServices(iMain); /* Start all the services. */ 338 335 rc = VBoxServiceStartServices(); 339 336 if (RT_FAILURE(rc)) 340 337 VBoxServiceWinSetStatus (SERVICE_STOPPED, 0); -
trunk/src/VBox/Additions/common/VBoxService/VBoxService.cpp
r29761 r29762 35 35 #include <iprt/initterm.h> 36 36 #include <iprt/path.h> 37 #include <iprt/semaphore.h> 37 38 #include <iprt/string.h> 38 39 #include <iprt/stream.h> … … 54 55 /** The default service interval (the -i | --interval) option). */ 55 56 uint32_t g_DefaultInterval = 0; 56 /** Shutdown the main thread. (later, for signals.) */ 57 bool volatile g_fShutdown; 57 #ifdef RT_OS_WINDOWS 58 /** Signal shutdown to the Windows service thread. */ 59 bool volatile g_WindowsServiceShutdown; 60 /** Event the Windows service thread waits for shutdown. */ 61 RTSEMEVENT g_WindowsServiceEvent; 62 #endif 58 63 59 64 /** … … 276 281 277 282 278 unsigned VBoxServiceGetStartedServices(void) 279 { 280 unsigned iMain = ~0U; 283 /** 284 * Check if at least one service should be started. 285 */ 286 static bool VBoxServiceCheckStartedServices(void) 287 { 281 288 for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) 282 289 if (g_aServices[j].fEnabled) 283 { 284 iMain = j; 285 break; 286 } 287 288 return iMain; /* Return the index of the main service (must always come last!). */ 290 return true; 291 292 return false; 289 293 } 290 294 … … 294 298 * 295 299 * @returns VBox status code, errors are fully bitched. 296 * 297 * @param iMain The index of the service that belongs to the main 298 * thread. Pass ~0U if none does. 299 */ 300 int VBoxServiceStartServices(unsigned iMain) 300 */ 301 int VBoxServiceStartServices(void) 301 302 { 302 303 int rc; … … 307 308 VBoxServiceVerbose(2, "Initializing services ...\n"); 308 309 for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) 310 { 309 311 if (g_aServices[j].fEnabled) 310 312 { … … 324 326 } 325 327 } 328 } 326 329 327 330 /* … … 332 335 for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) 333 336 { 334 if ( !g_aServices[j].fEnabled 335 || j == iMain) 337 if (!g_aServices[j].fEnabled) 336 338 continue; 337 339 … … 354 356 } 355 357 } 356 if ( RT_SUCCESS(rc) 357 && iMain != ~0U) 358 { 359 /* The final service runs in the main thread. */ 360 VBoxServiceVerbose(1, "Starting '%s' in the main thread\n", g_aServices[iMain].pDesc->pszName); 361 rc = g_aServices[iMain].pDesc->pfnWorker(&g_fShutdown); 362 if (RT_SUCCESS(rc)) 363 VBoxServiceVerbose(1, "Main service '%s' successfully stopped.\n", g_aServices[iMain].pDesc->pszName); 364 else /* Only complain if service returned an error. Otherwise the service is a one-timer. */ 365 VBoxServiceError("Service '%s' stopped unexpected; rc=%Rrc\n", g_aServices[iMain].pDesc->pszName, rc); 366 g_aServices[iMain].pDesc->pfnTerm(); 367 } 358 359 #ifdef RT_OS_WINDOWS 360 if (RT_SUCCESS(rc)) 361 { 362 /* Block the main thread. */ 363 VBoxServiceVerbose(1, "Waiting in main thread\n"); 364 int rc = RTSemEventCreate(&g_WindowsServiceEvent); 365 AssertRC(rc); 366 for (;;) 367 { 368 if (g_WindowsServiceShutdown) 369 break; 370 rc = RTSemEventWait(g_WindowsServiceEvent, RT_INDEFINITE_WAIT); 371 AssertRC(rc); 372 } 373 RTSemEventDestroy(g_WindowsServiceEvent); 374 g_WindowsServiceEvent = NIL_RTSEMEVENT; 375 } 376 #endif 368 377 return rc; 369 378 } … … 379 388 { 380 389 int rc = VINF_SUCCESS; 381 unsigned iMain = VBoxServiceGetStartedServices();382 390 383 391 for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) … … 390 398 } 391 399 for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) 392 393 if ( !g_aServices[j].fEnabled /* Only stop services which were started before. */ 394 || j == iMain) /* Don't call the termination function for main service yet. */ 400 { 401 if (!g_aServices[j].fEnabled) /* Only stop services which were started before. */ 402 continue; 403 if (g_aServices[j].Thread != NIL_RTTHREAD) 395 404 { 396 continue; 405 VBoxServiceVerbose(2, "Waiting for service '%s' to stop ...\n", g_aServices[j].pDesc->pszName); 406 for (int i = 0; i < 30; i++) /* Wait 30 seconds in total */ 407 { 408 rc = RTThreadWait(g_aServices[j].Thread, 1000 /* Wait 1 second */, NULL); 409 if (RT_SUCCESS(rc)) 410 break; 411 #ifdef RT_OS_WINDOWS 412 /* Notify SCM that it takes a bit longer ... */ 413 VBoxServiceWinSetStatus(SERVICE_STOP_PENDING, i); 414 #endif 415 } 416 if (RT_FAILURE(rc)) 417 VBoxServiceError("Service '%s' failed to stop. (%Rrc)\n", g_aServices[j].pDesc->pszName, rc); 397 418 } 398 else 399 { 400 if (g_aServices[j].Thread != NIL_RTTHREAD) 401 { 402 VBoxServiceVerbose(2, "Waiting for service '%s' to stop ...\n", g_aServices[j].pDesc->pszName); 403 for (int i = 0; i < 30; i++) /* Wait 30 seconds in total */ 404 { 405 rc = RTThreadWait(g_aServices[j].Thread, 1000 /* Wait 1 second */, NULL); 406 if (RT_SUCCESS(rc)) 407 break; 408 #ifdef RT_OS_WINDOWS 409 /* Notify SCM that it takes a bit longer ... */ 410 VBoxServiceWinSetStatus(SERVICE_STOP_PENDING, i); 411 #endif 412 } 413 if (RT_FAILURE(rc)) 414 VBoxServiceError("Service '%s' failed to stop. (%Rrc)\n", g_aServices[j].pDesc->pszName, rc); 415 } 416 VBoxServiceVerbose(3, "Terminating service '%s' (%d) ...\n", g_aServices[j].pDesc->pszName, j); 417 g_aServices[j].pDesc->pfnTerm(); 418 } 419 VBoxServiceVerbose(3, "Terminating service '%s' (%d) ...\n", g_aServices[j].pDesc->pszName, j); 420 g_aServices[j].pDesc->pfnTerm(); 421 } 419 422 420 423 #ifdef RT_OS_WINDOWS … … 425 428 * function). 426 429 */ 427 if ( iMain != ~0U)428 { 429 VBoxServiceVerbose(3, "Stopping main service '%s' (%d) ...\n", g_aServices[iMain].pDesc->pszName, iMain);430 431 ASMAtomicXchgBool(&g_fShutdown, true);432 g_aServices[iMain].pDesc->pfnStop();430 if (g_WindowsServiceEvent != NIL_RTSEMEVENT) 431 { 432 VBoxServiceVerbose(3, "Stopping the main thread...\n"); 433 ASMAtomicXchgBool(&g_WindowsServiceShutdown, true); 434 rc = RTSemEventSignal(g_WindowsServiceEvent); 435 AssertRC(rc); 433 436 } 434 437 #endif … … 641 644 * Check that at least one service is enabled. 642 645 */ 643 unsigned iMain = VBoxServiceGetStartedServices(); 644 if (iMain == ~0U) 646 if (!VBoxServiceCheckStartedServices()) 645 647 return VBoxServiceSyntax("At least one service must be enabled.\n"); 646 647 #ifndef RT_OS_WINDOWS648 /*649 * POSIX: No main service thread.650 */651 iMain = ~0U;652 #endif653 648 654 649 VBoxServiceVerbose(0, "%s r%s started. Verbose level = %d\n", … … 698 693 * and return immediately. 699 694 */ 700 rc = VBoxServiceStartServices( iMain);695 rc = VBoxServiceStartServices(); 701 696 #ifndef RT_OS_WINDOWS 702 697 if (RT_SUCCESS(rc)) … … 720 715 return RT_SUCCESS(rc) ? 0 : 1; 721 716 } 722 -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp
r29627 r29762 253 253 bool fProcessTimedOut = false; 254 254 uint64_t MsProcessKilled = UINT64_MAX; 255 bool const fHavePipes = hStdInW != NIL_RTPIPE256 || hStdOutR != NIL_RTPIPE257 || hStdErrR != NIL_RTPIPE;258 255 RTMSINTERVAL const cMsPollBase = hStdInW != NIL_RTPIPE 259 256 ? 100 /* need to poll for input */ -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
r29516 r29762 261 261 extern void VBoxServiceVerbose(int iLevel, const char *pszFormat, ...); 262 262 extern int VBoxServiceArgUInt32(int argc, char **argv, const char *psz, int *pi, uint32_t *pu32, uint32_t u32Min, uint32_t u32Max); 263 extern unsigned VBoxServiceGetStartedServices(void); 264 extern int VBoxServiceStartServices(unsigned iMain); 263 extern int VBoxServiceStartServices(void); 265 264 extern int VBoxServiceStopServices(void); 266 265
Note:
See TracChangeset
for help on using the changeset viewer.