Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelforney committed Feb 23, 2024
1 parent 52676ec commit 890e9a1
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 86 deletions.
59 changes: 19 additions & 40 deletions build.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static struct edge *work;
static size_t nstarted, nfinished, ntotal;
static bool consoleused;
static struct timespec starttime;
static char gmaketokens[512], *gmakelatest = gmaketokens;
static char jobtokens[512], *gmakelatest = gmaketokens;

void
buildreset(void)
Expand Down Expand Up @@ -320,15 +320,6 @@ jobstart(struct job *j, struct edge *e)
warn("posix_spawn_file_actions_addclose:");
goto err3;
}
if (buildopts.gmakepipe[0] >= 0) {
/* do not allow children to steal GNU/tokens */
for (i = 0; i < 2; ++i) {
if ((errno = posix_spawn_file_actions_addclose(&actions, buildopts.gmakepipe[i]))) {
warn("posix_spawn_file_actions_addclose:");
goto err3;
}
}
}
if (e->pool != &consolepool) {
if ((errno = posix_spawn_file_actions_addopen(&actions, 0, "/dev/null", O_RDONLY, 0))) {
warn("posix_spawn_file_actions_addopen:");
Expand Down Expand Up @@ -548,30 +539,13 @@ queryload(void)
#endif
}

/* returns remaining GNU/tokens */
static ssize_t
returngmake(void)
{
ssize_t returned = 0;
if (buildopts.gmakepipe[1] >= 0)
if ((returned = write(buildopts.gmakepipe[1], gmaketokens, gmakelatest - gmaketokens)) >= 0)
gmakelatest = gmaketokens;
return returned;
}

static void
gmakeatexit(void)
jobserverclose(void)
{
if (returngmake() < 0)
warn("last write to jobserver:");
}

static void
termsignal(int signum)
{
write(2, "terminating due to signal\n", 27);
(void)returngmake();
_exit(128 + signum);
if (buildopts.jobserver[1] == -1)
return;
if (write(buildopts.jobserver[1], jobtokens, njobtokens) < 0)
warn("jobserver: write:");
}

void
Expand All @@ -589,7 +563,10 @@ build(void)
return;
}

