| From 5c797a24a7d6337b5e654079a8d815199b1e8364 Mon Sep 17 00:00:00 2001 |
| From: Carmelo Amoroso <carmelo.amoroso@st.com> |
| Date: Thu, 2 Feb 2012 18:22:36 +0100 |
| Subject: [PATCH] inet:rpc: fix authnone_marshal in multithreading context |
| |
| This is a port of glibc's fix by Zack Weinberg as reported |
| in http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=142312, |
| and discussed in http://sourceware.org/ml/libc-alpha/2002-04/msg00069.html |
| and following. |
| |
| Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com> |
| --- |
| libc/inet/rpc/auth_none.c | 59 +++++++++++++++++++++---------------------- |
| libc/inet/rpc/rpc_private.h | 2 -- |
| libc/inet/rpc/rpc_thread.c | 1 - |
| 3 files changed, 29 insertions(+), 33 deletions(-) |
| |
| diff --git a/libc/inet/rpc/auth_none.c b/libc/inet/rpc/auth_none.c |
| index c48bbfe..d066f6b 100644 |
| --- a/libc/inet/rpc/auth_none.c |
| +++ b/libc/inet/rpc/auth_none.c |
| @@ -66,49 +66,48 @@ struct authnone_private_s { |
| char marshalled_client[MAX_MARSHAL_SIZE]; |
| u_int mcnt; |
| }; |
| -#ifdef __UCLIBC_HAS_THREADS__ |
| -#define authnone_private (*(struct authnone_private_s **)&RPC_THREAD_VARIABLE(authnone_private_s)) |
| -#else |
| -static struct authnone_private_s *authnone_private; |
| -#endif |
| |
| -AUTH * |
| -authnone_create (void) |
| +static struct authnone_private_s authnone_private; |
| +__libc_once_define(static, authnone_private_guard); |
| + |
| +static void authnone_create_once (void); |
| + |
| +static void |
| +authnone_create_once (void) |
| { |
| struct authnone_private_s *ap; |
| XDR xdr_stream; |
| XDR *xdrs; |
| |
| - ap = (struct authnone_private_s *) authnone_private; |
| - if (ap == NULL) |
| - { |
| - ap = (struct authnone_private_s *) calloc (1, sizeof (*ap)); |
| - if (ap == NULL) |
| - return NULL; |
| - authnone_private = ap; |
| - } |
| - if (!ap->mcnt) |
| - { |
| - ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth; |
| - ap->no_client.ah_ops = (struct auth_ops *)&ops; |
| - xdrs = &xdr_stream; |
| - xdrmem_create (xdrs, ap->marshalled_client, (u_int) MAX_MARSHAL_SIZE, |
| - XDR_ENCODE); |
| - (void) xdr_opaque_auth (xdrs, &ap->no_client.ah_cred); |
| - (void) xdr_opaque_auth (xdrs, &ap->no_client.ah_verf); |
| - ap->mcnt = XDR_GETPOS (xdrs); |
| - XDR_DESTROY (xdrs); |
| - } |
| - return (&ap->no_client); |
| + ap = &authnone_private; |
| + |
| + ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth; |
| + ap->no_client.ah_ops = (struct auth_ops *) &ops; |
| + xdrs = &xdr_stream; |
| + xdrmem_create(xdrs, ap->marshalled_client, |
| + (u_int) MAX_MARSHAL_SIZE, XDR_ENCODE); |
| + (void) xdr_opaque_auth(xdrs, &ap->no_client.ah_cred); |
| + (void) xdr_opaque_auth(xdrs, &ap->no_client.ah_verf); |
| + ap->mcnt = XDR_GETPOS (xdrs); |
| + XDR_DESTROY (xdrs); |
| +} |
| + |
| +AUTH * |
| +authnone_create (void) |
| +{ |
| + __libc_once (authnone_private_guard, authnone_create_once); |
| + return &authnone_private.no_client; |
| } |
| libc_hidden_def(authnone_create) |
| |
| static bool_t |
| -authnone_marshal (AUTH *client attribute_unused, XDR *xdrs) |
| +authnone_marshal (AUTH *client, XDR *xdrs) |
| { |
| struct authnone_private_s *ap; |
| |
| - ap = authnone_private; |
| + /* authnone_create returned authnone_private->no_client, which is |
| + the first field of struct authnone_private_s. */ |
| + ap = (struct authnone_private_s *) client; |
| if (ap == NULL) |
| return FALSE; |
| return (*xdrs->x_ops->x_putbytes) (xdrs, ap->marshalled_client, ap->mcnt); |
| diff --git a/libc/inet/rpc/rpc_private.h b/libc/inet/rpc/rpc_private.h |
| index ede3ddf..e1214d2 100644 |
| --- a/libc/inet/rpc/rpc_private.h |
| +++ b/libc/inet/rpc/rpc_private.h |
| @@ -18,8 +18,6 @@ struct rpc_thread_variables { |
| struct pollfd *svc_pollfd_s; /* Global, rpc_common.c */ |
| int svc_max_pollfd_s; /* Global, rpc_common.c */ |
| |
| - void *authnone_private_s; /* auth_none.c */ |
| - |
| void *clnt_perr_buf_s; /* clnt_perr.c */ |
| |
| void *clntraw_private_s; /* clnt_raw.c */ |
| diff --git a/libc/inet/rpc/rpc_thread.c b/libc/inet/rpc/rpc_thread.c |
| index 71303b2..3367659 100644 |
| --- a/libc/inet/rpc/rpc_thread.c |
| +++ b/libc/inet/rpc/rpc_thread.c |
| @@ -32,7 +32,6 @@ __rpc_thread_destroy (void) |
| __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); |
| -- |
| 1.7.10.4 |
| |