diff --git a/src/main/cpp/blaze_util.cc b/src/main/cpp/blaze_util.cc index 0ab9b763133139..4f568f5e3cc5f6 100644 --- a/src/main/cpp/blaze_util.cc +++ b/src/main/cpp/blaze_util.cc @@ -273,88 +273,6 @@ bool CheckJavaVersionIsAtLeast(const string &jvm_version, return true; } -uint64_t AcquireLock(const string& output_base, bool batch_mode, bool block, - BlazeLock* blaze_lock) { - string lockfile = output_base + "/lock"; - int lockfd = open(lockfile.c_str(), O_CREAT|O_RDWR, 0644); - - if (lockfd < 0) { - pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, - "cannot open lockfile '%s' for writing", lockfile.c_str()); - } - - // Keep server from inheriting a useless fd if we are not in batch mode - if (!batch_mode) { - if (fcntl(lockfd, F_SETFD, FD_CLOEXEC) == -1) { - pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, - "fcntl(F_SETFD) failed for lockfile"); - } - } - - struct flock lock; - lock.l_type = F_WRLCK; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - // This doesn't really matter now, but allows us to subdivide the lock - // later if that becomes meaningful. (Ranges beyond EOF can be locked.) - lock.l_len = 4096; - - uint64_t wait_time = 0; - // Try to take the lock, without blocking. - if (fcntl(lockfd, F_SETLK, &lock) == -1) { - if (errno != EACCES && errno != EAGAIN) { - pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, - "unexpected result from F_SETLK"); - } - - // We didn't get the lock. Find out who has it. - struct flock probe = lock; - probe.l_pid = 0; - if (fcntl(lockfd, F_GETLK, &probe) == -1) { - pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, - "unexpected result from F_GETLK"); - } - if (!block) { - die(blaze_exit_code::BAD_ARGV, - "Another command is running (pid=%d). Exiting immediately.", - probe.l_pid); - } - fprintf(stderr, "Another command is running (pid = %d). " - "Waiting for it to complete...", probe.l_pid); - fflush(stderr); - - // Take a clock sample for that start of the waiting time - uint64_t st = GetMillisecondsMonotonic(); - // Try to take the lock again (blocking). - int r; - do { - r = fcntl(lockfd, F_SETLKW, &lock); - } while (r == -1 && errno == EINTR); - fprintf(stderr, "\n"); - if (r == -1) { - pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, - "couldn't acquire file lock"); - } - // Take another clock sample, calculate elapsed - uint64_t et = GetMillisecondsMonotonic(); - wait_time = et - st; - } - - // Identify ourselves in the lockfile. - (void) ftruncate(lockfd, 0); - const char *tty = ttyname(STDIN_FILENO); // NOLINT (single-threaded) - string msg = "owner=launcher\npid=" - + ToString(getpid()) + "\ntty=" + (tty ? tty : "") + "\n"; - // The contents are currently meant only for debugging. - (void) write(lockfd, msg.data(), msg.size()); - blaze_lock->lockfd = lockfd; - return wait_time; -} - -void ReleaseLock(BlazeLock* blaze_lock) { - close(blaze_lock->lockfd); -} - bool IsArg(const string& arg) { return blaze_util::starts_with(arg, "-") && (arg != "--help") && (arg != "-help") && (arg != "-h"); diff --git a/src/main/cpp/blaze_util_posix.cc b/src/main/cpp/blaze_util_posix.cc index 5fdf3dd5c2ca70..fabeabd3bae0da 100644 --- a/src/main/cpp/blaze_util_posix.cc +++ b/src/main/cpp/blaze_util_posix.cc @@ -507,4 +507,86 @@ static void sigprintf(const char *format, ...) { } } +uint64_t AcquireLock(const string& output_base, bool batch_mode, bool block, + BlazeLock* blaze_lock) { + string lockfile = output_base + "/lock"; + int lockfd = open(lockfile.c_str(), O_CREAT|O_RDWR, 0644); + + if (lockfd < 0) { + pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, + "cannot open lockfile '%s' for writing", lockfile.c_str()); + } + + // Keep server from inheriting a useless fd if we are not in batch mode + if (!batch_mode) { + if (fcntl(lockfd, F_SETFD, FD_CLOEXEC) == -1) { + pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, + "fcntl(F_SETFD) failed for lockfile"); + } + } + + struct flock lock; + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + // This doesn't really matter now, but allows us to subdivide the lock + // later if that becomes meaningful. (Ranges beyond EOF can be locked.) + lock.l_len = 4096; + + uint64_t wait_time = 0; + // Try to take the lock, without blocking. + if (fcntl(lockfd, F_SETLK, &lock) == -1) { + if (errno != EACCES && errno != EAGAIN) { + pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, + "unexpected result from F_SETLK"); + } + + // We didn't get the lock. Find out who has it. + struct flock probe = lock; + probe.l_pid = 0; + if (fcntl(lockfd, F_GETLK, &probe) == -1) { + pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, + "unexpected result from F_GETLK"); + } + if (!block) { + die(blaze_exit_code::BAD_ARGV, + "Another command is running (pid=%d). Exiting immediately.", + probe.l_pid); + } + fprintf(stderr, "Another command is running (pid = %d). " + "Waiting for it to complete...", probe.l_pid); + fflush(stderr); + + // Take a clock sample for that start of the waiting time + uint64_t st = GetMillisecondsMonotonic(); + // Try to take the lock again (blocking). + int r; + do { + r = fcntl(lockfd, F_SETLKW, &lock); + } while (r == -1 && errno == EINTR); + fprintf(stderr, "\n"); + if (r == -1) { + pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, + "couldn't acquire file lock"); + } + // Take another clock sample, calculate elapsed + uint64_t et = GetMillisecondsMonotonic(); + wait_time = et - st; + } + + // Identify ourselves in the lockfile. + (void) ftruncate(lockfd, 0); + const char *tty = ttyname(STDIN_FILENO); // NOLINT (single-threaded) + string msg = "owner=launcher\npid=" + + ToString(getpid()) + "\ntty=" + (tty ? tty : "") + "\n"; + // The contents are currently meant only for debugging. + (void) write(lockfd, msg.data(), msg.size()); + blaze_lock->lockfd = lockfd; + return wait_time; +} + +void ReleaseLock(BlazeLock* blaze_lock) { + close(blaze_lock->lockfd); +} + } // namespace blaze. diff --git a/src/main/cpp/blaze_util_windows.cc b/src/main/cpp/blaze_util_windows.cc index 38c0c88b1ff4f5..05e93a945df9aa 100644 --- a/src/main/cpp/blaze_util_windows.cc +++ b/src/main/cpp/blaze_util_windows.cc @@ -1273,4 +1273,95 @@ uint64_t WindowsClock::GetProcessMilliseconds() const { return GetMilliseconds() - kStart.QuadPart; } +uint64_t AcquireLock(const string& output_base, bool batch_mode, bool block, + BlazeLock* blaze_lock) { +#ifdef COMPILER_MSVC + pdie(255, "blaze::AcquireLock is not implemented on Windows"); + return 0; +#else // not COMPILER_MSVC + string lockfile = output_base + "/lock"; + int lockfd = open(lockfile.c_str(), O_CREAT|O_RDWR, 0644); + + if (lockfd < 0) { + pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, + "cannot open lockfile '%s' for writing", lockfile.c_str()); + } + + // Keep server from inheriting a useless fd if we are not in batch mode + if (!batch_mode) { + if (fcntl(lockfd, F_SETFD, FD_CLOEXEC) == -1) { + pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, + "fcntl(F_SETFD) failed for lockfile"); + } + } + + struct flock lock; + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + // This doesn't really matter now, but allows us to subdivide the lock + // later if that becomes meaningful. (Ranges beyond EOF can be locked.) + lock.l_len = 4096; + + uint64_t wait_time = 0; + // Try to take the lock, without blocking. + if (fcntl(lockfd, F_SETLK, &lock) == -1) { + if (errno != EACCES && errno != EAGAIN) { + pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, + "unexpected result from F_SETLK"); + } + + // We didn't get the lock. Find out who has it. + struct flock probe = lock; + probe.l_pid = 0; + if (fcntl(lockfd, F_GETLK, &probe) == -1) { + pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, + "unexpected result from F_GETLK"); + } + if (!block) { + die(blaze_exit_code::BAD_ARGV, + "Another command is running (pid=%d). Exiting immediately.", + probe.l_pid); + } + fprintf(stderr, "Another command is running (pid = %d). " + "Waiting for it to complete...", probe.l_pid); + fflush(stderr); + + // Take a clock sample for that start of the waiting time + uint64_t st = GetMillisecondsMonotonic(); + // Try to take the lock again (blocking). + int r; + do { + r = fcntl(lockfd, F_SETLKW, &lock); + } while (r == -1 && errno == EINTR); + fprintf(stderr, "\n"); + if (r == -1) { + pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, + "couldn't acquire file lock"); + } + // Take another clock sample, calculate elapsed + uint64_t et = GetMillisecondsMonotonic(); + wait_time = et - st; + } + + // Identify ourselves in the lockfile. + (void) ftruncate(lockfd, 0); + const char *tty = ttyname(STDIN_FILENO); // NOLINT (single-threaded) + string msg = "owner=launcher\npid=" + + ToString(getpid()) + "\ntty=" + (tty ? tty : "") + "\n"; + // The contents are currently meant only for debugging. + (void) write(lockfd, msg.data(), msg.size()); + blaze_lock->lockfd = lockfd; + return wait_time; +#endif // COMPILER_MSVC +} + +void ReleaseLock(BlazeLock* blaze_lock) { +#ifdef COMPILER_MSVC + pdie(255, "blaze::AcquireLock is not implemented on Windows"); +#else // not COMPILER_MSVC + close(blaze_lock->lockfd); +#endif // COMPILER_MSVC +} + } // namespace blaze