Subject: Re: getaddrinfo() vs. JVM
To: None <tech-userlevel@netbsd.org>
From: Charles M. Hannum <abuse@spamalicious.com>
List: tech-userlevel
Date: 01/07/2005 21:52:25
--Boundary-00=_ZSw3B0eomWd/MXe
Content-Type: text/plain;
  charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

> 2) Put a mutex around getservbyname() and/or getaddrinfo().  Is there a way
> to do this in libc that will work both with and without libpthread?

I've done this.  See the following patches.

--Boundary-00=_ZSw3B0eomWd/MXe
Content-Type: text/x-diff;
  charset="iso-8859-1";
  name="getfoo.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="getfoo.diff"

Index: getprotobyname.c
===================================================================
RCS file: /cvsroot/src/lib/libc/net/getprotobyname.c,v
retrieving revision 1.1
diff -u -r1.1 getprotobyname.c
--- getprotobyname.c	19 Feb 2004 19:27:26 -0000	1.1
+++ getprotobyname.c	7 Jan 2005 21:50:35 -0000
@@ -41,18 +41,26 @@
 #endif /* LIBC_SCCS and not lint */
 
 #include "namespace.h"
-#include <assert.h>
+#include "reentrant.h"
+
 #include <netdb.h>
-#include <string.h>
 
 #ifdef __weak_alias
 __weak_alias(getprotobyname,_getprotobyname)
 #endif
 
+#ifdef _REENTRANT
+extern mutex_t _protoent_mutex;
+#endif
 extern struct protoent_data _protoent_data;
 
 struct protoent *
 getprotobyname(const char *name)
 {
-	return getprotobyname_r(name, &_protoent_data.proto, &_protoent_data);
+	struct protoent *p;
+
+	mutex_lock(&_protoent_mutex);
+	p = getprotobyname_r(name, &_protoent_data.proto, &_protoent_data);
+	mutex_unlock(&_protoent_mutex);
+	return (p);
 }
Index: getprotobynumber.c
===================================================================
RCS file: /cvsroot/src/lib/libc/net/getprotobynumber.c,v
retrieving revision 1.1
diff -u -r1.1 getprotobynumber.c
--- getprotobynumber.c	19 Feb 2004 19:27:26 -0000	1.1
+++ getprotobynumber.c	7 Jan 2005 21:50:35 -0000
@@ -42,17 +42,26 @@
 #endif /* LIBC_SCCS and not lint */
 
 #include "namespace.h"
+#include "reentrant.h"
+
 #include <netdb.h>
 
 #ifdef __weak_alias
 __weak_alias(getprotobynumber,_getprotobynumber)
 #endif
 
+#ifdef _REENTRANT
+extern mutex_t _protoent_mutex;
+#endif
 extern struct protoent_data _protoent_data;
 
 struct protoent *
 getprotobynumber(int proto)
 {
-	return getprotobynumber_r(proto, &_protoent_data.proto,
-	    &_protoent_data);
+	struct protoent *p;
+
+	mutex_lock(&_protoent_mutex);
+	p = getprotobynumber_r(proto, &_protoent_data.proto, &_protoent_data);
+	mutex_unlock(&_protoent_mutex);
+	return (p);
 }
Index: getprotoent.c
===================================================================
RCS file: /cvsroot/src/lib/libc/net/getprotoent.c,v
retrieving revision 1.9
diff -u -r1.9 getprotoent.c
--- getprotoent.c	19 Feb 2004 19:27:26 -0000	1.9
+++ getprotoent.c	7 Jan 2005 21:50:35 -0000
@@ -42,6 +42,8 @@
 #endif /* LIBC_SCCS and not lint */
 
 #include "namespace.h"
+#include "reentrant.h"
+
 #include <netdb.h>
 
 #ifdef __weak_alias
@@ -50,22 +52,34 @@
 __weak_alias(setprotoent,_setprotoent)
 #endif
 
+#ifdef _REENTRANT
+mutex_t _protoent_mutex = MUTEX_INITIALIZER;
+#endif
 struct protoent_data _protoent_data;
 
 void
 setprotoent(int f)
 {
+	mutex_lock(&_protoent_mutex);
 	setprotoent_r(f, &_protoent_data);
+	mutex_unlock(&_protoent_mutex);
 }
 
 void
 endprotoent(void)
 {
+	mutex_lock(&_protoent_mutex);
 	endprotoent_r(&_protoent_data);
+	mutex_unlock(&_protoent_mutex);
 }
 
 struct protoent *
 getprotoent(void)
 {
-	return getprotoent_r(&_protoent_data.proto, &_protoent_data);
+	struct protoent *p;
+
+	mutex_lock(&_protoent_mutex);
+	p = getprotoent_r(&_protoent_data.proto, &_protoent_data);
+	mutex_unlock(&_protoent_mutex);
+	return (p);
 }
