Changeset 56597 in vbox
- Timestamp:
- Jun 23, 2015 11:27:49 AM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 101226
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/webservice/vboxweb.cpp
r56030 r56597 51 51 #include <iprt/asm.h> 52 52 53 #ifndef RT_OS_WINDOWS 54 # include <signal.h> 55 #endif 56 53 57 // workaround for compile problems on gcc 4.1 54 58 #ifdef __GNUC__ … … 143 147 144 148 static bool g_fDaemonize = false; // run in background. 149 static volatile bool g_fKeepRunning = true; // controlling the exit 145 150 146 151 const WSDLT_ID g_EmptyWSDLID; // for NULL MORs … … 366 371 int rc = RTThreadCreate(&m_pThread, 367 372 fntWrapper, 368 this, 369 0, // cbStack,373 this, // pvUser 374 0, // cbStack 370 375 RTTHREADTYPE_MAIN_HEAVY_WORKER, 371 376 0, … … 401 406 { 402 407 SoapThread *pst = (SoapThread*)pvThread; 403 pst->process(); // this never returns really408 pst->process(); 404 409 return 0; 405 410 } … … 435 440 ~SoapQ() 436 441 { 442 /* Tell the threads to terminate. */ 443 RTSemEventMultiSignal(m_event); 444 { 445 util::AutoWriteLock qlock(m_mutex COMMA_LOCKVAL_SRC_POS); 446 int i = 0; 447 while (m_llAllThreads.size() && i++ <= 30) 448 { 449 qlock.release(); 450 RTThreadSleep(1000); 451 RTSemEventMultiSignal(m_event); 452 qlock.acquire(); 453 } 454 WebLog("ending queue processing (%d out of %d threads idle)\n", m_cIdleThreads, m_llAllThreads.size()); 455 } 456 437 457 RTSemEventMultiDestroy(m_event); 438 458 } … … 489 509 SOAP_SOCKET get(size_t &cIdleThreads, size_t &cThreads) 490 510 { 491 while ( 1)511 while (g_fKeepRunning) 492 512 { 493 513 // wait for something to happen 494 514 RTSemEventMultiWait(m_event, RT_INDEFINITE_WAIT); 515 516 if (!g_fKeepRunning) 517 break; 495 518 496 519 util::AutoWriteLock qlock(m_mutex COMMA_LOCKVAL_SRC_POS); … … 515 538 // nothing to do: keep looping 516 539 } 540 return SOAP_INVALID_SOCKET; 517 541 } 518 542 … … 527 551 } 528 552 553 /** 554 * To be called by a worker thread when signing off, i.e. no longer 555 * willing to process requests. 556 */ 557 void signoff(SoapThread *th) 558 { 559 { 560 util::AutoWriteLock thrLock(g_pThreadsLockHandle COMMA_LOCKVAL_SRC_POS); 561 size_t c = g_mapThreads.erase(th->m_pThread); 562 AssertReturnVoid(c == 1); 563 } 564 { 565 util::AutoWriteLock qlock(m_mutex COMMA_LOCKVAL_SRC_POS); 566 m_llAllThreads.remove(th); 567 --m_cIdleThreads; 568 } 569 } 570 529 571 const struct soap *m_soap; // soap structure created by main(), passed to constructor 530 572 … … 550 592 WebLog("New SOAP thread started\n"); 551 593 552 while ( 1)594 while (g_fKeepRunning) 553 595 { 554 596 // wait for a socket to arrive on the queue 555 597 size_t cIdleThreads = 0, cThreads = 0; 556 598 m_soap->socket = m_pQ->get(cIdleThreads, cThreads); 599 600 if (!soap_valid_socket(m_soap->socket)) 601 continue; 557 602 558 603 WebLog("Processing connection from IP=%lu.%lu.%lu.%lu socket=%d (%d out of %d threads idle)\n", … … 587 632 m_pQ->done(); 588 633 } 634 m_pQ->signoff(this); 589 635 } 590 636 … … 631 677 { 632 678 util::AutoWriteLock vlock(g_pVirtualBoxLockHandle COMMA_LOCKVAL_SRC_POS); 633 g_pVirtualBox = NULL;679 g_pVirtualBox.setNull(); 634 680 } 635 681 { … … 873 919 874 920 for (uint64_t i = 1; 875 ;921 g_fKeepRunning; 876 922 i++) 877 923 { 878 924 // call gSOAP to handle incoming SOAP connection 925 soap.accept_timeout = 10; 879 926 s = soap_accept(&soap); 880 if ( s < 0)927 if (!soap_valid_socket(s)) 881 928 { 882 WebLogSoapError(&soap); 929 if (soap.errnum) 930 WebLogSoapError(&soap); 883 931 continue; 884 932 } … … 889 937 WebLog("Request %llu on socket %d queued for processing (%d items on Q)\n", i, s, cItemsOnQ); 890 938 } 939 940 delete g_pSoapQ; 941 g_pSoapQ = NULL; 942 943 WebLog("ending SOAP request handling\n"); 944 945 delete g_pSoapQ; 946 g_pSoapQ = NULL; 947 891 948 } 892 949 soap_done(&soap); // close master socket and detach environment … … 912 969 doQueuesLoop(); 913 970 971 thrLock.acquire(); 972 g_mapThreads.erase(RTThreadSelf()); 914 973 return 0; 915 974 } … … 918 977 // Required for ATL 919 978 static CComModule _Module; 979 980 /** 981 * "Signal" handler for cleanly terminating the event loop. 982 */ 983 static BOOL WINAPI websrvSignalHandler(DWORD dwCtrlType) 984 { 985 bool fEventHandled = FALSE; 986 switch (dwCtrlType) 987 { 988 /* User pressed CTRL+C or CTRL+BREAK or an external event was sent 989 * via GenerateConsoleCtrlEvent(). */ 990 case CTRL_BREAK_EVENT: 991 case CTRL_CLOSE_EVENT: 992 case CTRL_C_EVENT: 993 case CTRL_LOGOFF_EVENT: 994 case CTRL_SHUTDOWN_EVENT: 995 ASMAtomicWriteBool(&g_fGuestCtrlCanceled, true); 996 fEventHandled = TRUE; 997 break; 998 default: 999 break; 1000 } 1001 return fEventHandled; 1002 #else 1003 class ForceQuitEvent : public com::NativeEvent 1004 { 1005 void *handler() 1006 { 1007 LogFlowFunc(("\n")); 1008 1009 g_fKeepRunning = false; 1010 1011 return NULL; 1012 } 1013 }; 1014 1015 /** 1016 * Signal handler for cleanly terminating the event loop. 1017 */ 1018 static void websrvSignalHandler(int iSignal) 1019 { 1020 NOREF(iSignal); 1021 com::NativeEventQueue *pQ = com::NativeEventQueue::getMainEventQueue(); 1022 pQ->postEvent(new ForceQuitEvent()); 1023 } 920 1024 #endif 921 1025 … … 1200 1304 1201 1305 // SOAP queue pumper thread 1202 rc = RTThreadCreate(NULL, 1306 RTTHREAD threadQPumper; 1307 rc = RTThreadCreate(&threadQPumper, 1203 1308 fntQPumper, 1204 1309 NULL, // pvUser 1205 1310 0, // cbStack (default) 1206 1311 RTTHREADTYPE_MAIN_WORKER, 1207 0, // flags1312 RTTHREADFLAGS_WAITABLE, 1208 1313 "SQPmp"); 1209 1314 if (RT_FAILURE(rc)) … … 1211 1316 1212 1317 // watchdog thread 1318 RTTHREAD threadWatchdog = NIL_RTTHREAD; 1213 1319 if (g_iWatchdogTimeoutSecs > 0) 1214 1320 { 1215 1321 // start our watchdog thread 1216 rc = RTThreadCreate( NULL,1322 rc = RTThreadCreate(&threadWatchdog, 1217 1323 fntWatchdog, 1218 1324 NULL, 1219 1325 0, 1220 1326 RTTHREADTYPE_MAIN_WORKER, 1221 0,1327 RTTHREADFLAGS_WAITABLE, 1222 1328 "Watchdog"); 1223 1329 if (RT_FAILURE(rc)) … … 1225 1331 } 1226 1332 1333 #ifdef RT_OS_WINDOWS 1334 if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)gctlSignalHandler, TRUE /* Add handler */)) 1335 { 1336 rc = RTErrConvertFromWin32(GetLastError()); 1337 RTMsgError("Unable to install console control handler, rc=%Rrc\n", rc); 1338 } 1339 #else 1340 signal(SIGINT, websrvSignalHandler); 1341 # ifdef SIGBREAK 1342 signal(SIGBREAK, websrvSignalHandler); 1343 # endif 1344 #endif 1345 1227 1346 com::NativeEventQueue *pQ = com::NativeEventQueue::getMainEventQueue(); 1228 for (;;)1347 while (g_fKeepRunning) 1229 1348 { 1230 1349 // we have to process main event queue … … 1235 1354 } 1236 1355 1356 WebLog("requested termination, cleaning up\n"); 1357 1358 #ifdef RT_OS_WINDOWS 1359 if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)gctlSignalHandler, FALSE /* Remove handler */)) 1360 { 1361 rc = RTErrConvertFromWin32(GetLastError()); 1362 RTMsgError("Unable to remove console control handler, rc=%Rrc\n", rc); 1363 } 1364 #else 1365 signal(SIGINT, SIG_DFL); 1366 # ifdef SIGBREAK 1367 signal(SIGBREAK, SIG_DFL); 1368 # endif 1369 #endif 1370 1371 RTThreadWait(threadQPumper, 30000, NULL); 1372 if (threadWatchdog != NIL_RTTHREAD) 1373 RTThreadWait(threadWatchdog, g_iWatchdogCheckInterval * 1000 + 10000, NULL); 1374 1237 1375 /* VirtualBoxClient events unregistration. */ 1238 1376 if (vboxClientListener) … … 1245 1383 } 1246 1384 1385 { 1386 util::AutoWriteLock vlock(g_pVirtualBoxLockHandle COMMA_LOCKVAL_SRC_POS); 1387 g_pVirtualBox.setNull(); 1388 } 1389 { 1390 util::AutoWriteLock lock(g_pWebsessionsLockHandle COMMA_LOCKVAL_SRC_POS); 1391 WebsessionsMapIterator it = g_mapWebsessions.begin(), 1392 itEnd = g_mapWebsessions.end(); 1393 while (it != itEnd) 1394 { 1395 WebServiceSession *pWebsession = it->second; 1396 WEBDEBUG(("SVC unavailable: websession %#llx stale, deleting\n", pWebsession->getID())); 1397 delete pWebsession; 1398 it = g_mapWebsessions.begin(); 1399 } 1400 } 1401 g_pVirtualBoxClient.setNull(); 1402 1247 1403 com::Shutdown(); 1248 1404 … … 1273 1429 WEBDEBUG(("Watchdog thread started\n")); 1274 1430 1275 while ( 1)1431 while (g_fKeepRunning) 1276 1432 { 1277 1433 WEBDEBUG(("Watchdog: sleeping %d seconds\n", g_iWatchdogCheckInterval)); … … 1311 1467 } 1312 1468 1313 WEBDEBUG(("Watchdog thread ending\n")); 1469 thrLock.acquire(); 1470 g_mapThreads.erase(RTThreadSelf()); 1471 1472 WebLog("ending Watchdog thread\n"); 1314 1473 return 0; 1315 1474 }
Note:
See TracChangeset
for help on using the changeset viewer.