Sat Nov 7 20:24:00 2015 UTC ()
spell reserved.


(christos)
diff -r1.7 -r1.8 src/lib/libc/rpc/svc_fdset.c

cvs diff -r1.7 -r1.8 src/lib/libc/rpc/svc_fdset.c (switch to unified diff)

--- src/lib/libc/rpc/svc_fdset.c 2015/11/07 16:58:24 1.7
+++ src/lib/libc/rpc/svc_fdset.c 2015/11/07 20:24:00 1.8
@@ -1,316 +1,316 @@ @@ -1,316 +1,316 @@
1/* $NetBSD: svc_fdset.c,v 1.7 2015/11/07 16:58:24 christos Exp $ */ 1/* $NetBSD: svc_fdset.c,v 1.8 2015/11/07 20:24:00 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2015 The NetBSD Foundation, Inc. 4 * Copyright (c) 2015 The NetBSD Foundation, Inc.
5 * All rights resefdsed. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas. 8 * by Christos Zoulas.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__RCSID("$NetBSD: svc_fdset.c,v 1.7 2015/11/07 16:58:24 christos Exp $"); 33__RCSID("$NetBSD: svc_fdset.c,v 1.8 2015/11/07 20:24:00 christos Exp $");
34 34
35 35
36#include "reentrant.h" 36#include "reentrant.h"
37 37
38#include <sys/fd_set.h> 38#include <sys/fd_set.h>
39 39
40#include <rpc/rpc.h> 40#include <rpc/rpc.h>
41 41
42#ifdef FDSET_DEBUG 42#ifdef FDSET_DEBUG
43#include <stdio.h> 43#include <stdio.h>
44#include <stdarg.h> 44#include <stdarg.h>
45#include <unistd.h> 45#include <unistd.h>
46#include <lwp.h> 46#include <lwp.h>
47#endif 47#endif
48#include <stdlib.h> 48#include <stdlib.h>
49#include <string.h> 49#include <string.h>
50 50
51#include "svc_fdset.h" 51#include "svc_fdset.h"
52 52
53#undef svc_fdset 53#undef svc_fdset
54#undef svc_maxfd 54#undef svc_maxfd
55extern __fd_set_256 svc_fdset; 55extern __fd_set_256 svc_fdset;
56extern int svc_maxfd; 56extern int svc_maxfd;
57 57
58struct svc_fdset { 58struct svc_fdset {
59 fd_set *fdset; 59 fd_set *fdset;
60 int fdmax; 60 int fdmax;
61 int fdsize; 61 int fdsize;
62}; 62};
63 63
64/* The single threaded, one global fd_set version */ 64/* The single threaded, one global fd_set version */
65static struct svc_fdset __svc_fdset; 65static struct svc_fdset __svc_fdset;
66 66
67static thread_key_t fdsetkey = -2; 67static thread_key_t fdsetkey = -2;
68 68
69#ifdef FDSET_DEBUG 69#ifdef FDSET_DEBUG
70 70
71static void __printflike(3, 0) 71static void __printflike(3, 0)
72svc_header(const char *func, size_t line, const char *fmt, va_list ap) 72svc_header(const char *func, size_t line, const char *fmt, va_list ap)
73{ 73{
74 fprintf(stderr, "%s[%d.%d]: %s, %zu: ", getprogname(), (int)getpid(), 74 fprintf(stderr, "%s[%d.%d]: %s, %zu: ", getprogname(), (int)getpid(),
75 (int)_lwp_self(), func, line); 75 (int)_lwp_self(), func, line);
76 vfprintf(stderr, fmt, ap); 76 vfprintf(stderr, fmt, ap);
77 va_end(ap); 77 va_end(ap);
78} 78}
79 79
80static void __printflike(4, 5) 80static void __printflike(4, 5)
81svc_fdset_print(const char *func, size_t line, struct svc_fdset *fds,  81svc_fdset_print(const char *func, size_t line, struct svc_fdset *fds,
82 const char *fmt, ...) 82 const char *fmt, ...)
83{ 83{
84 va_list ap; 84 va_list ap;
85 const char *did = ""; 85 const char *did = "";
86 86
87 va_start(ap, fmt); 87 va_start(ap, fmt);
88 svc_header(func, line, fmt, ap); 88 svc_header(func, line, fmt, ap);
89 va_end(ap); 89 va_end(ap);
90 90
91 fprintf(stderr, "%p[%d] <", fds->fdset, fds->fdmax); 91 fprintf(stderr, "%p[%d] <", fds->fdset, fds->fdmax);
92 for (int i = 0; i <= fds->fdmax; i++) { 92 for (int i = 0; i <= fds->fdmax; i++) {
93 if (!FD_ISSET(i, fds->fdset)) 93 if (!FD_ISSET(i, fds->fdset))
94 continue; 94 continue;
95 fprintf(stderr, "%s%d", did, i); 95 fprintf(stderr, "%s%d", did, i);
96 did = ", "; 96 did = ", ";
97 } 97 }
98 fprintf(stderr, ">\n"); 98 fprintf(stderr, ">\n");
99} 99}
100 100
101static void __printflike(3, 4) 101static void __printflike(3, 4)
102svc_print(const char *func, size_t line, const char *fmt, ...) 102svc_print(const char *func, size_t line, const char *fmt, ...)
103{ 103{
104 va_list ap; 104 va_list ap;
105 105
106 va_start(ap, fmt); 106 va_start(ap, fmt);
107 svc_header(func, line, fmt, ap); 107 svc_header(func, line, fmt, ap);
108 va_end(ap); 108 va_end(ap);
109 fprintf(stderr, "\n"); 109 fprintf(stderr, "\n");
110} 110}
111 111
112#define DPRINTF(...) svc_print(__func__, __LINE__, __VA_ARGS__) 112#define DPRINTF(...) svc_print(__func__, __LINE__, __VA_ARGS__)
113#define DPRINTF_FDSET(...) svc_fdset_print(__func__, __LINE__, __VA_ARGS__) 113#define DPRINTF_FDSET(...) svc_fdset_print(__func__, __LINE__, __VA_ARGS__)
114 114
115#else 115#else
116 116
117#define DPRINTF(...) 117#define DPRINTF(...)
118#define DPRINTF_FDSET(...) 118#define DPRINTF_FDSET(...)
119 119
120#endif 120#endif
121 121
122 122
123static inline void 123static inline void
124svc_fdset_sanitize(struct svc_fdset *fds) 124svc_fdset_sanitize(struct svc_fdset *fds)
125{ 125{
126 while (fds->fdmax >= 0 && !FD_ISSET(fds->fdmax, fds->fdset)) 126 while (fds->fdmax >= 0 && !FD_ISSET(fds->fdmax, fds->fdset))
127 fds->fdmax--; 127 fds->fdmax--;
128 /* Compat update */ 128 /* Compat update */
129 if (fds == &__svc_fdset) { 129 if (fds == &__svc_fdset) {
130 svc_fdset = *(__fd_set_256 *)__svc_fdset.fdset; 130 svc_fdset = *(__fd_set_256 *)__svc_fdset.fdset;
131 svc_maxfd = __svc_fdset.fdmax; 131 svc_maxfd = __svc_fdset.fdmax;
132 } 132 }
133} 133}
134 134
135static void 135static void
136svc_fdset_free(void *v) 136svc_fdset_free(void *v)
137{ 137{
138 struct svc_fdset *fds = v; 138 struct svc_fdset *fds = v;
139 DPRINTF_FDSET(fds, "free"); 139 DPRINTF_FDSET(fds, "free");
140 140
141 free(fds->fdset); 141 free(fds->fdset);
142 free(fds); 142 free(fds);
143} 143}
144 144
145static struct svc_fdset * 145static struct svc_fdset *
146svc_fdset_resize(int fd, struct svc_fdset *fds) 146svc_fdset_resize(int fd, struct svc_fdset *fds)
147{ 147{
148 if (fds->fdset && fd < fds->fdsize) { 148 if (fds->fdset && fd < fds->fdsize) {
149 DPRINTF_FDSET(fds, "keeping %d < %d", fd, fds->fdsize); 149 DPRINTF_FDSET(fds, "keeping %d < %d", fd, fds->fdsize);
150 return fds; 150 return fds;
151 } 151 }
152 152
153 fd += FD_SETSIZE;  153 fd += FD_SETSIZE;
154 154
155 char *newfdset = realloc(fds->fdset, __NFD_BYTES(fd)); 155 char *newfdset = realloc(fds->fdset, __NFD_BYTES(fd));
156 if (newfdset == NULL) 156 if (newfdset == NULL)
157 return NULL; 157 return NULL;
158 158
159 memset(newfdset + __NFD_BYTES(fds->fdsize), 0, 159 memset(newfdset + __NFD_BYTES(fds->fdsize), 0,
160 __NFD_BYTES(fd) - __NFD_BYTES(fds->fdsize)); 160 __NFD_BYTES(fd) - __NFD_BYTES(fds->fdsize));
161 161
162 162
163 fds->fdset = (void *)newfdset; 163 fds->fdset = (void *)newfdset;
164 DPRINTF_FDSET(fds, "resize %d > %d", fd, fds->fdsize); 164 DPRINTF_FDSET(fds, "resize %d > %d", fd, fds->fdsize);
165 fds->fdsize = fd; 165 fds->fdsize = fd;
166 166
167 return fds; 167 return fds;
168} 168}
169 169
170static struct svc_fdset * 170static struct svc_fdset *
171svc_fdset_alloc(int fd) 171svc_fdset_alloc(int fd)
172{ 172{
173 struct svc_fdset *fds; 173 struct svc_fdset *fds;
174 174
175 if (!__isthreaded || fdsetkey == -2) 175 if (!__isthreaded || fdsetkey == -2)
176 return svc_fdset_resize(fd, &__svc_fdset); 176 return svc_fdset_resize(fd, &__svc_fdset);
177 177
178 if (fdsetkey == -1) 178 if (fdsetkey == -1)
179 thr_keycreate(&fdsetkey, svc_fdset_free); 179 thr_keycreate(&fdsetkey, svc_fdset_free);
180 180
181 if ((fds = thr_getspecific(fdsetkey)) == NULL) { 181 if ((fds = thr_getspecific(fdsetkey)) == NULL) {
182 182
183 fds = calloc(1, sizeof(*fds)); 183 fds = calloc(1, sizeof(*fds));
184 if (fds == NULL) 184 if (fds == NULL)
185 return NULL; 185 return NULL;
186 186
187 (void)thr_setspecific(fdsetkey, fds); 187 (void)thr_setspecific(fdsetkey, fds);
188 188
189 if (__svc_fdset.fdsize != 0) { 189 if (__svc_fdset.fdsize != 0) {
190 *fds = __svc_fdset; 190 *fds = __svc_fdset;
191 DPRINTF("switching to %p", fds->fdset); 191 DPRINTF("switching to %p", fds->fdset);
192 } else { 192 } else {
193 DPRINTF("first thread time %p", fds->fdset); 193 DPRINTF("first thread time %p", fds->fdset);
194 } 194 }
195 } else { 195 } else {
196 DPRINTF("again for %p", fds->fdset); 196 DPRINTF("again for %p", fds->fdset);
197 if (fd < fds->fdsize) 197 if (fd < fds->fdsize)
198 return fds; 198 return fds;
199 } 199 }
200 200
201 return svc_fdset_resize(fd, fds); 201 return svc_fdset_resize(fd, fds);
202} 202}
203 203
204/* allow each thread to have their own copy */ 204/* allow each thread to have their own copy */
205void 205void
206svc_fdset_init(int flags) 206svc_fdset_init(int flags)
207{ 207{
208 DPRINTF("%x", flags); 208 DPRINTF("%x", flags);
209 if ((flags & SVC_FDSET_MT) && fdsetkey == -2) 209 if ((flags & SVC_FDSET_MT) && fdsetkey == -2)
210 fdsetkey = -1; 210 fdsetkey = -1;
211} 211}
212 212
213void 213void
214svc_fdset_zero(void) 214svc_fdset_zero(void)
215{ 215{
216 DPRINTF("zero"); 216 DPRINTF("zero");
217 struct svc_fdset *fds = svc_fdset_alloc(0); 217 struct svc_fdset *fds = svc_fdset_alloc(0);
218 memset(fds->fdset, 0, fds->fdsize); 218 memset(fds->fdset, 0, fds->fdsize);
219 fds->fdmax = -1; 219 fds->fdmax = -1;
220} 220}
221 221
222int 222int
223svc_fdset_set(int fd) 223svc_fdset_set(int fd)
224{ 224{
225 struct svc_fdset *fds = svc_fdset_alloc(fd); 225 struct svc_fdset *fds = svc_fdset_alloc(fd);
226 226
227 if (fds == NULL) 227 if (fds == NULL)
228 return -1; 228 return -1;
229 229
230 FD_SET(fd, fds->fdset); 230 FD_SET(fd, fds->fdset);
231 if (fd > fds->fdmax) 231 if (fd > fds->fdmax)
232 fds->fdmax = fd; 232 fds->fdmax = fd;
233 233
234 DPRINTF_FDSET(fds, "%d", fd); 234 DPRINTF_FDSET(fds, "%d", fd);
235 235
236 svc_fdset_sanitize(fds); 236 svc_fdset_sanitize(fds);
237 return 0; 237 return 0;
238} 238}
239 239
240int 240int
241svc_fdset_isset(int fd) 241svc_fdset_isset(int fd)
242{ 242{
243 struct svc_fdset *fds = svc_fdset_alloc(fd); 243 struct svc_fdset *fds = svc_fdset_alloc(fd);
244 244
245 if (fds == NULL) 245 if (fds == NULL)
246 return -1; 246 return -1;
247 247
248 DPRINTF_FDSET(fds, "%d", fd); 248 DPRINTF_FDSET(fds, "%d", fd);
249 249
250 return FD_ISSET(fd, fds->fdset) != 0; 250 return FD_ISSET(fd, fds->fdset) != 0;
251} 251}
252 252
253int 253int
254svc_fdset_clr(int fd) 254svc_fdset_clr(int fd)
255{ 255{
256 struct svc_fdset *fds = svc_fdset_alloc(fd); 256 struct svc_fdset *fds = svc_fdset_alloc(fd);
257 257
258 if (fds == NULL) 258 if (fds == NULL)
259 return -1; 259 return -1;
260 260
261 FD_CLR(fd, fds->fdset); 261 FD_CLR(fd, fds->fdset);
262 DPRINTF_FDSET(fds, "%d", fd); 262 DPRINTF_FDSET(fds, "%d", fd);
263 263
264 svc_fdset_sanitize(fds); 264 svc_fdset_sanitize(fds);
265 return 0; 265 return 0;
266} 266}
267 267
268fd_set * 268fd_set *
269svc_fdset_copy(const fd_set *orig) 269svc_fdset_copy(const fd_set *orig)
270{ 270{
271 int size = svc_fdset_getsize(0); 271 int size = svc_fdset_getsize(0);
272 fd_set *copy = calloc(1, __NFD_BYTES(size)); 272 fd_set *copy = calloc(1, __NFD_BYTES(size));
273 if (copy == NULL) 273 if (copy == NULL)
274 return NULL; 274 return NULL;
275 if (orig) 275 if (orig)
276 memcpy(copy, orig, __NFD_BYTES(size)); 276 memcpy(copy, orig, __NFD_BYTES(size));
277 return copy; 277 return copy;
278} 278}
279 279
280fd_set * 280fd_set *
281svc_fdset_get(void) 281svc_fdset_get(void)
282{ 282{
283 struct svc_fdset *fds = svc_fdset_alloc(0); 283 struct svc_fdset *fds = svc_fdset_alloc(0);
284 284
285 if (fds == NULL) 285 if (fds == NULL)
286 return NULL; 286 return NULL;
287 287
288 DPRINTF_FDSET(fds, "get"); 288 DPRINTF_FDSET(fds, "get");
289 svc_fdset_sanitize(fds); 289 svc_fdset_sanitize(fds);
290 return fds->fdset; 290 return fds->fdset;
291} 291}
292 292
293int * 293int *
294svc_fdset_getmax(void) 294svc_fdset_getmax(void)
295{ 295{
296 struct svc_fdset *fds = svc_fdset_alloc(0); 296 struct svc_fdset *fds = svc_fdset_alloc(0);
297 297
298 if (fds == NULL) 298 if (fds == NULL)
299 return NULL; 299 return NULL;
300 300
301 DPRINTF_FDSET(fds, "getmax"); 301 DPRINTF_FDSET(fds, "getmax");
302 svc_fdset_sanitize(fds); 302 svc_fdset_sanitize(fds);
303 return &fds->fdmax; 303 return &fds->fdmax;
304} 304}
305 305
306int 306int
307svc_fdset_getsize(int fd) 307svc_fdset_getsize(int fd)
308{ 308{
309 struct svc_fdset *fds = svc_fdset_alloc(fd); 309 struct svc_fdset *fds = svc_fdset_alloc(fd);
310 310
311 if (fds == NULL) 311 if (fds == NULL)
312 return -1; 312 return -1;
313 313
314 DPRINTF_FDSET(fds, "getsize"); 314 DPRINTF_FDSET(fds, "getsize");
315 return fds->fdsize; 315 return fds->fdsize;
316} 316}