diff options
author | Eli Zaretskii <eliz@gnu.org> | 2012-12-07 14:11:15 +0000 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2012-12-07 14:11:15 +0000 |
commit | 715927552ff90f6e77598ca2c216d49527368323 (patch) | |
tree | 7cb3f01efd7c311a0b13f9b26821d50f50f33a4a /job.c | |
parent | 7670c84f7732db29f5a9d9c145c2327f4b575f91 (diff) | |
download | gunmake-715927552ff90f6e77598ca2c216d49527368323.tar.gz |
Avoid leaving temporary batch files in the temporary directory.
job.c (create_batch_file): Declare the counter of batch files
static, to avoid having 2 jobs using the same file name and
stepping on each other's toes. When all 64K names are used up,
make one more loop looking for slots that became vacant. This
avoids leaving behind temporary batch files in the temporary
directory, which happens frequently on a fast machine when using
parallel builds.
Diffstat (limited to 'job.c')
-rw-r--r-- | job.c | 34 |
1 files changed, 30 insertions, 4 deletions
@@ -265,7 +265,16 @@ create_batch_file (char const *base, int unixy, int *fd) char temp_path[MAXPATHLEN]; /* need to know its length */ unsigned path_size = GetTempPath(sizeof temp_path, temp_path); int path_is_dot = 0; - unsigned uniq = 1; + /* The following variable is static so we won't try to reuse a name + that was generated a little while ago, because that file might + not be on disk yet, since we use FILE_ATTRIBUTE_TEMPORARY below, + which tells the OS it doesn't need to flush the cache to disk. + If the file is not yet on disk, we might think the name is + available, while it really isn't. This happens in parallel + builds, where Make doesn't wait for one job to finish before it + launches the next one. */ + static unsigned uniq = 1; + static int second_loop = 0; const unsigned sizemax = strlen (base) + strlen (ext) + 10; if (path_size == 0) @@ -276,7 +285,7 @@ create_batch_file (char const *base, int unixy, int *fd) while (path_size > 0 && path_size + sizemax < sizeof temp_path && - uniq < 0x10000) + !(uniq >= 0x10000 && second_loop)) { unsigned size = sprintf (temp_path + path_size, "%s%s-%x.%s", @@ -296,7 +305,18 @@ create_batch_file (char const *base, int unixy, int *fd) const DWORD er = GetLastError(); if (er == ERROR_FILE_EXISTS || er == ERROR_ALREADY_EXISTS) - ++uniq; + { + ++uniq; + if (uniq == 0x10000 && !second_loop) + { + /* If we already had 64K batch files in this + process, make a second loop through the numbers, + looking for free slots, i.e. files that were + deleted in the meantime. */ + second_loop = 1; + uniq = 0; + } + } /* the temporary path is not guaranteed to exist */ else if (path_is_dot == 0) @@ -791,11 +811,17 @@ reap_children (int block, int err) c, pid2str (c->pid), c->remote ? _(" (remote)") : "")); if (c->sh_batch_file) { + int rm_status; + DB (DB_JOBS, (_("Cleaning up temp batch file %s\n"), c->sh_batch_file)); /* just try and remove, don't care if this fails */ - remove (c->sh_batch_file); + errno = 0; + rm_status = remove (c->sh_batch_file); + if (rm_status) + DB (DB_JOBS, (_("Cleaning up temp batch file %s failed (%d)\n"), + c->sh_batch_file, errno)); /* all done with memory */ free (c->sh_batch_file); |