Changeset 3199 for trunk/src/kWorker/kWorker.c
- Timestamp:
- Mar 28, 2018, 8:56:21 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kWorker/kWorker.c
r3198 r3199 928 928 929 929 /** Whether control-C/SIGINT or Control-Break/SIGBREAK have been seen. */ 930 static KBOOL volatile g_fCtrlC = K_FALSE; 930 static int volatile g_rcCtrlC = 0; 931 932 /** The communication pipe handle. We break this when we see Ctrl-C such. */ 933 #ifdef KBUILD_OS_WINDOWS 934 static HANDLE g_hPipe = INVALID_HANDLE_VALUE; 935 #else 936 static int g_hPipe = -1; 937 #endif 938 931 939 932 940 /* Further down. */ … … 6657 6665 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 6658 6666 g_cWriteFileCalls++; 6659 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread || g_ fCtrlC);6667 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread || g_rcCtrlC != 0); 6660 6668 if (idxHandle < g_Sandbox.cHandles) 6661 6669 { … … 7368 7376 BOOL fRet; 7369 7377 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hObject); 7370 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread || g_ fCtrlC);7378 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread || g_rcCtrlC != 0); 7371 7379 if (idxHandle < g_Sandbox.cHandles) 7372 7380 { … … 9526 9534 KU32 const g_cSandboxGetProcReplacements = K_ELEMENTS(g_aSandboxGetProcReplacements); 9527 9535 9536 /** 9537 * Thread that is spawned by the first terminal kwSandboxCtrlHandler invocation. 9538 * 9539 * This will wait 5 second in a hope that the main thread will shut down the 9540 * process nicly, otherwise it will terminate it forcefully. 9541 */ 9542 static DWORD WINAPI kwSandboxCtrlThreadProc(PVOID pvUser) 9543 { 9544 int i; 9545 for (i = 0; i < 10; i++) 9546 { 9547 Sleep(500); 9548 CancelIoEx(g_hPipe, NULL); 9549 } 9550 TerminateProcess(GetCurrentProcess(), (int)(intptr_t)pvUser); 9551 return -1; 9552 } 9553 9528 9554 9529 9555 /** … … 9535 9561 static BOOL WINAPI kwSandboxCtrlHandler(DWORD dwCtrlType) 9536 9562 { 9563 DWORD cbIgn; 9564 int volatile rc; /* volatile for debugging */ 9565 int volatile rcPrev; 9566 const char *pszMsg; 9537 9567 switch (dwCtrlType) 9538 9568 { 9539 9569 case CTRL_C_EVENT: 9540 fprintf(stderr, "kWorker: Ctrl-C\n"); 9541 g_fCtrlC = K_TRUE; 9542 exit(9); 9570 rc = 9; 9571 pszMsg = "kWorker: Ctrl-C\r\n"; 9543 9572 break; 9544 9573 9545 9574 case CTRL_BREAK_EVENT: 9546 fprintf(stderr, "kWorker: Ctrl-Break\n"); 9547 g_fCtrlC = K_TRUE; 9548 exit(10); 9575 rc = 10; 9576 pszMsg = "kWorker: Ctrl-Break\r\n"; 9549 9577 break; 9550 9578 9551 9579 case CTRL_CLOSE_EVENT: 9552 fprintf(stderr, "kWorker: console closed\n"); 9553 g_fCtrlC = K_TRUE; 9554 exit(11); 9580 rc = 11; 9581 pszMsg = "kWorker: console closed\r\n"; 9555 9582 break; 9556 9583 9557 9584 case CTRL_LOGOFF_EVENT: 9558 fprintf(stderr, "kWorker: logoff event\n"); 9559 g_fCtrlC = K_TRUE; 9560 exit(11); 9585 rc = 11; 9586 pszMsg = "kWorker: logoff event\r\n"; 9561 9587 break; 9562 9588 9563 9589 case CTRL_SHUTDOWN_EVENT: 9564 fprintf(stderr, "kWorker: shutdown event\n"); 9565 g_fCtrlC = K_TRUE; 9566 exit(11); 9590 rc = 11; 9591 pszMsg = "kWorker: shutdown event\r\n"; 9567 9592 break; 9568 9593 9569 9594 default: 9570 9595 fprintf(stderr, "kwSandboxCtrlHandler: %#x\n", dwCtrlType); 9571 break; 9572 } 9596 return TRUE; 9597 } 9598 9599 /* 9600 * Terminate the process after 5 seconds. 9601 * 9602 * We don't want to wait here as the console server will otherwise not 9603 * signal the other processes in the console, which is bad for kmk as it 9604 * will continue to forge ahead. So, the first time we get here we start 9605 * a thread for doing the delayed termination. 9606 * 9607 * If we get here a second time we just terminate the process ourselves. 9608 * 9609 * Note! We do no try call exit() here as it turned out to deadlock a lot 9610 * flusing file descriptors (stderr back when we first wrote to it). 9611 */ 9612 rcPrev = g_rcCtrlC; 9613 g_rcCtrlC = rc; 9614 WriteFile(GetStdHandle(STD_ERROR_HANDLE), pszMsg, (DWORD)strlen(pszMsg), &cbIgn, NULL); 9615 CancelIoEx(g_hPipe, NULL); /* wake up idle main thread */ 9616 if (rcPrev == 0) 9617 { 9618 CreateThread(NULL, 0, kwSandboxCtrlThreadProc, (void*)(intptr_t)rc, 0 /*fFlags*/, NULL); 9619 return TRUE; 9620 } 9621 TerminateProcess(GetCurrentProcess(), rc); 9573 9622 return TRUE; 9574 9623 } … … 10607 10656 KU8 const *pbBuf = (KU8 const *)pvBuf; 10608 10657 KU32 cbLeft = cbToWrite; 10609 for (;;)10658 while (g_rcCtrlC == 0) 10610 10659 { 10611 10660 DWORD cbActuallyWritten = 0; … … 10627 10676 } 10628 10677 } 10678 return -1; 10629 10679 } 10630 10680 … … 10646 10696 KU8 *pbBuf = (KU8 *)pvBuf; 10647 10697 KU32 cbLeft = cbToRead; 10648 for (;;)10698 while (g_rcCtrlC == 0) 10649 10699 { 10650 10700 DWORD cbActuallyRead = 0; … … 10671 10721 } 10672 10722 } 10723 return -1; 10673 10724 } 10674 10725 … … 11238 11289 { 11239 11290 close(fdNul); 11240 kHlpAssert(GetStdHandle(STD_INPUT_HANDLE) != hPipe);11241 11291 hPipe = hDuplicate; 11242 11292 } … … 11257 11307 return kwErrPrintfRc(2, "The specified --pipe %p is not a pipe handle: type %#x (last err %u)!\n", 11258 11308 GetFileType(hPipe), GetLastError()); 11309 g_hPipe = hPipe; 11259 11310 11260 11311 /* … … 11296 11347 /* The first string after the header is the command. */ 11297 11348 psz = (const char *)&pbMsgBuf[sizeof(cbMsg)]; 11298 if (strcmp(psz, "JOB") == 0) 11349 if ( strcmp(psz, "JOB") == 0 11350 && g_rcCtrlC == 0) 11299 11351 { 11300 11352 struct … … 11314 11366 { 11315 11367 kwSandboxCleanupLate(&g_Sandbox); 11316 continue; 11368 if (g_rcCtrlC == 0) 11369 continue; 11317 11370 } 11318 11371 } … … 11347 11400 if (getenv("KWORKER_STATS") != NULL) 11348 11401 kwPrintStats(); 11349 return rc > 0 ? 0 : 1;11402 return g_rcCtrlC != 0 ? g_rcCtrlC : rc > 0 ? 0 : 1; 11350 11403 } 11351 11404 }
Note:
See TracChangeset
for help on using the changeset viewer.