Changeset 3353 for trunk/src/kmk/w32
- Timestamp:
- Jun 5, 2020, 2:57:13 AM (5 years ago)
- File:
-
- 1 edited
-
trunk/src/kmk/w32/winchildren.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/w32/winchildren.c
r3313 r3353 107 107 extern void kmk_cache_exec_image_w(const wchar_t *); /* imagecache.c */ 108 108 #endif 109 110 /* Option values from main.c: */ 111 extern const char *win_job_object_mode; 112 extern const char *win_job_object_name; 109 113 110 114 … … 481 485 InitializeSRWLock(&g_RWLock); 482 486 #endif 487 488 /* 489 * Depending on the --job-object=mode value, we typically create a job 490 * object here if we're the root make instance. The job object is then 491 * typically configured to kill all remaining processes when the root make 492 * terminates, so that there aren't any stuck processes around messing up 493 * subsequent builds. This is very handy on build servers, provided of 494 * course that, there aren't parallel kmk instance that wants to share 495 * mspdbsrv.exe or something like that. 496 * 497 * If we're not in a -kill mode, the job object is pretty pointless for 498 * manual cleanup as the job object becomes invisible (or something) when 499 * the last handle to it closes, i.e. hJob below. On windows 8 and later 500 * it looks like any orphaned children are immediately assigned to the 501 * parent job object. Too bad for kmk_kill and such. 502 * 503 * win_job_object_mode values: none, root-kill, root-nokill, all-kill, all-nokill 504 */ 505 if ( strcmp(win_job_object_mode, "none") != 0 506 && ( makelevel == 0 507 || strstr(win_job_object_mode, "root") == NULL)) 508 { 509 HANDLE hJob = NULL; 510 BOOL fCreate = TRUE; 511 const char *pszJobName = win_job_object_name; 512 if (pszJobName) 513 { 514 /* Try open it first, in case it already exists. If it doesn't we'll try create it. */ 515 fCreate = FALSE; 516 hJob = OpenJobObjectA(JOB_OBJECT_ASSIGN_PROCESS, FALSE /*bInheritHandle*/, pszJobName); 517 if (hJob) 518 { 519 DWORD dwErr = GetLastError(); 520 if (dwErr == ERROR_PATH_NOT_FOUND || dwErr == ERROR_FILE_NOT_FOUND) 521 fCreate = TRUE; 522 else 523 OSN(message, 0, _("OpenJobObjectA(,,%s) failed: %u"), pszJobName, GetLastError()); 524 } 525 } 526 527 if (fCreate) 528 { 529 char szJobName[128]; 530 SYSTEMTIME Now = {0}; 531 GetSystemTime(&Now); 532 snprintf(szJobName, sizeof(szJobName) / 2, "kmk-job-obj-%04u-%02u-%02uT%02u-%02u-%02uZ%u", 533 Now.wYear, Now.wMonth, Now.wDay, Now.wHour, Now.wMinute, Now.wSecond, getpid()); 534 if (!pszJobName) 535 pszJobName = szJobName; 536 537 hJob = CreateJobObjectA(NULL, pszJobName); 538 if (hJob) 539 { 540 /* We need to set the BREAKAWAY_OK flag, as we don't want make CreateProcess fail if 541 someone tries to break way. Also set KILL_ON_JOB_CLOSE unless 'nokill' is given. */ 542 JOBOBJECT_EXTENDED_LIMIT_INFORMATION Info; 543 DWORD cbActual = 0; 544 memset(&Info, 0, sizeof(Info)); 545 if (QueryInformationJobObject(hJob, JobObjectExtendedLimitInformation, &Info, sizeof(Info), &cbActual)) 546 { 547 Info.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_BREAKAWAY_OK; 548 if (strstr(win_job_object_mode, "nokill") == NULL) 549 Info.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; 550 else 551 Info.BasicLimitInformation.LimitFlags &= ~JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; 552 if (!SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &Info, sizeof(Info))) 553 OSN(message, 0, _("SetInformationJobObject(%s,JobObjectExtendedLimitInformation,{%s},) failed: %u"), 554 pszJobName, win_job_object_mode, GetLastError()); 555 } 556 else 557 OSN(message, 0, _("QueryInformationJobObject(%s,JobObjectExtendedLimitInformation,,,) failed: %u"), 558 pszJobName, GetLastError()); 559 } 560 else 561 OSN(message, 0, _("CreateJobObjectA(NULL,%s) failed: %u"), pszJobName, GetLastError()); 562 } 563 564 if (hJob) 565 { 566 if (!(AssignProcessToJobObject(hJob, GetCurrentProcess()))) 567 OSN(message, 0, _("AssignProcessToJobObject(%s, me) failed: %u"), pszJobName, GetLastError()); 568 } 569 } 483 570 484 571 /*
Note:
See TracChangeset
for help on using the changeset viewer.
