blob: 71303b2be7ef49aa2788c53193bfa34782cf890c [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/*
2 * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
3 *
4 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
5 */
6
7#define __FORCE_GLIBC
8#include <features.h>
9#include <stdio.h>
10#include <assert.h>
11#include "rpc_private.h"
12
13
14#ifdef __UCLIBC_HAS_THREADS__
15
16#include <bits/libc-tsd.h>
17#include <bits/libc-lock.h>
18
19/* Variable used in non-threaded applications or for the first thread. */
20static struct rpc_thread_variables __libc_tsd_RPC_VARS_mem;
21__libc_tsd_define (, RPC_VARS)
22
23/*
24 * Task-variable destructor
25 */
26void
27__rpc_thread_destroy (void)
28{
29 struct rpc_thread_variables *tvp = __libc_tsd_get (RPC_VARS);
30
31 if (tvp != NULL && tvp != &__libc_tsd_RPC_VARS_mem) {
32 __rpc_thread_svc_cleanup ();
33 __rpc_thread_clnt_cleanup ();
34 /*__rpc_thread_key_cleanup (); */
35 free (tvp->authnone_private_s);
36 free (tvp->clnt_perr_buf_s);
37 free (tvp->clntraw_private_s);
38 free (tvp->svcraw_private_s);
39 free (tvp->authdes_cache_s);
40 free (tvp->authdes_lru_s);
41 free (tvp);
42 __libc_tsd_set (RPC_VARS, NULL);
43 }
44}
45
46/*
47 * Initialize RPC multi-threaded operation
48 */
49static void
50rpc_thread_multi (void)
51{
52 __libc_tsd_set (RPC_VARS, &__libc_tsd_RPC_VARS_mem);
53}
54
55
56struct rpc_thread_variables attribute_hidden *
57__rpc_thread_variables (void)
58{
59 __libc_once_define (static, once);
60 struct rpc_thread_variables *tvp;
61
62 tvp = __libc_tsd_get (RPC_VARS);
63 if (tvp == NULL) {
64 __libc_once (once, rpc_thread_multi);
65 tvp = __libc_tsd_get (RPC_VARS);
66 if (tvp == NULL) {
67 tvp = calloc (1, sizeof *tvp);
68 if (tvp != NULL)
69 __libc_tsd_set (RPC_VARS, tvp);
70 else
71 tvp = __libc_tsd_get (RPC_VARS);
72 }
73 }
74 return tvp;
75}
76
77
78/* Global variables If we're single-threaded, or if this is the first
79 thread using the variable, use the existing global variable. This
80 provides backwards compatability for existing applications which
81 dynamically link against this code. */
82#undef svc_fdset
83#undef rpc_createerr
84#undef svc_pollfd
85#undef svc_max_pollfd
86
87fd_set *
88__rpc_thread_svc_fdset (void)
89{
90 struct rpc_thread_variables *tvp;
91
92 tvp = __rpc_thread_variables ();
93 if (tvp == &__libc_tsd_RPC_VARS_mem)
94 return &svc_fdset;
95 return &tvp->svc_fdset_s;
96}
97
98struct 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
109struct pollfd **
110__rpc_thread_svc_pollfd (void)
111{
112 struct rpc_thread_variables *tvp;
113
114 tvp = __rpc_thread_variables ();
115 if (tvp == &__libc_tsd_RPC_VARS_mem)
116 return &svc_pollfd;
117 return &tvp->svc_pollfd_s;
118}
119
120int *
121__rpc_thread_svc_max_pollfd (void)
122{
123 struct rpc_thread_variables *tvp;
124
125 tvp = __rpc_thread_variables ();
126 if (tvp == &__libc_tsd_RPC_VARS_mem)
127 return &svc_max_pollfd;
128 return &tvp->svc_max_pollfd_s;
129}
130#else
131
132#undef svc_fdset
133#undef rpc_createerr
134#undef svc_pollfd
135#undef svc_max_pollfd
136
137extern fd_set svc_fdset;
138fd_set * __rpc_thread_svc_fdset (void)
139{
140 return &(svc_fdset);
141}
142
143extern struct rpc_createerr rpc_createerr;
144struct rpc_createerr * __rpc_thread_createerr (void)
145{
146 return &(rpc_createerr);
147}
148
149extern struct pollfd *svc_pollfd;
150struct pollfd ** __rpc_thread_svc_pollfd (void)
151{
152 return &(svc_pollfd);
153}
154
155extern int svc_max_pollfd;
156int * __rpc_thread_svc_max_pollfd (void)
157{
158 return &(svc_max_pollfd);
159}
160
161#endif /* __UCLIBC_HAS_THREADS__ */
162
163libc_hidden_def(__rpc_thread_svc_fdset)
164libc_hidden_def(__rpc_thread_createerr)
165libc_hidden_def(__rpc_thread_svc_pollfd)
166libc_hidden_def(__rpc_thread_svc_max_pollfd)