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]

[PATCH] RPC changes


On Fri, Mar 23, 2001 at 03:00:15PM +0100, Jakub Jelinek wrote:
> 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.

Actually, it was not that bright idea, since copy relocation screws it up.
Here is an updated patch which uses one more level of indirection.
I've tested it so far just by looking at addresses of the 4 variables and
what __rpc_thread_variables() gives (including calling it from separate
thread) and it looked ok.
The only problem I see is that <rpc/clnt.h> defines rpc_createerr as a
macro, so if some rpc code uses something like:
int foo(void)
{
  struct rpc_createerr x = rpc_createerr;
}
then it will not compile. I'm not sure what can be done about that, it was
a bad idea to call the structure with the same name as the variable.
Perhaps we could leave svc_* as it is in the patch below and don't define
rpc_createerr as macro outside of glibc, instead define rpc_get_createerr()
as macro and threaded programs would be recommended to use that instead of
rpc_createerr.

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_thread.c (__rpc_thread_do_destroy): New.
	(__rpc_thread_destroy): Use it. Don't free __libc_tsd_RPC_VARS_mem.
	(struct __rpc_thread_vars): New.
	(__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 17:05:22 2001
@@ -394,7 +394,22 @@ struct rpc_createerr {
 
 extern struct rpc_createerr rpc_createerr;
 
+#if !defined _LIBC || defined _RPC_THREAD_SAFE_
 
+struct __rpc_thread_variables_s {
+	int *__const __svc_max_pollfd;
+	struct pollfd ** __const __svc_pollfd;
+	fd_set * __const __svc_fdset;
+	struct rpc_createerr * __const __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_thread.c.jj	Tue Mar 20 19:32:02 2001
+++ libc/sunrpc/rpc_thread.c	Fri Mar 23 17:07:10 2001
@@ -1,3 +1,4 @@
+#include <stddef.h>
 #include <stdio.h>
 #include <bits/libc-lock.h>
 #include <rpc/rpc.h>
@@ -8,11 +9,27 @@
 
 #ifdef _RPC_THREAD_SAFE_
 
+#undef svc_fdset
+#undef rpc_createerr
+#undef svc_pollfd
+#undef svc_max_pollfd
 
 /* Variable used in non-threaded applications.  */
-static struct rpc_thread_variables __libc_tsd_RPC_VARS_mem;
+static struct rpc_thread_variables __libc_tsd_RPC_VARS_mem =
+{ { &svc_max_pollfd, &svc_pollfd, &svc_fdset, &rpc_createerr }, 0 };
 static struct rpc_thread_variables *__libc_tsd_RPC_VARS_data =
-     &__libc_tsd_RPC_VARS_mem;
+  &__libc_tsd_RPC_VARS_mem;
+
+static void
+__rpc_thread_do_destroy (struct rpc_thread_variables *tvp)
+{
+  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
@@ -20,36 +37,61 @@ static struct rpc_thread_variables *__li
 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) {
-		__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);
-		free (tvp);
-	}
+  if (tvp != NULL && tvp != &__libc_tsd_RPC_VARS_mem)
+    {
+      __rpc_thread_svc_cleanup ();
+      __rpc_thread_clnt_cleanup ();
+      __rpc_thread_key_cleanup ();
+      __rpc_thread_do_destroy (tvp);
+      free (tvp);
+    }
 }
 
+struct __rpc_thread_vars {
+  struct rpc_thread_variables s;
+  int svc_max_pollfd;
+  struct pollfd *svc_pollfd;
+  fd_set svc_fdset;
+  struct rpc_createerr rpc_createerr;
+};
 
-struct rpc_thread_variables *
+struct __rpc_thread_variables_s *
 __rpc_thread_variables (void)
 {
-	struct rpc_thread_variables *tvp;
+  struct __rpc_thread_vars *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;
+  tvp = __libc_tsd_get (RPC_VARS);
+  if (tvp == NULL)
+    {
+      __libc_lock_define_initialized (static, tvp_lock)
+      if (__libc_lock_trylock (tvp_lock))
+	{
+	  tvp = calloc (1, sizeof *tvp);
+	  if (tvp == NULL)
+	    tvp = (struct __rpc_thread_vars *)&__libc_tsd_RPC_VARS_mem;
+	  else
+	    {
+	      *(void *)&tvp->s.var_s.__svc_max_pollfd = &tvp->svc_max_pollfd;
+	      *(void *)&tvp->s.var_s.__svc_pollfd = &tvp->svc_pollfd;
+	      *(void *)&tvp->s.var_s.__svc_fdset = &tvp->svc_fdset;
+	      *(void *)&tvp->s.var_s.__rpc_createerr = &tvp->rpc_createerr;
+	    }
 	}
-	return tvp;
+      else
+	tvp = (struct __rpc_thread_vars *)&__libc_tsd_RPC_VARS_mem;
+      __libc_tsd_set (RPC_VARS, 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]