- Timestamp:
- Jun 5, 2020, 2:57:13 AM (5 years ago)
- Location:
- trunk/src/kmk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/main.c
r3297 r3353 416 416 417 417 int make_expensive_statistics = 0; 418 #endif 419 420 #if defined (WINDOWS32) && defined (CONFIG_NEW_WIN_CHILDREN) 421 /* --job-object[=mode]. */ 422 char *win_job_object_mode = NULL; 423 424 /* --job-object-name=name */ 425 char *win_job_object_name = NULL; 418 426 #endif 419 427 … … 552 560 --statistics Gather extra statistics for $(make-stats ).\n"), 553 561 #endif 562 #if defined (WINDOWS32) && defined (CONFIG_NEW_WIN_CHILDREN) 563 N_("\ 564 --job-object=mode Windows job object mode:\n\ 565 root-kill = Root make instance only, kill all\n\ 566 process when root exits. (def)\n\ 567 root-nokill = Root make instance only.\n\ 568 No killing.\n\ 569 each-kill = Each make instances, kill all\n\ 570 children when an instance exits.\n\ 571 each-nokill = Each make instances, no killing.\n\ 572 none = No job objects.\n"), 573 N_("\ 574 --job-object-name=name Name of windows job object to open or create.\n\ 575 The default name is 'kmk-job-obj-<date>Z<pid>'.\n"), 576 #endif 554 577 NULL 555 578 }; … … 577 600 { 'p', flag, &print_data_base_flag, 1, 1, 0, 0, 0, "print-data-base" }, 578 601 #ifdef CONFIG_PRETTY_COMMAND_PRINTING 579 { CHAR_MAX+ 10, flag, (char *) &pretty_command_printing, 1, 1, 1, 0, 0,602 { CHAR_MAX+50, flag, (char *) &pretty_command_printing, 1, 1, 1, 0, 0, 580 603 "pretty-command-printing" }, 581 604 #endif 582 605 #ifdef CONFIG_WITH_PRINT_STATS_SWITCH 583 { CHAR_MAX+ 11, flag, (char *) &print_stats_flag, 1, 1, 1, 0, 0,606 { CHAR_MAX+51, flag, (char *) &print_stats_flag, 1, 1, 1, 0, 0, 584 607 "print-stats" }, 585 608 #endif 586 609 #ifdef CONFIG_WITH_PRINT_TIME_SWITCH 587 { CHAR_MAX+ 12, positive_int, (char *) &print_time_min, 1, 1, 0,610 { CHAR_MAX+52, positive_int, (char *) &print_time_min, 1, 1, 0, 588 611 (char *) &no_val_print_time_min, (char *) &default_print_time_min, 589 612 "print-time" }, 590 613 #endif 591 614 #ifdef KMK 592 { CHAR_MAX+ 14, positive_int, (char *) &process_priority, 1, 1, 0,615 { CHAR_MAX+54, positive_int, (char *) &process_priority, 1, 1, 0, 593 616 (char *) &process_priority, (char *) &process_priority, "priority" }, 594 { CHAR_MAX+ 15, positive_int, (char *) &process_affinity, 1, 1, 0,617 { CHAR_MAX+55, positive_int, (char *) &process_affinity, 1, 1, 0, 595 618 (char *) &process_affinity, (char *) &process_affinity, "affinity" }, 596 { CHAR_MAX+ 17, flag, (char *) &process_priority, 1, 1, 0, 0, 0, "nice" },619 { CHAR_MAX+56, flag, (char *) &process_priority, 1, 1, 0, 0, 0, "nice" }, 597 620 #endif 598 621 { 'q', flag, &question_flag, 1, 1, 1, 0, 0, "question" }, … … 604 627 "no-keep-going" }, 605 628 #if defined (CONFIG_WITH_MAKE_STATS) || defined (CONFIG_WITH_MINIMAL_STATS) 606 { CHAR_MAX+ 16, flag, (char *) &make_expensive_statistics, 1, 1, 1, 0, 0,629 { CHAR_MAX+57, flag, (char *) &make_expensive_statistics, 1, 1, 1, 0, 0, 607 630 "statistics" }, 608 631 #endif … … 639 662 { CHAR_MAX+6, strlist, &eval_strings, 1, 0, 0, 0, 0, "eval" }, 640 663 { CHAR_MAX+7, string, &sync_mutex, 1, 1, 0, 0, 0, "sync-mutex" }, 664 #if defined (WINDOWS32) && defined (CONFIG_NEW_WIN_CHILDREN) 665 { CHAR_MAX+58, string, &win_job_object_mode, 1, 1, 1, 0, 0, "job-object" }, 666 { CHAR_MAX+59, string, &win_job_object_name, 1, 1, 1, 0, 0, 667 "job-object-name" }, 668 #endif 641 669 { 0, 0, 0, 0, 0, 0, 0, 0, 0 } 642 670 }; … … 3728 3756 decode_debug_flags (); 3729 3757 decode_output_sync_flags (); 3758 3759 #if defined (WINDOWS32) && defined (CONFIG_NEW_WIN_CHILDREN) 3760 /* validate the job object mode value . */ 3761 if (win_job_object_mode == NULL) 3762 win_job_object_mode = xstrdup("root-kill"); 3763 else if ( strcmp (win_job_object_mode, "none") != 0 3764 && strcmp (win_job_object_mode, "root-kill") != 0 3765 && strcmp (win_job_object_mode, "root-nokill") != 0 3766 && strcmp (win_job_object_mode, "each-kill") != 0 3767 && strcmp (win_job_object_mode, "each-nokill") != 0) 3768 OS (fatal, NILF, _("unknown job object mode '%s'"), win_job_object_mode); 3769 #endif 3730 3770 } 3731 3771 -
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.