diff options
author | Eric Andersen <andersen@codepoet.org> | 2006-12-07 23:24:02 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2006-12-07 23:24:02 +0000 |
commit | 1478c2de052374c6356db5513749a144c13791b1 (patch) | |
tree | 3b22a3f8361f94c99508c497e240ecb71acf8641 /libc/stdio | |
parent | 99d6c367c4820a072dc4ada51561df17e2093778 (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/stdio')
-rw-r--r-- | libc/stdio/popen.c | 33 |
1 files changed, 17 insertions, 16 deletions
diff --git a/libc/stdio/popen.c b/libc/stdio/popen.c index 2163d7f8c..43d07fa0f 100644 --- a/libc/stdio/popen.c +++ b/libc/stdio/popen.c @@ -20,6 +20,11 @@ #include <errno.h> #include <unistd.h> #include <sys/wait.h> +#include <bits/uClibc_mutex.h> + +#ifdef __UCLIBC_MJN3_ONLY__ +#warning "hmm... susv3 says Pipe streams are byte-oriented." +#endif /* __UCLIBC_MJN3_ONLY__ */ libc_hidden_proto(close) libc_hidden_proto(_exit) @@ -34,22 +39,16 @@ libc_hidden_proto(fclose) /* uClinux-2.0 has vfork, but Linux 2.0 doesn't */ #include <sys/syscall.h> #if ! defined __NR_vfork -# define vfork fork +# define vfork fork # define VFORK_LOCK ((void) 0) -# define VFORK_UNLOCK ((void) 0) +# define VFORK_UNLOCK ((void) 0) libc_hidden_proto(fork) #endif -#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) - #ifndef VFORK_LOCK -# define VFORK_LOCK LOCK -# define VFORK_UNLOCK UNLOCK +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); +# define VFORK_LOCK __UCLIBC_MUTEX_LOCK(mylock) +# define VFORK_UNLOCK __UCLIBC_MUTEX_UNLOCK(mylock) #endif struct popen_list_item { @@ -126,11 +125,11 @@ FILE *popen(const char *command, const char *modes) if (pid > 0) { /* Parent of vfork... */ pi->pid = pid; pi->f = fp; - LOCK; + VFORK_LOCK; pi->next = popen_list; popen_list = pi; - UNLOCK; - + VFORK_UNLOCK; + return fp; } @@ -144,6 +143,8 @@ FILE *popen(const char *command, const char *modes) return NULL; } +#warning is pclose correct wrt the new mutex semantics? + int pclose(FILE *stream) { struct popen_list_item *p; @@ -152,7 +153,7 @@ int pclose(FILE *stream) /* First, find the list entry corresponding to stream and remove it * from the list. Set p to the list item (NULL if not found). */ - LOCK; + VFORK_LOCK; if ((p = popen_list) != NULL) { if (p->f == stream) { popen_list = p->next; @@ -171,7 +172,7 @@ int pclose(FILE *stream) } while (1); } } - UNLOCK; + VFORK_UNLOCK; if (p) { pid = p->pid; /* Save the pid we need */ |