1 /* COPYING ******************************************************************
2 For copyright and licensing terms, see the file named COPYING.
3 // **************************************************************************
4 */
5
6 #include <cstring>
7 #include <cstdlib>
8 #include <iostream>
9 #include <iomanip>
10 #include <unistd.h>
11 #include <poll.h>
12 #include "redo.h"
13 #include "jobserver.h"
14
15 /* The GNU make jobserver ***************************************************
16 // **************************************************************************
17 */
18
19 using namespace jobserver;
20
21 int jobserver::fds[2] = { -1, -1 };
22
23 static unsigned implicit_jobs = 1;
24
25 bool
try_procure_slot(const char * prog)26 jobserver::try_procure_slot(
27 const char * prog
28 ) {
29 if (implicit_jobs) {
30 --implicit_jobs;
31 if (debug) {
32 msg(prog, "INFO") << "Procured implicit job slot that is this process itself.\n";
33 }
34 return true;
35 }
36 if (-1 != fds[0]) {
37 pollfd p;
38 p.fd = fds[0];
39 p.events = POLLIN;
40 const int r0(poll(&p, sizeof p/sizeof(pollfd), 0));
41 if ((0 <= r0) && (p.revents & POLLIN)) {
42 char c;
43 const ssize_t r(read(fds[0], &c, sizeof c));
44 if (debug) {
45 if (0 < r)
46 msg(prog, "INFO") << "Procured a job slot from the jobserver.\n";
47 else
48 msg(prog, "INFO") << "Failed to procure a job slot from the jobserver.\n";
49 }
50 return 0 < r;
51 }
52 }
53 return false;
54 }
55
56 bool
procure_slot(const char * prog)57 jobserver::procure_slot(
58 const char * prog
59 ) {
60 if (implicit_jobs) {
61 --implicit_jobs;
62 if (debug) {
63 msg(prog, "INFO") << "Procured implicit job slot that is this process itself.\n";
64 }
65 return true;
66 }
67 if (-1 != fds[0]) {
68 char c;
69 const ssize_t r(read(fds[0], &c, sizeof c));
70 if (debug) {
71 if (0 < r)
72 msg(prog, "INFO") << "Procured a job slot from the jobserver.\n";
73 else
74 msg(prog, "INFO") << "Failed to procure a job slot from the jobserver.\n";
75 }
76 return 0 < r;
77 }
78 return false;
79 }
80
81 void
vacate_slot(const char * prog)82 jobserver::vacate_slot(
83 const char * prog
84 ) {
85 if (!implicit_jobs) {
86 ++implicit_jobs;
87 if (debug) {
88 msg(prog, "INFO") << "Vacated implicit job slot that is this process itself.\n";
89 }
90 } else
91 if (-1 != fds[1]) {
92 const char c('\0');
93 write(fds[1], &c, sizeof c);
94 if (debug) {
95 msg(prog, "INFO") << "Vacated a job slot to the jobserver.\n";
96 }
97 }
98 }
99