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] |