This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
On Tue, Mar 20, 2001 at 10:50:14AM -0800, Ulrich Drepper wrote:
> I've checked in a patch I got quite some time ago and which I delayed
> for the 2.2 release. It is introducing thread-safe RPC functions,
> similar to what Solaris has. This should not introduce
> incompatibilities since programs currently using RPC functions in
> different threads are doomed.
>
> I had to modify the patch quite a lot and have done only a tiny bit of
> testing myself. Please test it out.
Here is a harmless typo patch.
Anyway, after second look at the patch, the patch does introduce
incompatibilities even in programs not using RPC functions in different
threads, particularly that the exported svc_fdset, rpc_createerr, svc_pollfd
and svc_max_pollfd variables will be always 0 all the time (which breaks I
think am-utils and other programs).
Here is a patch I wrote today, it builds fine but have not tested it yet.
What it does is (in order to avoid having svc_fdset_s etc. as pointers to
the actual variables) exporting svc_fdset etc. as aliases into the
__libc_tsd_RPC_VARS_mem variable and making sure __libc_tsd_RPC_VARS_mem
is used in non-threaded apps and for the first thread using rpc in threaded
apps (several programs like am-utils are linked against -lpthread, yet use
rpc just in one thread) and we should maintain binary compatibility there.
Also, it exports __rpc_thread_variables to userland, so that threads can
access svc_fdset etc. and see there meaningful things.
The __dummy field seems unfortunately necessary, since otherwise the alias
gets for some reason the size of the whole __libc_tsd_RPC_VARS_mem and not
just of the field in it.
2001-03-23 Jakub Jelinek <jakub@redhat.com>
* include/rpc/rpc.h (rpc_thread_variables): Use a special structure
for global exported variables.
(__rpc_thread_variables): Remove prototype.
(svc_fdset, rpc_createerr, svc_pollfd, svc_max_pollfd): Remove.
* sunrpc/rpc/clnt.h (struct __rpc_thread_variables_s): New.
(__rpc_thread_variables): Add prototype.
(__RPC_THREAD_VARIABLE, rpc_createerr): Define.
* sunrpc/rpc/svc.h (svc_fdset, svc_pollfd, svc_max_pollfd): Define.
* sunrpc/rpc_common.c (svc_fdset, rpc_createerr, svc_pollfd,
svc_max_pollfd): Only declare if not thread safe.
* sunrpc/rpc_thread.c (svc_fdset, rpc_createerr, svc_pollfd,
svc_max_pollfd): Declare as aliases into __libc_tsd_RPC_VARS_mem.
(__rpc_thread_do_destroy): New.
(__rpc_thread_destroy): Use it. Don't free __libc_tsd_RPC_VARS_mem.
(__rpc_thread_variables): In threaded application, use
__libc_tsd_RPC_VARS_mem for the first thread which calls
__rpc_thread_variables.
(free_mem): New.
* sunrpc/clnt_perr.c (free_mem): Only declare if not thread safe.
* sunrpc/auth_none.c (authnone_private): Fix a typo.
* sunrpc/Versions (__rpc_thread_variables): Export @GLIBC_2.2.3.
--- libc/include/rpc/rpc.h.jj Wed Mar 21 15:44:51 2001
+++ libc/include/rpc/rpc.h Fri Mar 23 15:24:21 2001
@@ -11,10 +11,7 @@ extern unsigned long _create_xid (void);
*/
#ifdef _RPC_THREAD_SAFE_
struct rpc_thread_variables {
- fd_set svc_fdset_s; /* Global, rpc_common.c */
- struct rpc_createerr rpc_createerr_s; /* Global, rpc_common.c */
- struct pollfd *svc_pollfd_s; /* Global, rpc_common.c */
- int svc_max_pollfd_s; /* Global, rpc_common.c */
+ struct __rpc_thread_variables_s var_s; /* Global, rpc_thread.c */
void *authnone_private_s; /* auth_none.c */
@@ -38,23 +35,14 @@ struct rpc_thread_variables {
void *svcsimple_transp_s; /* svc_simple.c */
};
-extern struct rpc_thread_variables *__rpc_thread_variables(void)
- __attribute__ ((const));
extern void __rpc_thread_svc_cleanup (void);
extern void __rpc_thread_clnt_cleanup (void);
extern void __rpc_thread_key_cleanup (void);
extern void __rpc_thread_destroy (void);
-#define RPC_THREAD_VARIABLE(x) (__rpc_thread_variables()->x)
-
-/*
- * Global variables
- */
-#define svc_fdset RPC_THREAD_VARIABLE(svc_fdset_s)
-#define rpc_createerr RPC_THREAD_VARIABLE(rpc_createerr_s)
-#define svc_pollfd RPC_THREAD_VARIABLE(svc_pollfd_s)
-#define svc_max_pollfd RPC_THREAD_VARIABLE(svc_max_pollfd_s)
+#define RPC_THREAD_VARIABLE(x) \
+ (((struct rpc_thread_variables *)__rpc_thread_variables())->x)
#endif /* _RPC_THREAD_SAFE_ */
--- libc/sunrpc/rpc/clnt.h.jj Wed Aug 2 21:36:33 2000
+++ libc/sunrpc/rpc/clnt.h Fri Mar 23 15:42:11 2001
@@ -394,7 +394,23 @@ struct rpc_createerr {
extern struct rpc_createerr rpc_createerr;
+#if !defined _LIBC || defined _RPC_THREAD_SAFE_
+struct __rpc_thread_variables_s {
+ int __dummy;
+ int __svc_max_pollfd;
+ struct pollfd *__svc_pollfd;
+ fd_set __svc_fdset;
+ struct rpc_createerr __rpc_createerr;
+};
+
+extern struct __rpc_thread_variables_s *__rpc_thread_variables(void)
+ __attribute__ ((const));
+
+#define __RPC_THREAD_VARIABLE(x) (__rpc_thread_variables()->x)
+#define rpc_createerr __RPC_THREAD_VARIABLE(__rpc_createerr)
+
+#endif /* _RPC_THREAD_SAFE_ */
/*
* Copy error message to buffer.
--- libc/sunrpc/rpc/svc.h.jj Wed Aug 2 21:36:33 2000
+++ libc/sunrpc/rpc/svc.h Fri Mar 23 15:27:20 2001
@@ -263,6 +263,13 @@ extern void svcerr_systemerr (SVCXPRT *_
extern struct pollfd *svc_pollfd;
extern int svc_max_pollfd;
extern fd_set svc_fdset;
+
+#if !defined _LIBC || defined _RPC_THREAD_SAFE_
+#define svc_fdset __RPC_THREAD_VARIABLE(__svc_fdset)
+#define svc_pollfd __RPC_THREAD_VARIABLE(__svc_pollfd)
+#define svc_max_pollfd __RPC_THREAD_VARIABLE(__svc_max_pollfd)
+#endif /* _RPC_THREAD_SAFE_ */
+
#define svc_fds svc_fdset.fds_bits[0] /* compatibility */
/*
--- libc/sunrpc/auth_none.c.jj Wed Mar 21 15:44:52 2001
+++ libc/sunrpc/auth_none.c Fri Mar 23 11:45:54 2001
@@ -62,7 +62,7 @@ struct authnone_private_s {
u_int mcnt;
};
#ifdef _RPC_THREAD_SAFE_
-#define authnone_private ((struct authnone_private_ *)RPC_THREAD_VARIABLE(authnone_private_s))
+#define authnone_private ((struct authnone_private_s *)RPC_THREAD_VARIABLE(authnone_private_s))
#else
static struct authnone_private_s *authnone_private;
#endif
--- libc/sunrpc/rpc_common.c.jj Wed Mar 21 15:44:52 2001
+++ libc/sunrpc/rpc_common.c Fri Mar 23 12:21:23 2001
@@ -28,19 +28,14 @@
*/
#include <rpc/rpc.h>
-#ifdef _RPC_THREAD_SAFE_
-#undef svc_fdset
-#undef rpc_createerr
-#undef svc_pollfd
-#undef svc_max_pollfd
-#endif /* _RPC_THREAD_SAFE_ */
-
/*
* This file should only contain common data (global data) that is exported
* by public interfaces
*/
struct opaque_auth _null_auth;
+#ifndef _RPC_THREAD_SAFE_
fd_set svc_fdset;
struct rpc_createerr rpc_createerr;
struct pollfd *svc_pollfd;
int svc_max_pollfd;
+#endif
--- libc/sunrpc/rpc_thread.c.jj Tue Mar 20 19:32:02 2001
+++ libc/sunrpc/rpc_thread.c Fri Mar 23 15:38:21 2001
@@ -1,3 +1,4 @@
+#include <stddef.h>
#include <stdio.h>
#include <bits/libc-lock.h>
#include <rpc/rpc.h>
@@ -15,41 +16,86 @@ static struct rpc_thread_variables *__li
&__libc_tsd_RPC_VARS_mem;
/*
+ * Export globally some members of __libc_tsd_RPC_VARS_mem.
+ */
+#define S_(x) #x
+#define S(x) S_(x)
+#ifdef HAVE_ASM_SET_DIRECTIVE
+#define A(x,y) ".set " S_(x) "," S_(y)
+#else
+#define A(x,y) S_(x) " = " S_(y)
+#endif
+#define V(var) \
+ asm volatile ( \
+ S(ASM_GLOBAL_DIRECTIVE) " " S(C_SYMBOL_NAME(var)) S(ASM_LINE_SEP) \
+ ".type " S(C_SYMBOL_NAME(var)) ",@object" S(ASM_LINE_SEP) \
+ ".size " S(C_SYMBOL_NAME(var)) ",%c0" S(ASM_LINE_SEP) \
+ A(C_SYMBOL_NAME(var), \
+ C_SYMBOL_NAME(__libc_tsd_RPC_VARS_mem) + %c1) S(ASM_LINE_SEP) \
+ : : "i" (sizeof (__libc_tsd_RPC_VARS_mem.var_s.__##var)), \
+ "i" (offsetof (struct rpc_thread_variables, var_s.__##var)));
+
+#undef svc_fdset
+#undef rpc_createerr
+#undef svc_pollfd
+#undef svc_max_pollfd
+
+static void
+__rpc_thread_do_destroy (struct rpc_thread_variables *tvp)
+{
+ V (svc_fdset)
+ V (rpc_createerr)
+ V (svc_pollfd)
+ V (svc_max_pollfd)
+
+ free (tvp->authnone_private_s);
+ free (tvp->clnt_perr_buf_s);
+ free (tvp->clntraw_private_s);
+ free (tvp->svcraw_private_s);
+ free (tvp->authdes_cache_s);
+ free (tvp->authdes_lru_s);
+}
+
+/*
* Task-variable destructor
*/
void
__rpc_thread_destroy (void)
{
- struct rpc_thread_variables *tvp = __rpc_thread_variables();
+ struct rpc_thread_variables *tvp =
+ (struct rpc_thread_variables *)__rpc_thread_variables();
- if (tvp != NULL) {
+ if (tvp != NULL && tvp != &__libc_tsd_RPC_VARS_mem) {
__rpc_thread_svc_cleanup ();
__rpc_thread_clnt_cleanup ();
__rpc_thread_key_cleanup ();
- free (tvp->authnone_private_s);
- free (tvp->clnt_perr_buf_s);
- free (tvp->clntraw_private_s);
- free (tvp->svcraw_private_s);
- free (tvp->authdes_cache_s);
- free (tvp->authdes_lru_s);
+ __rpc_thread_do_destroy (tvp);
free (tvp);
}
}
-struct rpc_thread_variables *
+struct __rpc_thread_variables_s *
__rpc_thread_variables (void)
{
struct rpc_thread_variables *tvp;
tvp = __libc_tsd_get (RPC_VARS);
if (tvp == NULL) {
- tvp = calloc (1, sizeof *tvp);
- if (tvp != NULL)
- __libc_tsd_set (RPC_VARS, tvp);
- else
- tvp = __libc_tsd_RPC_VARS_data;
+ __libc_lock_define_initialized (static, tvp_lock)
+ if (!__libc_lock_trylock (tvp_lock)
+ || (tvp = calloc (1, sizeof *tvp)) == NULL)
+ tvp = &__libc_tsd_RPC_VARS_mem;
+ __libc_tsd_set (RPC_VARS, tvp);
}
- return tvp;
+ return (struct __rpc_thread_variables_s *) tvp;
}
+
+static void __attribute__ ((unused))
+free_mem (void)
+{
+ __rpc_thread_do_destroy (&__libc_tsd_RPC_VARS_mem);
+}
+text_set_element (__libc_subfreeres, free_mem);
+
#endif /* _RPC_THREAD_SAFE_ */
--- libc/sunrpc/clnt_perr.c.jj Wed Mar 21 15:44:52 2001
+++ libc/sunrpc/clnt_perr.c Fri Mar 23 14:16:26 2001
@@ -391,10 +391,11 @@ auth_errmsg (enum auth_stat stat)
return NULL;
}
-
+#ifndef _RPC_THREAD_SAFE_
static void __attribute__ ((unused))
free_mem (void)
{
free (buf);
}
text_set_element (__libc_subfreeres, free_mem);
+#endif
--- libc/sunrpc/Versions.jj Wed Mar 21 15:44:52 2001
+++ libc/sunrpc/Versions Fri Mar 23 15:12:35 2001
@@ -110,6 +110,6 @@ libc {
svc_getreq_common; svc_getreq_poll; svc_max_pollfd; svc_pollfd;
}
GLIBC_2.2.3 {
- __rpc_thread_destroy;
+ __rpc_thread_destroy; __rpc_thread_variables;
}
}
Jakub
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |