summaryrefslogtreecommitdiff
path: root/libc/pwd_grp/lckpwdf.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2006-12-07 23:24:02 +0000
committerEric Andersen <andersen@codepoet.org>2006-12-07 23:24:02 +0000
commit1478c2de052374c6356db5513749a144c13791b1 (patch)
tree3b22a3f8361f94c99508c497e240ecb71acf8641 /libc/pwd_grp/lckpwdf.c
parent99d6c367c4820a072dc4ada51561df17e2093778 (diff)
Major cleanup of internal mutex locking. Be more consistant in how we do
things, and avoid potential deadlocks caused when a thread holding a uClibc internal lock get canceled and terminates without releasing the lock. This change also provides a single place, bits/uClibc_mutex.h, for thread libraries to modify to change all instances of internal locking.
Diffstat (limited to 'libc/pwd_grp/lckpwdf.c')
-rw-r--r--libc/pwd_grp/lckpwdf.c37
1 files changed, 15 insertions, 22 deletions
diff --git a/libc/pwd_grp/lckpwdf.c b/libc/pwd_grp/lckpwdf.c
index 2d38e89f9..f241cdffc 100644
--- a/libc/pwd_grp/lckpwdf.c
+++ b/libc/pwd_grp/lckpwdf.c
@@ -48,12 +48,8 @@ libc_hidden_proto(alarm)
static int lock_fd = -1;
/* Prevent problems in multithreaded program by using mutex. */
-#ifdef __UCLIBC_HAS_THREADS__
-# include <pthread.h>
-static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
-#endif
-#define LOCK __pthread_mutex_lock(&mylock)
-#define UNLOCK __pthread_mutex_unlock(&mylock)
+#include <bits/uClibc_mutex.h>
+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
/* Prototypes for local functions. */
@@ -70,19 +66,19 @@ lckpwdf (void)
struct sigaction new_act; /* New signal action. */
struct flock fl; /* Information struct for locking. */
int result;
+ int rv = -1;
if (lock_fd != -1)
/* Still locked by own process. */
return -1;
/* Prevent problems caused by multiple threads. */
- LOCK;
+ __UCLIBC_MUTEX_LOCK(mylock);
lock_fd = open (_PATH_PASSWD, O_WRONLY);
if (lock_fd == -1) {
/* Cannot create lock file. */
- UNLOCK;
- return -1;
+ goto DONE;
}
/* Make sure file gets correctly closed when process finished. */
@@ -91,16 +87,14 @@ lckpwdf (void)
/* Cannot get file flags. */
close(lock_fd);
lock_fd = -1;
- UNLOCK;
- return -1;
+ goto DONE;
}
flags |= FD_CLOEXEC; /* Close on exit. */
if (fcntl (lock_fd, F_SETFD, flags) < 0) {
/* Cannot set new flags. */
close(lock_fd);
lock_fd = -1;
- UNLOCK;
- return -1;
+ goto DONE;
}
/* Now we have to get exclusive write access. Since multiple
@@ -121,8 +115,7 @@ lckpwdf (void)
/* Cannot install signal handler. */
close(lock_fd);
lock_fd = -1;
- UNLOCK;
- return -1;
+ goto DONE;
}
/* Now make sure the alarm signal is not blocked. */
@@ -132,8 +125,7 @@ lckpwdf (void)
sigaction (SIGALRM, &saved_act, NULL);
close(lock_fd);
lock_fd = -1;
- UNLOCK;
- return -1;
+ goto DONE;
}
/* Start timer. If we cannot get the lock in the specified time we
@@ -160,11 +152,12 @@ lckpwdf (void)
if (result < 0) {
close(lock_fd);
lock_fd = -1;
- UNLOCK;
- return -1;
+ goto DONE;
}
+ rv = 0;
- UNLOCK;
+DONE:
+ __UCLIBC_MUTEX_UNLOCK(mylock);
return 0;
}
@@ -180,7 +173,7 @@ ulckpwdf (void)
else
{
/* Prevent problems caused by multiple threads. */
- LOCK;
+ __UCLIBC_MUTEX_LOCK(mylock);
result = close (lock_fd);
@@ -188,7 +181,7 @@ ulckpwdf (void)
lock_fd = -1;
/* Clear mutex. */
- UNLOCK;
+ __UCLIBC_MUTEX_UNLOCK(mylock);
}
return result;