summaryrefslogtreecommitdiff
path: root/libc/inet/getservice.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/inet/getservice.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/inet/getservice.c')
-rw-r--r--libc/inet/getservice.c48
1 files changed, 22 insertions, 26 deletions
diff --git a/libc/inet/getservice.c b/libc/inet/getservice.c
index 7f4939bbd..5a94c9c69 100644
--- a/libc/inet/getservice.c
+++ b/libc/inet/getservice.c
@@ -72,12 +72,8 @@ libc_hidden_proto(rewind)
libc_hidden_proto(fgets)
libc_hidden_proto(abort)
-#ifdef __UCLIBC_HAS_THREADS__
-# include <pthread.h>
-static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
-#endif
-#define LOCK __pthread_mutex_lock(&mylock)
-#define UNLOCK __pthread_mutex_unlock(&mylock)
+#include <bits/uClibc_mutex.h>
+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
@@ -102,26 +98,26 @@ static void __initbuf(void)
libc_hidden_proto(setservent)
void setservent(int f)
{
- LOCK;
+ __UCLIBC_MUTEX_LOCK(mylock);
if (servf == NULL)
servf = fopen(_PATH_SERVICES, "r" );
else
rewind(servf);
serv_stayopen |= f;
- UNLOCK;
+ __UCLIBC_MUTEX_UNLOCK(mylock);
}
libc_hidden_def(setservent)
libc_hidden_proto(endservent)
void endservent(void)
{
- LOCK;
+ __UCLIBC_MUTEX_LOCK(mylock);
if (servf) {
fclose(servf);
servf = NULL;
}
serv_stayopen = 0;
- UNLOCK;
+ __UCLIBC_MUTEX_UNLOCK(mylock);
}
libc_hidden_def(endservent)
@@ -134,6 +130,7 @@ int getservent_r(struct servent * result_buf,
register char *cp, **q;
char **serv_aliases;
char *line;
+ int rv;
*result=NULL;
@@ -141,30 +138,27 @@ int getservent_r(struct servent * result_buf,
errno=ERANGE;
return errno;
}
- LOCK;
+ __UCLIBC_MUTEX_LOCK(mylock);
serv_aliases=(char **)buf;
buf+=sizeof(*serv_aliases)*MAXALIASES;
buflen-=sizeof(*serv_aliases)*MAXALIASES;
if (buflen < BUFSIZ+1) {
- UNLOCK;
- errno=ERANGE;
- return errno;
+ errno=rv=ERANGE;
+ goto DONE;
}
line=buf;
buf+=BUFSIZ+1;
buflen-=BUFSIZ+1;
if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) {
- UNLOCK;
- errno=EIO;
- return errno;
+ errno=rv=EIO;
+ goto DONE;
}
again:
if ((p = fgets(line, BUFSIZ, servf)) == NULL) {
- UNLOCK;
- errno=EIO;
- return errno;
+ errno=rv=EIO;
+ goto DONE;
}
if (*p == '#')
goto again;
@@ -202,8 +196,10 @@ again:
}
*q = NULL;
*result=result_buf;
- UNLOCK;
- return 0;
+ rv = 0;
+DONE:
+ __UCLIBC_MUTEX_UNLOCK(mylock);
+ return rv;
}
libc_hidden_def(getservent_r)
@@ -224,7 +220,7 @@ int getservbyname_r(const char *name, const char *proto,
register char **cp;
int ret;
- LOCK;
+ __UCLIBC_MUTEX_LOCK(mylock);
setservent(serv_stayopen);
while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
if (strcmp(name, result_buf->s_name) == 0)
@@ -239,7 +235,7 @@ gotname:
}
if (!serv_stayopen)
endservent();
- UNLOCK;
+ __UCLIBC_MUTEX_UNLOCK(mylock);
return *result?0:ret;
}
libc_hidden_def(getservbyname_r)
@@ -261,7 +257,7 @@ int getservbyport_r(int port, const char *proto,
{
int ret;
- LOCK;
+ __UCLIBC_MUTEX_LOCK(mylock);
setservent(serv_stayopen);
while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
if (result_buf->s_port != port)
@@ -271,7 +267,7 @@ int getservbyport_r(int port, const char *proto,
}
if (!serv_stayopen)
endservent();
- UNLOCK;
+ __UCLIBC_MUTEX_UNLOCK(mylock);
return *result?0:ret;
}
libc_hidden_def(getservbyport_r)