| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: job.c,v 1.164 2013/01/25 02:01:10 sjg Exp $ */ | | 1 | /* $NetBSD: job.c,v 1.165 2013/01/26 15:52:59 christos Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. | | 4 | * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * Adam de Boor. | | 8 | * Adam de Boor. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -60,34 +60,34 @@ | | | @@ -60,34 +60,34 @@ |
60 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 60 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
61 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 61 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
62 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 62 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
63 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 63 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
64 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 64 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
65 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 65 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
66 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 66 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
67 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 67 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
68 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 68 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
69 | * SUCH DAMAGE. | | 69 | * SUCH DAMAGE. |
70 | */ | | 70 | */ |
71 | | | 71 | |
72 | #ifndef MAKE_NATIVE | | 72 | #ifndef MAKE_NATIVE |
73 | static char rcsid[] = "$NetBSD: job.c,v 1.164 2013/01/25 02:01:10 sjg Exp $"; | | 73 | static char rcsid[] = "$NetBSD: job.c,v 1.165 2013/01/26 15:52:59 christos Exp $"; |
74 | #else | | 74 | #else |
75 | #include <sys/cdefs.h> | | 75 | #include <sys/cdefs.h> |
76 | #ifndef lint | | 76 | #ifndef lint |
77 | #if 0 | | 77 | #if 0 |
78 | static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94"; | | 78 | static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94"; |
79 | #else | | 79 | #else |
80 | __RCSID("$NetBSD: job.c,v 1.164 2013/01/25 02:01:10 sjg Exp $"); | | 80 | __RCSID("$NetBSD: job.c,v 1.165 2013/01/26 15:52:59 christos Exp $"); |
81 | #endif | | 81 | #endif |
82 | #endif /* not lint */ | | 82 | #endif /* not lint */ |
83 | #endif | | 83 | #endif |
84 | | | 84 | |
85 | /*- | | 85 | /*- |
86 | * job.c -- | | 86 | * job.c -- |
87 | * handle the creation etc. of our child processes. | | 87 | * handle the creation etc. of our child processes. |
88 | * | | 88 | * |
89 | * Interface: | | 89 | * Interface: |
90 | * Job_Make Start the creation of the given target. | | 90 | * Job_Make Start the creation of the given target. |
91 | * | | 91 | * |
92 | * Job_CatchChildren Check for and handle the termination of any | | 92 | * Job_CatchChildren Check for and handle the termination of any |
93 | * children. This must be called reasonably | | 93 | * children. This must be called reasonably |
| @@ -467,54 +467,57 @@ JobCondPassSig(int signo) | | | @@ -467,54 +467,57 @@ JobCondPassSig(int signo) |
467 | * | | 467 | * |
468 | * Results: | | 468 | * Results: |
469 | * None. | | 469 | * None. |
470 | * | | 470 | * |
471 | * Side Effects: | | 471 | * Side Effects: |
472 | * Sends a token on the child exit pipe to wake us up from | | 472 | * Sends a token on the child exit pipe to wake us up from |
473 | * select()/poll(). | | 473 | * select()/poll(). |
474 | * | | 474 | * |
475 | *----------------------------------------------------------------------- | | 475 | *----------------------------------------------------------------------- |
476 | */ | | 476 | */ |
477 | static void | | 477 | static void |
478 | JobChildSig(int signo MAKE_ATTR_UNUSED) | | 478 | JobChildSig(int signo MAKE_ATTR_UNUSED) |
479 | { | | 479 | { |
480 | write(childExitJob.outPipe, CHILD_EXIT, 1); | | 480 | while (write(childExitJob.outPipe, CHILD_EXIT, 1) == -1 && errno == EAGAIN) |
| | | 481 | continue; |
481 | } | | 482 | } |
482 | | | 483 | |
483 | | | 484 | |
484 | /*- | | 485 | /*- |
485 | *----------------------------------------------------------------------- | | 486 | *----------------------------------------------------------------------- |
486 | * JobContinueSig -- | | 487 | * JobContinueSig -- |
487 | * Resume all stopped jobs. | | 488 | * Resume all stopped jobs. |
488 | * | | 489 | * |
489 | * Input: | | 490 | * Input: |
490 | * signo The signal number we've received | | 491 | * signo The signal number we've received |
491 | * | | 492 | * |
492 | * Results: | | 493 | * Results: |
493 | * None. | | 494 | * None. |
494 | * | | 495 | * |
495 | * Side Effects: | | 496 | * Side Effects: |
496 | * Jobs start running again. | | 497 | * Jobs start running again. |
497 | * | | 498 | * |
498 | *----------------------------------------------------------------------- | | 499 | *----------------------------------------------------------------------- |
499 | */ | | 500 | */ |
500 | static void | | 501 | static void |
501 | JobContinueSig(int signo MAKE_ATTR_UNUSED) | | 502 | JobContinueSig(int signo MAKE_ATTR_UNUSED) |
502 | { | | 503 | { |
503 | /* | | 504 | /* |
504 | * Defer sending to SIGCONT to our stopped children until we return | | 505 | * Defer sending to SIGCONT to our stopped children until we return |
505 | * from the signal handler. | | 506 | * from the signal handler. |
506 | */ | | 507 | */ |
507 | write(childExitJob.outPipe, DO_JOB_RESUME, 1); | | 508 | while (write(childExitJob.outPipe, DO_JOB_RESUME, 1) == -1 && |
| | | 509 | errno == EAGAIN) |
| | | 510 | continue; |
508 | } | | 511 | } |
509 | | | 512 | |
510 | /*- | | 513 | /*- |
511 | *----------------------------------------------------------------------- | | 514 | *----------------------------------------------------------------------- |
512 | * JobPassSig -- | | 515 | * JobPassSig -- |
513 | * Pass a signal on to all jobs, then resend to ourselves. | | 516 | * Pass a signal on to all jobs, then resend to ourselves. |
514 | * | | 517 | * |
515 | * Input: | | 518 | * Input: |
516 | * signo The signal number we've received | | 519 | * signo The signal number we've received |
517 | * | | 520 | * |
518 | * Results: | | 521 | * Results: |
519 | * None. | | 522 | * None. |
520 | * | | 523 | * |
| @@ -1151,27 +1154,28 @@ Job_Touch(GNode *gn, Boolean silent) | | | @@ -1151,27 +1154,28 @@ Job_Touch(GNode *gn, Boolean silent) |
1151 | times.actime = times.modtime = now; | | 1154 | times.actime = times.modtime = now; |
1152 | if (utime(file, ×) < 0){ | | 1155 | if (utime(file, ×) < 0){ |
1153 | streamID = open(file, O_RDWR | O_CREAT, 0666); | | 1156 | streamID = open(file, O_RDWR | O_CREAT, 0666); |
1154 | | | 1157 | |
1155 | if (streamID >= 0) { | | 1158 | if (streamID >= 0) { |
1156 | char c; | | 1159 | char c; |
1157 | | | 1160 | |
1158 | /* | | 1161 | /* |
1159 | * Read and write a byte to the file to change the | | 1162 | * Read and write a byte to the file to change the |
1160 | * modification time, then close the file. | | 1163 | * modification time, then close the file. |
1161 | */ | | 1164 | */ |
1162 | if (read(streamID, &c, 1) == 1) { | | 1165 | if (read(streamID, &c, 1) == 1) { |
1163 | (void)lseek(streamID, (off_t)0, SEEK_SET); | | 1166 | (void)lseek(streamID, (off_t)0, SEEK_SET); |
1164 | (void)write(streamID, &c, 1); | | 1167 | while (write(streamID, &c, 1) == -1 && errno == EAGAIN) |
| | | 1168 | continue; |
1165 | } | | 1169 | } |
1166 | | | 1170 | |
1167 | (void)close(streamID); | | 1171 | (void)close(streamID); |
1168 | } else { | | 1172 | } else { |
1169 | (void)fprintf(stdout, "*** couldn't touch %s: %s", | | 1173 | (void)fprintf(stdout, "*** couldn't touch %s: %s", |
1170 | file, strerror(errno)); | | 1174 | file, strerror(errno)); |
1171 | (void)fflush(stdout); | | 1175 | (void)fflush(stdout); |
1172 | } | | 1176 | } |
1173 | } | | 1177 | } |
1174 | } | | 1178 | } |
1175 | } | | 1179 | } |
1176 | | | 1180 | |
1177 | /*- | | 1181 | /*- |
| @@ -2036,27 +2040,28 @@ Job_CatchOutput(void) | | | @@ -2036,27 +2040,28 @@ Job_CatchOutput(void) |
2036 | { | | 2040 | { |
2037 | int nready; | | 2041 | int nready; |
2038 | Job *job; | | 2042 | Job *job; |
2039 | int i; | | 2043 | int i; |
2040 | | | 2044 | |
2041 | (void)fflush(stdout); | | 2045 | (void)fflush(stdout); |
2042 | | | 2046 | |
2043 | /* The first fd in the list is the job token pipe */ | | 2047 | /* The first fd in the list is the job token pipe */ |
2044 | nready = poll(fds + 1 - wantToken, nfds - 1 + wantToken, POLL_MSEC); | | 2048 | nready = poll(fds + 1 - wantToken, nfds - 1 + wantToken, POLL_MSEC); |
2045 | | | 2049 | |
2046 | if (nready < 0 || readyfd(&childExitJob)) { | | 2050 | if (nready < 0 || readyfd(&childExitJob)) { |
2047 | char token = 0; | | 2051 | char token = 0; |
2048 | nready -= 1; | | 2052 | nready -= 1; |
2049 | (void)read(childExitJob.inPipe, &token, 1); | | 2053 | while (read(childExitJob.inPipe, &token, 1) == -1 && errno == EAGAIN) |
| | | 2054 | continue; |
2050 | if (token == DO_JOB_RESUME[0]) | | 2055 | if (token == DO_JOB_RESUME[0]) |
2051 | /* Complete relay requested from our SIGCONT handler */ | | 2056 | /* Complete relay requested from our SIGCONT handler */ |
2052 | JobRestartJobs(); | | 2057 | JobRestartJobs(); |
2053 | Job_CatchChildren(); | | 2058 | Job_CatchChildren(); |
2054 | } | | 2059 | } |
2055 | | | 2060 | |
2056 | if (nready <= 0) | | 2061 | if (nready <= 0) |
2057 | return; | | 2062 | return; |
2058 | | | 2063 | |
2059 | if (wantToken && readyfd(&tokenWaitJob)) | | 2064 | if (wantToken && readyfd(&tokenWaitJob)) |
2060 | nready--; | | 2065 | nready--; |
2061 | | | 2066 | |
2062 | for (i = 2; i < nfds; i++) { | | 2067 | for (i = 2; i < nfds; i++) { |
| @@ -2767,27 +2772,28 @@ readyfd(Job *job) | | | @@ -2767,27 +2772,28 @@ readyfd(Job *job) |
2767 | | | 2772 | |
2768 | static void | | 2773 | static void |
2769 | JobTokenAdd(void) | | 2774 | JobTokenAdd(void) |
2770 | { | | 2775 | { |
2771 | char tok = JOB_TOKENS[aborting], tok1; | | 2776 | char tok = JOB_TOKENS[aborting], tok1; |
2772 | | | 2777 | |
2773 | /* If we are depositing an error token flush everything else */ | | 2778 | /* If we are depositing an error token flush everything else */ |
2774 | while (tok != '+' && read(tokenWaitJob.inPipe, &tok1, 1) == 1) | | 2779 | while (tok != '+' && read(tokenWaitJob.inPipe, &tok1, 1) == 1) |
2775 | continue; | | 2780 | continue; |
2776 | | | 2781 | |
2777 | if (DEBUG(JOB)) | | 2782 | if (DEBUG(JOB)) |
2778 | fprintf(debug_file, "(%d) aborting %d, deposit token %c\n", | | 2783 | fprintf(debug_file, "(%d) aborting %d, deposit token %c\n", |
2779 | getpid(), aborting, JOB_TOKENS[aborting]); | | 2784 | getpid(), aborting, JOB_TOKENS[aborting]); |
2780 | write(tokenWaitJob.outPipe, &tok, 1); | | 2785 | while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN) |
| | | 2786 | continue; |
2781 | } | | 2787 | } |
2782 | | | 2788 | |
2783 | /*- | | 2789 | /*- |
2784 | *----------------------------------------------------------------------- | | 2790 | *----------------------------------------------------------------------- |
2785 | * Job_ServerStartTokenAdd -- | | 2791 | * Job_ServerStartTokenAdd -- |
2786 | * Prep the job token pipe in the root make process. | | 2792 | * Prep the job token pipe in the root make process. |
2787 | * | | 2793 | * |
2788 | *----------------------------------------------------------------------- | | 2794 | *----------------------------------------------------------------------- |
2789 | */ | | 2795 | */ |
2790 | | | 2796 | |
2791 | void | | 2797 | void |
2792 | Job_ServerStart(int max_tokens, int jp_0, int jp_1) | | 2798 | Job_ServerStart(int max_tokens, int jp_0, int jp_1) |
2793 | { | | 2799 | { |
| @@ -2880,33 +2886,35 @@ Job_TokenWithdraw(void) | | | @@ -2880,33 +2886,35 @@ Job_TokenWithdraw(void) |
2880 | if (DEBUG(JOB)) | | 2886 | if (DEBUG(JOB)) |
2881 | fprintf(debug_file, "(%d) blocked for token\n", getpid()); | | 2887 | fprintf(debug_file, "(%d) blocked for token\n", getpid()); |
2882 | wantToken = 1; | | 2888 | wantToken = 1; |
2883 | return FALSE; | | 2889 | return FALSE; |
2884 | } | | 2890 | } |
2885 | | | 2891 | |
2886 | if (count == 1 && tok != '+') { | | 2892 | if (count == 1 && tok != '+') { |
2887 | /* make being abvorted - remove any other job tokens */ | | 2893 | /* make being abvorted - remove any other job tokens */ |
2888 | if (DEBUG(JOB)) | | 2894 | if (DEBUG(JOB)) |
2889 | fprintf(debug_file, "(%d) aborted by token %c\n", getpid(), tok); | | 2895 | fprintf(debug_file, "(%d) aborted by token %c\n", getpid(), tok); |
2890 | while (read(tokenWaitJob.inPipe, &tok1, 1) == 1) | | 2896 | while (read(tokenWaitJob.inPipe, &tok1, 1) == 1) |
2891 | continue; | | 2897 | continue; |
2892 | /* And put the stopper back */ | | 2898 | /* And put the stopper back */ |
2893 | write(tokenWaitJob.outPipe, &tok, 1); | | 2899 | while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN) |
| | | 2900 | continue; |
2894 | Fatal("A failure has been detected in another branch of the parallel make"); | | 2901 | Fatal("A failure has been detected in another branch of the parallel make"); |
2895 | } | | 2902 | } |
2896 | | | 2903 | |
2897 | if (count == 1 && jobTokensRunning == 0) | | 2904 | if (count == 1 && jobTokensRunning == 0) |
2898 | /* We didn't want the token really */ | | 2905 | /* We didn't want the token really */ |
2899 | write(tokenWaitJob.outPipe, &tok, 1); | | 2906 | while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN) |
| | | 2907 | continue; |
2900 | | | 2908 | |
2901 | jobTokensRunning++; | | 2909 | jobTokensRunning++; |
2902 | if (DEBUG(JOB)) | | 2910 | if (DEBUG(JOB)) |
2903 | fprintf(debug_file, "(%d) withdrew token\n", getpid()); | | 2911 | fprintf(debug_file, "(%d) withdrew token\n", getpid()); |
2904 | return TRUE; | | 2912 | return TRUE; |
2905 | } | | 2913 | } |
2906 | | | 2914 | |
2907 | #ifdef USE_SELECT | | 2915 | #ifdef USE_SELECT |
2908 | int | | 2916 | int |
2909 | emul_poll(struct pollfd *fd, int nfd, int timeout) | | 2917 | emul_poll(struct pollfd *fd, int nfd, int timeout) |
2910 | { | | 2918 | { |
2911 | fd_set rfds, wfds; | | 2919 | fd_set rfds, wfds; |
2912 | int i, maxfd, nselect, npoll; | | 2920 | int i, maxfd, nselect, npoll; |