if (buildopts.gmakepipe[0] >= 0) {
if (buildopts.jobserver[0] != -1) {
maxjobs = 0;
fds = xmalloc(sizeof *fds);
fds = xreallocarray(fds, jobslen, sizeof(fds[0]));
if (atexit(gmakeatexit) == 0) {
maxjobs = 1; /* will change dynamically as tokens are exchanged */
tokenin.fd = buildopts.gmakepipe[0];
Expand Down Expand Up @@ -640,18 +617,18 @@ build(void)
if (jobslen > buildopts.maxjobs)
jobslen = buildopts.maxjobs;
jobs = xreallocarray(jobs, jobslen, sizeof(jobs[0]));
fds = xreallocarray(fds, jobslen, sizeof(fds[0]));
fds = xreallocarray(1 + fds, jobslen, sizeof(fds[0]));
for (i = next; i < jobslen; ++i) {
jobs[i].buf.data = NULL;
jobs[i].buf.len = 0;
jobs[i].buf.cap = 0;
jobs[i].next = i + 1;
fds[i].fd = -1;
fds[i].events = POLLIN;
fds[1 + i].fd = -1;
fds[1 + i].events = POLLIN;
}
}
fds[next].fd = jobstart(&jobs[next], e);
if (fds[next].fd < 0) {
fds[1 + next].fd = jobstart(&jobs[next], e);
if (fds[1 + next].fd < 0) {
warn("job failed to start");
++numfail;
} else {
Expand All @@ -661,9 +638,11 @@ build(void)
}
if (numjobs == 0)
break;
if (poll(fds, jobslen, 5000) < 0)
if (poll(fds, 1 + jobslen, 5000) < 0)
fatal("poll:");
for (i = 0; i < jobslen; ++i) {
if (fds[0].revents) {
}
for (i = 1; i <= jobslen; ++i) {
if (!fds[i].revents || jobwork(&jobs[i]))
continue;
--numjobs;
Expand Down
2 changes: 1 addition & 1 deletion build.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ struct buildoptions {
_Bool verbose, explain, keepdepfile, keeprsp, dryrun;
const char *statusfmt;
double maxload;
int gmakepipe[2];
int jobserver[2];
};

extern struct buildoptions buildopts;
Expand Down
93 changes: 48 additions & 45 deletions samu.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> /* for chdir */
#include <unistd.h> /* for chdir */
#include <poll.h> /* for poll */
#include <fcntl.h> /* for open */
#include <fcntl.h> /* for open, fcntl */
#include "arg.h"
#include "build.h"
#include "deps.h"
Expand Down Expand Up @@ -93,58 +93,61 @@ jobsflag(const char *flag)
}

static void
jobserverflags(const char *flag)
parsegmakeflags(const char *flag)
{
int read_end, write_end;
char *fifo_path;
struct pollfd check[2];
char authbuf[1024];
const char *auth, *end;
size_t authlen;
int rfd, wfd;

if (!flag)
return;
if (sscanf(flag, "%d,%d", &read_end, &write_end) == 2) {
/* prepare error message */
errno = EBADF;
} else if (sscanf(flag,"fifo:%ms", &fifo_path) == 1) {
read_end = open(fifo_path, O_RDONLY);
write_end = open(fifo_path, O_WRONLY);
free(fifo_path);
} else {
fatal("invalid jobserver parameter");
for (; *flag != ' '; ++flag) {
switch (*flag) {
case 'n':
buildopts.dryrun = true;
break;
case '\0':
return;
}
}

check[0].fd = read_end;
check[1].fd = write_end;
if (write_end <= 0 || read_end <= 0 || poll(check, 2, 0) == -1 || check[0].revents & POLLNVAL || check[1].revents & POLLNVAL) {
fatal("invalid jobserver fds:");
return;
while (flag) {
++flag;
end = strchr(flag, ' ');
if (strncmp(flag, "--jobserver-auth=", 17) == 0) {
auth = flag + 17;
authlen = end ? end - auth : strlen(auth);
}
flag = end;
}
buildopts.gmakepipe[0] = check[0].fd;
buildopts.gmakepipe[1] = check[1].fd;
warn("using GNU Make jobserver");
}

static void
parsegmakeflags(char *env) {
char *arg;

if (!env)
if (authlen >= sizeof(authbuf)) {
warn("jobserver: MAKEFLAGS option is too long; ignoring");
return;
env = xmemdup(env, strlen(env) + 1);

arg = strtok(env, " ");
/* first word might contain dry run */
if (arg && strchr(arg, 'n'))
buildopts.dryrun = true;
arg = strtok(NULL, " ");
while (arg) {
if (strncmp(arg, "-j", 2) == 0) {
/* handled by parent process */
} else if (strncmp(arg, "--jobserver-auth=", 17) == 0 || strncmp(arg, "--jobserver-fds=", 16) == 0) {
jobserverflags(strchr(arg, '=')+1);
}
memcpy(authbuf, auth, authlen);
authbuf[authlen] = 0;
auth = authbuf;

if (strncmp(auth, "fifo:", 5) == 0) {
auth += 5;
rfd = wfd = open(auth, O_RDONLY | O_CLOEXEC);
if (rfd < 0) {
warn("jobserver: open %s:", auth);
return;
}
arg = strtok(NULL, " ");
} else if (sscanf(auth, "%d,%d", &rfd, &wfd) == 2) {
if (rfd < 0 || wfd < 0)
return; /* jobserver is disabled */
if (fcntl(rfd, F_SETFD, FD_CLOEXEC) != 0 || fcntl(wfd, F_SETFD, FD_CLOEXEC) != 0) {
warn("jobserver: fcntl set FD_CLOEXEC:");
return;
}
} else {
warn("jobserver: MAKEFLAGS option has unrecognized format; ignoring");
return;
}
free(env);
buildops.jobserver[0] = rfd;
buildops.jobserver[1] = wfd;
}

static void
Expand Down

0 comments on commit 890e9a1

Please sign in to comment.