diff options
author | trawick <trawick@13f79535-47bb-0310-9956-ffa450edef68> | 2000-07-19 16:35:48 +0000 |
---|---|---|
committer | trawick <trawick@13f79535-47bb-0310-9956-ffa450edef68> | 2000-07-19 16:35:48 +0000 |
commit | aa54ab4a2bdd6dc2bbbdfd948e8edb59f8ef0d86 (patch) | |
tree | 209b97b588fce1b00855e6b3c7aeb8527eae4c0b /locks | |
parent | 1f96528919f42f60736f02bb540d290126e22a1a (diff) | |
download | libapr-aa54ab4a2bdd6dc2bbbdfd948e8edb59f8ef0d86.tar.gz |
APR lock fixes: when using SysV sems, flock(), or fcntl(), be sure
to repeat the syscall until we stop getting EINTR. I noticed a
related problem at termination (SIGTERM) on FreeBSD when using
fcntl(). Apache 1.3 had these new loops too.
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@60392 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'locks')
-rw-r--r-- | locks/unix/crossproc.c | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/locks/unix/crossproc.c b/locks/unix/crossproc.c index e543814dc..2b0fb74aa 100644 --- a/locks/unix/crossproc.c +++ b/locks/unix/crossproc.c @@ -104,16 +104,26 @@ ap_status_t ap_unix_create_inter_lock(ap_lock_t *new) ap_status_t ap_unix_lock_inter(ap_lock_t *lock) { - lock->curr_locked = 1; - if (semop(lock->interproc, &op_on, 1) < 0) { + int rc; + + do { + rc = semop(lock->interproc, &op_on, 1); + } while (rc < 0 && errno == EINTR); + if (rc < 0) { return errno; } + lock->curr_locked = 1; return APR_SUCCESS; } ap_status_t ap_unix_unlock_inter(ap_lock_t *lock) { - if (semop(lock->interproc, &op_off, 1) < 0) { + int rc; + + do { + rc = semop(lock->interproc, &op_off, 1); + } while (rc < 0 && errno == EINTR); + if (rc < 0) { return errno; } lock->curr_locked = 0; @@ -260,10 +270,7 @@ static ap_status_t lock_cleanup(void *lock_) ap_lock_t *lock=lock_; if (lock->curr_locked == 1) { - if (fcntl(lock->interproc, F_SETLKW, &unlock_it) < 0) { - return errno; - } - lock->curr_locked=0; + return ap_unix_unlock_inter(lock); } return APR_SUCCESS; } @@ -291,16 +298,26 @@ ap_status_t ap_unix_create_inter_lock(ap_lock_t *new) ap_status_t ap_unix_lock_inter(ap_lock_t *lock) { - lock->curr_locked=1; - if (fcntl(lock->interproc, F_SETLKW, &lock_it) < 0) { + int rc; + + do { + rc = fcntl(lock->interproc, F_SETLKW, &lock_it); + } while (rc < 0 && errno == EINTR); + if (rc < 0) { return errno; } + lock->curr_locked=1; return APR_SUCCESS; } ap_status_t ap_unix_unlock_inter(ap_lock_t *lock) { - if (fcntl(lock->interproc, F_SETLKW, &unlock_it) < 0) { + int rc; + + do { + rc = fcntl(lock->interproc, F_SETLKW, &unlock_it); + } while (rc < 0 && errno == EINTR); + if (rc < 0) { return errno; } lock->curr_locked=0; @@ -334,10 +351,7 @@ static ap_status_t lock_cleanup(void *lock_) ap_lock_t *lock=lock_; if (lock->curr_locked == 1) { - if (flock(lock->interproc, LOCK_UN) < 0) { - return errno; - } - lock->curr_locked = 0; + return ap_unix_unlock_inter(lock); } unlink(lock->fname); return APR_SUCCESS; @@ -364,16 +378,26 @@ ap_status_t ap_unix_create_inter_lock(ap_lock_t *new) ap_status_t ap_unix_lock_inter(ap_lock_t *lock) { - lock->curr_locked = 1; - if (flock(lock->interproc, LOCK_EX) < 0) { + int rc; + + do { + rc = flock(lock->interproc, LOCK_EX); + } while (rc < 0 && errno == EINTR); + if (rc < 0) { return errno; } + lock->curr_locked = 1; return APR_SUCCESS; } ap_status_t ap_unix_unlock_inter(ap_lock_t *lock) { - if (flock(lock->interproc, LOCK_UN) < 0) { + int rc; + + do { + rc = flock(lock->interproc, LOCK_UN); + } while (rc < 0 && errno == EINTR); + if (rc < 0) { return errno; } lock->curr_locked = 0; |