Index: getservbyname.c
===================================================================
RCS file: /cvsroot/src/lib/libc/net/getservbyname.c,v
retrieving revision 1.11
diff -u -r1.11 getservbyname.c
--- getservbyname.c	19 Feb 2004 19:27:26 -0000	1.11
+++ getservbyname.c	7 Jan 2005 21:50:35 -0000
@@ -41,19 +41,26 @@
 #endif /* LIBC_SCCS and not lint */
 
 #include "namespace.h"
-#include <assert.h>
+#include "reentrant.h"
+
 #include <netdb.h>
-#include <string.h>
 
 #ifdef __weak_alias
 __weak_alias(getservbyname,_getservbyname)
 #endif
 
+#ifdef _REENTRANT
+extern mutex_t _servent_mutex;
+#endif
 extern struct servent_data _servent_data;
 
 struct servent *
 getservbyname(const char *name, const char *proto)
 {
-	return getservbyname_r(name, proto,
-	    &_servent_data.serv, &_servent_data);
+	struct servent *s;
+
+	mutex_lock(&_servent_mutex);
+	s = getservbyname_r(name, proto, &_servent_data.serv, &_servent_data);
+	mutex_unlock(&_servent_mutex);
+	return (s);
 }
Index: getservbyport.c
===================================================================
RCS file: /cvsroot/src/lib/libc/net/getservbyport.c,v
retrieving revision 1.9
diff -u -r1.9 getservbyport.c
--- getservbyport.c	19 Feb 2004 19:27:26 -0000	1.9
+++ getservbyport.c	7 Jan 2005 21:50:35 -0000
@@ -42,17 +42,26 @@
 #endif /* LIBC_SCCS and not lint */
 
 #include "namespace.h"
+#include "reentrant.h"
+
 #include <netdb.h>
 
 #ifdef __weak_alias
 __weak_alias(getservbyport,_getservbyport)
 #endif
 
+#ifdef _REENTRANT
+extern mutex_t _servent_mutex;
+#endif
 extern struct servent_data _servent_data;
 
 struct servent *
 getservbyport(int port, const char *proto)
 {
-	return getservbyport_r(port, proto, &_servent_data.serv,
-	    &_servent_data);
+	struct servent *s;
+
+	mutex_lock(&_servent_mutex);
+	s = getservbyport_r(port, proto, &_servent_data.serv, &_servent_data);
+	mutex_unlock(&_servent_mutex);
+	return (s);
 }
Index: getservent.c
===================================================================
RCS file: /cvsroot/src/lib/libc/net/getservent.c,v
retrieving revision 1.9
diff -u -r1.9 getservent.c
--- getservent.c	19 Feb 2004 19:27:26 -0000	1.9
+++ getservent.c	7 Jan 2005 21:50:35 -0000
@@ -42,6 +42,8 @@
 #endif /* LIBC_SCCS and not lint */
 
 #include "namespace.h"
+#include "reentrant.h"
+
 #include <netdb.h>
 
 #ifdef __weak_alias
@@ -50,22 +52,34 @@
 __weak_alias(setservent,_setservent)
 #endif
 
+#ifdef _REENTRANT
+mutex_t _servent_mutex = MUTEX_INITIALIZER;
+#endif
 struct servent_data _servent_data;
 
 void
 setservent(int f)
 {
+	mutex_lock(&_servent_mutex);
 	setservent_r(f, &_servent_data);
+	mutex_unlock(&_servent_mutex);
 }
 
 void
 endservent(void)
 {
+	mutex_lock(&_servent_mutex);
 	endservent_r(&_servent_data);
+	mutex_unlock(&_servent_mutex);
 }
 
 struct servent *
 getservent(void)
 {
-	return getservent_r(&_servent_data.serv, &_servent_data);
+	struct servent *s;
+
+	mutex_lock(&_servent_mutex);
+	s = getservent_r(&_servent_data.serv, &_servent_data);
+	mutex_unlock(&_servent_mutex);
+	return (s);
 }

--Boundary-00=_ZSw3B0eomWd/MXe--