return fd;
}
-static int sleep_microseconds(long us)
-{
- struct timeval tv;
- tv.tv_sec = 0;
- tv.tv_usec = us;
- return select(0, NULL, NULL, NULL, &tv);
-}
-
/*
* Constants defining the gaps between attempts to lock a file. The
* first backoff period is approximately INITIAL_BACKOFF_MS
{
int n = 1;
int multiplier = 1;
- long remaining_us = 0;
+ long remaining_ms = 0;
static int random_initialized = 0;
if (timeout_ms == 0)
return lock_file(lk, path, flags);
if (!random_initialized) {
- srandom((unsigned int)getpid());
+ srand((unsigned int)getpid());
random_initialized = 1;
}
- if (timeout_ms > 0) {
- /* avoid overflow */
- if (timeout_ms <= LONG_MAX / 1000)
- remaining_us = timeout_ms * 1000;
- else
- remaining_us = LONG_MAX;
- }
+ if (timeout_ms > 0)
+ remaining_ms = timeout_ms;
while (1) {
- long backoff_ms, wait_us;
+ long backoff_ms, wait_ms;
int fd;
fd = lock_file(lk, path, flags);
return fd; /* success */
else if (errno != EEXIST)
return -1; /* failure other than lock held */
- else if (timeout_ms > 0 && remaining_us <= 0)
+ else if (timeout_ms > 0 && remaining_ms <= 0)
return -1; /* failure due to timeout */
backoff_ms = multiplier * INITIAL_BACKOFF_MS;
/* back off for between 0.75*backoff_ms and 1.25*backoff_ms */
- wait_us = (750 + random() % 500) * backoff_ms;
- sleep_microseconds(wait_us);
- remaining_us -= wait_us;
+ wait_ms = (750 + rand() % 500) * backoff_ms / 1000;
+ sleep_millisec(wait_ms);
+ remaining_ms -= wait_ms;
/* Recursion: (n+1)^2 = n^2 + 2n + 1 */
multiplier += 2*n + 1;
void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
{
if (err == EEXIST) {
- strbuf_addf(buf, "Unable to create '%s.lock': %s.\n\n"
- "If no other git process is currently running, this probably means a\n"
- "git process crashed in this repository earlier. Make sure no other git\n"
- "process is running and remove the file manually to continue.",
+ strbuf_addf(buf, _("Unable to create '%s.lock': %s.\n\n"
+ "Another git process seems to be running in this repository, e.g.\n"
+ "an editor opened by 'git commit'. Please make sure all processes\n"
+ "are terminated then try again. If it still fails, a git process\n"
+ "may have crashed in this repository earlier:\n"
+ "remove the file manually to continue."),
absolute_path(path), strerror(err));
} else
- strbuf_addf(buf, "Unable to create '%s.lock': %s",
+ strbuf_addf(buf, _("Unable to create '%s.lock': %s"),
absolute_path(path), strerror(err));
}
int flags, long timeout_ms)
{
int fd = lock_file_timeout(lk, path, flags, timeout_ms);
- if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
- unable_to_lock_die(path, errno);
- return fd;
-}
-
-int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags)
-{
- int fd, orig_fd;
-
- fd = lock_file(lk, path, flags);
if (fd < 0) {
if (flags & LOCK_DIE_ON_ERROR)
unable_to_lock_die(path, errno);
- return fd;
- }
-
- orig_fd = open(path, O_RDONLY);
- if (orig_fd < 0) {
- if (errno != ENOENT) {
- int save_errno = errno;
-
- if (flags & LOCK_DIE_ON_ERROR)
- die("cannot open '%s' for copying", path);
- rollback_lock_file(lk);
- error("cannot open '%s' for copying", path);
- errno = save_errno;
- return -1;
+ if (flags & LOCK_REPORT_ON_ERROR) {
+ struct strbuf buf = STRBUF_INIT;
+ unable_to_lock_message(path, errno, &buf);
+ error("%s", buf.buf);
+ strbuf_release(&buf);
}
- } else if (copy_fd(orig_fd, fd)) {
- int save_errno = errno;
-
- if (flags & LOCK_DIE_ON_ERROR)
- die("failed to prepare '%s' for appending", path);
- close(orig_fd);
- rollback_lock_file(lk);
- errno = save_errno;
- return -1;
- } else {
- close(orig_fd);
}
return fd;
}