Back to index

glibc  2.9
rpc_thread.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <bits/libc-lock.h>
00003 #include <rpc/rpc.h>
00004 #include <assert.h>
00005 
00006 #include <bits/libc-lock.h>
00007 #include <bits/libc-tsd.h>
00008 
00009 #ifdef _RPC_THREAD_SAFE_
00010 
00011 /* Variable used in non-threaded applications or for the first thread.  */
00012 static struct rpc_thread_variables __libc_tsd_RPC_VARS_mem;
00013 __libc_tsd_define (, struct rpc_thread_variables *, RPC_VARS)
00014 
00015 /*
00016  * Task-variable destructor
00017  */
00018 void __attribute__ ((section ("__libc_thread_freeres_fn")))
00019 __rpc_thread_destroy (void)
00020 {
00021        struct rpc_thread_variables *tvp
00022          = __libc_tsd_get (struct rpc_thread_variables *, RPC_VARS);
00023 
00024        if (tvp != NULL) {
00025               __rpc_thread_svc_cleanup ();
00026               __rpc_thread_clnt_cleanup ();
00027               __rpc_thread_key_cleanup ();
00028               free (tvp->clnt_perr_buf_s);
00029               free (tvp->clntraw_private_s);
00030               free (tvp->svcraw_private_s);
00031               free (tvp->authdes_cache_s);
00032               free (tvp->authdes_lru_s);
00033               free (tvp->svc_xports_s);
00034               free (tvp->svc_pollfd_s);
00035               if (tvp != &__libc_tsd_RPC_VARS_mem)
00036                      free (tvp);
00037               __libc_tsd_set (struct rpc_thread_variables *, RPC_VARS, NULL);
00038        }
00039 }
00040 #ifdef _LIBC_REENTRANT
00041 text_set_element (__libc_thread_subfreeres, __rpc_thread_destroy);
00042 #endif
00043 text_set_element (__libc_subfreeres, __rpc_thread_destroy);
00044 
00045 
00046 /*
00047  * Initialize RPC multi-threaded operation
00048  */
00049 static void
00050 rpc_thread_multi (void)
00051 {
00052   __libc_tsd_set (struct rpc_thread_variables *, RPC_VARS,
00053                 &__libc_tsd_RPC_VARS_mem);
00054 }
00055 
00056 
00057 struct rpc_thread_variables *
00058 __rpc_thread_variables (void)
00059 {
00060        __libc_once_define (static, once);
00061        struct rpc_thread_variables *tvp;
00062 
00063        tvp = __libc_tsd_get (struct rpc_thread_variables *, RPC_VARS);
00064        if (tvp == NULL) {
00065               __libc_once (once, rpc_thread_multi);
00066               tvp = __libc_tsd_get (struct rpc_thread_variables *, RPC_VARS);
00067               if (tvp == NULL) {
00068                      tvp = calloc (1, sizeof *tvp);
00069                      if (tvp != NULL)
00070                             __libc_tsd_set (struct rpc_thread_variables *,
00071                                           RPC_VARS, tvp);
00072                      else
00073                             tvp = __libc_tsd_get (struct rpc_thread_variables *,
00074                                                 RPC_VARS);
00075               }
00076        }
00077        return tvp;
00078 }
00079 
00080 
00081 /* Global variables If we're single-threaded, or if this is the first
00082    thread using the variable, use the existing global variable.  This
00083    provides backwards compatability for existing applications which
00084    dynamically link against this code.  */
00085 #undef svc_fdset
00086 #undef rpc_createerr
00087 #undef svc_pollfd
00088 #undef svc_max_pollfd
00089 
00090 fd_set *
00091 __rpc_thread_svc_fdset (void)
00092 {
00093        struct rpc_thread_variables *tvp;
00094 
00095        tvp = __rpc_thread_variables ();
00096        if (tvp == &__libc_tsd_RPC_VARS_mem)
00097               return &svc_fdset;
00098        return &tvp->svc_fdset_s;
00099 }
00100 libc_hidden_def (__rpc_thread_svc_fdset)
00101 
00102 struct rpc_createerr *
00103 __rpc_thread_createerr (void)
00104 {
00105        struct rpc_thread_variables *tvp;
00106 
00107        tvp = __rpc_thread_variables ();
00108        if (tvp == &__libc_tsd_RPC_VARS_mem)
00109               return &rpc_createerr;
00110        return &tvp->rpc_createerr_s;
00111 }
00112 libc_hidden_def (__rpc_thread_createerr)
00113 
00114 struct pollfd **
00115 __rpc_thread_svc_pollfd (void)
00116 {
00117        struct rpc_thread_variables *tvp;
00118 
00119        tvp = __rpc_thread_variables ();
00120        if (tvp == &__libc_tsd_RPC_VARS_mem)
00121               return &svc_pollfd;
00122        return &tvp->svc_pollfd_s;
00123 }
00124 libc_hidden_def (__rpc_thread_svc_pollfd)
00125 
00126 int *
00127 __rpc_thread_svc_max_pollfd (void)
00128 {
00129        struct rpc_thread_variables *tvp;
00130 
00131        tvp = __rpc_thread_variables ();
00132        if (tvp == &__libc_tsd_RPC_VARS_mem)
00133               return &svc_max_pollfd;
00134        return &tvp->svc_max_pollfd_s;
00135 }
00136 libc_hidden_def (__rpc_thread_svc_max_pollfd)
00137 
00138 #endif /* _RPC_THREAD_SAFE_ */