summaryrefslogtreecommitdiff
path: root/locks
diff options
context:
space:
mode:
authortrawick <trawick@13f79535-47bb-0310-9956-ffa450edef68>2000-07-19 16:35:48 +0000
committertrawick <trawick@13f79535-47bb-0310-9956-ffa450edef68>2000-07-19 16:35:48 +0000
commitaa54ab4a2bdd6dc2bbbdfd948e8edb59f8ef0d86 (patch)
tree209b97b588fce1b00855e6b3c7aeb8527eae4c0b /locks
parent1f96528919f42f60736f02bb540d290126e22a1a (diff)
downloadlibapr-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.c58
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;