Date: Sun, 24 Jan 2010 04:18:48 +0900 From: Hajimu UMEMOTO <ume@FreeBSD.org> To: Gabor Kovesdan <gabor@FreeBSD.org> Cc: Kostik Belousov <kostikbel@gmail.com>, attilio@FreeBSD.org, current@FreeBSD.org Subject: Re: NLS/strerror efficiency Message-ID: <yge1vhgvdd3.wl%ume@mahoroba.org> In-Reply-To: <4B56CACF.50508@FreeBSD.org> References: <20100119212019.GL59590@deviant.kiev.zoral.com.ua> <4B56CACF.50508@FreeBSD.org>
next in thread | previous in thread | raw e-mail | index | archive | help
--Multipart_Sun_Jan_24_04:18:48_2010-1
Content-Type: text/plain; charset=ISO-2022-JP-2
Hi,
>>>>> On Wed, 20 Jan 2010 10:20:15 +0100
>>>>> Gabor Kovesdan <gabor@FreeBSD.org> said:
gabor> El 2010. 01. 19. 22:20, Kostik Belousov escribi$(D+Q(B:
> Hi,
> r189765 enabled NLS support for libc. Now, any strerror(3) call causes
> 4 (!) failing stat(2) calls. I think this is untolerable.
>
> Catopen() does not cache the catalog descriptor, at least for libc,
> at least for the case where the open failed.
>
gabor> Hi Kostik,
gabor> thank you for pointing this out. I'll check the code to see how we could
gabor> add a caching for the failing catalogs. I'll post the patch here when
gabor> I'm done.
The gai_strerror(3) has same issue. How about the attached patch in
this mail?
Sincerely,
--Multipart_Sun_Jan_24_04:18:48_2010-1
Content-Type: text/x-patch; type=patch; charset=US-ASCII
Content-Disposition: attachment; filename="strerror-lock.diff"
Content-Transfer-Encoding: 7bit
Index: lib/libc/include/libc_private.h
diff -u lib/libc/include/libc_private.h.orig lib/libc/include/libc_private.h
--- lib/libc/include/libc_private.h.orig 2010-01-01 02:14:04.000000000 +0900
+++ lib/libc/include/libc_private.h 2010-01-24 03:39:20.480514921 +0900
@@ -211,4 +211,10 @@
/* execve() with PATH processing to implement posix_spawnp() */
int _execvpe(const char *, char * const *, char * const *);
+#ifdef NLS
+extern char *__cat_gets(int, int, const char *);
+extern void __cat_lock(void);
+extern void __cat_unlock(void);
+#endif
+
#endif /* _LIBC_PRIVATE_H_ */
Index: lib/libc/net/gai_strerror.c
diff -u -p lib/libc/net/gai_strerror.c.orig lib/libc/net/gai_strerror.c
--- lib/libc/net/gai_strerror.c.orig 2009-11-23 02:05:46.000000000 +0900
+++ lib/libc/net/gai_strerror.c 2010-01-24 03:30:15.086490501 +0900
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD: src/lib/libc/net/gai
#include "reentrant.h"
#endif
#include "un-namespace.h"
+#include "libc_private.h"
/* Entries EAI_ADDRFAMILY (1) and EAI_NODATA (7) are obsoleted, but left */
/* for backward compatibility with userland code prior to 2553bis-02 */
@@ -79,7 +80,6 @@ const char *
gai_strerror(int ecode)
{
#if defined(NLS)
- nl_catd catd;
char *buf;
if (thr_main() != 0)
@@ -98,17 +98,17 @@ gai_strerror(int ecode)
}
}
- catd = catopen("libc", NL_CAT_LOCALE);
+ __cat_lock();
if (ecode > 0 && ecode < EAI_MAX)
- strlcpy(buf, catgets(catd, 3, ecode, ai_errlist[ecode]),
+ strlcpy(buf, __cat_gets(3, ecode, ai_errlist[ecode]),
sizeof(gai_buf));
else if (ecode == 0)
- strlcpy(buf, catgets(catd, 3, NL_MSGMAX - 1, "Success"),
+ strlcpy(buf, __cat_gets(3, NL_MSGMAX - 1, "Success"),
sizeof(gai_buf));
else
- strlcpy(buf, catgets(catd, 3, NL_MSGMAX, "Unknown error"),
+ strlcpy(buf, __cat_gets(3, NL_MSGMAX, "Unknown error"),
sizeof(gai_buf));
- catclose(catd);
+ __cat_unlock();
return buf;
thr_err:
Index: lib/libc/string/strerror.c
diff -u -p lib/libc/string/strerror.c.orig lib/libc/string/strerror.c
--- lib/libc/string/strerror.c.orig 2009-08-03 17:13:06.000000000 +0900
+++ lib/libc/string/strerror.c 2010-01-24 04:11:37.168662523 +0900
@@ -33,14 +33,16 @@ static char sccsid[] = "@(#)strerror.c 8
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/lib/libc/string/strerror.c,v 1.16.10.1 2009/08/03 08:13:06 kensmith Exp $");
-#if defined(NLS)
-#include <nl_types.h>
-#endif
-
+#include "namespace.h"
#include <limits.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
+#if defined(NLS)
+#include <nl_types.h>
+#include "reentrant.h"
+#endif
+#include "un-namespace.h"
#define UPREFIX "Unknown error"
@@ -52,6 +54,31 @@ __FBSDID("$FreeBSD: src/lib/libc/string/
*/
#define EBUFSIZE (20 + 2 + sizeof(UPREFIX))
+#if defined(NLS)
+static mutex_t catd_mutex = MUTEX_INITIALIZER;
+static nl_catd catd;
+
+char *
+__cat_gets(int set_id, int msg_id, const char *s)
+{
+ if (catd == NULL)
+ catd = catopen("libc", NL_CAT_LOCALE);
+ return (catgets(catd, set_id, msg_id, s));
+}
+
+void
+__cat_lock(void)
+{
+ mutex_lock(&catd_mutex);
+}
+
+void
+__cat_unlock(void)
+{
+ mutex_unlock(&catd_mutex);
+}
+#endif
+
/*
* Doing this by hand instead of linking with stdio(3) avoids bloat for
* statically linked binaries.
@@ -83,14 +110,14 @@ strerror_r(int errnum, char *strerrbuf,
int retval = 0;
#if defined(NLS)
int saved_errno = errno;
- nl_catd catd;
- catd = catopen("libc", NL_CAT_LOCALE);
+
+ __cat_lock();
#endif
if (errnum < 1 || errnum >= sys_nerr) {
errstr(errnum,
#if defined(NLS)
- catgets(catd, 1, 0xffff, UPREFIX),
+ __cat_gets(1, 0xffff, UPREFIX),
#else
UPREFIX,
#endif
@@ -99,7 +126,7 @@ strerror_r(int errnum, char *strerrbuf,
} else {
if (strlcpy(strerrbuf,
#if defined(NLS)
- catgets(catd, 1, errnum, sys_errlist[errnum]),
+ __cat_gets(1, errnum, sys_errlist[errnum]),
#else
sys_errlist[errnum],
#endif
@@ -108,7 +135,7 @@ strerror_r(int errnum, char *strerrbuf,
}
#if defined(NLS)
- catclose(catd);
+ __cat_unlock();
errno = saved_errno;
#endif
--Multipart_Sun_Jan_24_04:18:48_2010-1
Content-Type: text/plain; charset=US-ASCII
--
Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan
ume@mahoroba.org ume@{,jp.}FreeBSD.org
http://www.imasy.org/~ume/
--Multipart_Sun_Jan_24_04:18:48_2010-1--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?yge1vhgvdd3.wl%ume>
