* libio/stdio.h (vscanf): Fix -std=c99 redirect.
[kopensolaris-gnu/glibc.git] / sunrpc / rpc_thread.c
1 #include <stdio.h>
2 #include <bits/libc-lock.h>
3 #include <rpc/rpc.h>
4 #include <assert.h>
5
6 #include <bits/libc-lock.h>
7 #include <bits/libc-tsd.h>
8
9 #ifdef _RPC_THREAD_SAFE_
10
11 /* Variable used in non-threaded applications or for the first thread.  */
12 static struct rpc_thread_variables __libc_tsd_RPC_VARS_mem;
13 __libc_tsd_define (, RPC_VARS)
14
15 /*
16  * Task-variable destructor
17  */
18 void __attribute__ ((section ("__libc_thread_freeres_fn")))
19 __rpc_thread_destroy (void)
20 {
21         struct rpc_thread_variables *tvp = __libc_tsd_get (RPC_VARS);
22
23         if (tvp != NULL) {
24                 __rpc_thread_svc_cleanup ();
25                 __rpc_thread_clnt_cleanup ();
26                 __rpc_thread_key_cleanup ();
27                 free (tvp->clnt_perr_buf_s);
28                 free (tvp->clntraw_private_s);
29                 free (tvp->svcraw_private_s);
30                 free (tvp->authdes_cache_s);
31                 free (tvp->authdes_lru_s);
32                 free (tvp->svc_xports_s);
33                 free (tvp->svc_pollfd_s);
34                 if (tvp != &__libc_tsd_RPC_VARS_mem)
35                         free (tvp);
36                 __libc_tsd_set (RPC_VARS, NULL);
37         }
38 }
39 #ifdef _LIBC_REENTRANT
40 text_set_element (__libc_thread_subfreeres, __rpc_thread_destroy);
41 #endif
42 text_set_element (__libc_subfreeres, __rpc_thread_destroy);
43
44
45 /*
46  * Initialize RPC multi-threaded operation
47  */
48 static void
49 rpc_thread_multi (void)
50 {
51   __libc_tsd_set (RPC_VARS, &__libc_tsd_RPC_VARS_mem);
52 }
53
54
55 struct rpc_thread_variables *
56 __rpc_thread_variables (void)
57 {
58         __libc_once_define (static, once);
59         struct rpc_thread_variables *tvp;
60
61         tvp = __libc_tsd_get (RPC_VARS);
62         if (tvp == NULL) {
63                 __libc_once (once, rpc_thread_multi);
64                 tvp = __libc_tsd_get (RPC_VARS);
65                 if (tvp == NULL) {
66                         tvp = calloc (1, sizeof *tvp);
67                         if (tvp != NULL)
68                                 __libc_tsd_set (RPC_VARS, tvp);
69                         else
70                                 tvp = __libc_tsd_get (RPC_VARS);
71                 }
72         }
73         return tvp;
74 }
75
76
77 /* Global variables If we're single-threaded, or if this is the first
78    thread using the variable, use the existing global variable.  This
79    provides backwards compatability for existing applications which
80    dynamically link against this code.  */
81 #undef svc_fdset
82 #undef rpc_createerr
83 #undef svc_pollfd
84 #undef svc_max_pollfd
85
86 fd_set *
87 __rpc_thread_svc_fdset (void)
88 {
89         struct rpc_thread_variables *tvp;
90
91         tvp = __rpc_thread_variables ();
92         if (tvp == &__libc_tsd_RPC_VARS_mem)
93                 return &svc_fdset;
94         return &tvp->svc_fdset_s;
95 }
96 libc_hidden_def (__rpc_thread_svc_fdset)
97
98 struct rpc_createerr *
99 __rpc_thread_createerr (void)
100 {
101         struct rpc_thread_variables *tvp;
102
103         tvp = __rpc_thread_variables ();
104         if (tvp == &__libc_tsd_RPC_VARS_mem)
105                 return &rpc_createerr;
106         return &tvp->rpc_createerr_s;
107 }
108 libc_hidden_def (__rpc_thread_createerr)
109
110 struct pollfd **
111 __rpc_thread_svc_pollfd (void)
112 {
113         struct rpc_thread_variables *tvp;
114
115         tvp = __rpc_thread_variables ();
116         if (tvp == &__libc_tsd_RPC_VARS_mem)
117                 return &svc_pollfd;
118         return &tvp->svc_pollfd_s;
119 }
120 libc_hidden_def (__rpc_thread_svc_pollfd)
121
122 int *
123 __rpc_thread_svc_max_pollfd (void)
124 {
125         struct rpc_thread_variables *tvp;
126
127         tvp = __rpc_thread_variables ();
128         if (tvp == &__libc_tsd_RPC_VARS_mem)
129                 return &svc_max_pollfd;
130         return &tvp->svc_max_pollfd_s;
131 }
132 libc_hidden_def (__rpc_thread_svc_max_pollfd)
133
134 #endif /* _RPC_THREAD_SAFE_ */