Sun Nov 8 19:30:53 2015 UTC ()
Add debugging for pollfd


(christos)
diff -r1.11 -r1.12 src/lib/libc/rpc/svc_fdset.c

cvs diff -r1.11 -r1.12 src/lib/libc/rpc/svc_fdset.c (expand / switch to unified diff)

--- src/lib/libc/rpc/svc_fdset.c 2015/11/08 02:46:53 1.11
+++ src/lib/libc/rpc/svc_fdset.c 2015/11/08 19:30:53 1.12
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: svc_fdset.c,v 1.11 2015/11/08 02:46:53 christos Exp $ */ 1/* $NetBSD: svc_fdset.c,v 1.12 2015/11/08 19:30:53 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 reserved. 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.
@@ -20,27 +20,27 @@ @@ -20,27 +20,27 @@
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.11 2015/11/08 02:46:53 christos Exp $"); 33__RCSID("$NetBSD: svc_fdset.c,v 1.12 2015/11/08 19:30:53 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>
@@ -87,33 +87,42 @@ svc_header(const char *func, size_t line @@ -87,33 +87,42 @@ svc_header(const char *func, size_t line
87} 87}
88 88
89static void __printflike(4, 5) 89static void __printflike(4, 5)
90svc_fdset_print(const char *func, size_t line, struct svc_fdset *fds,  90svc_fdset_print(const char *func, size_t line, struct svc_fdset *fds,
91 const char *fmt, ...) 91 const char *fmt, ...)
92{ 92{
93 va_list ap; 93 va_list ap;
94 const char *did = ""; 94 const char *did = "";
95 95
96 va_start(ap, fmt); 96 va_start(ap, fmt);
97 svc_header(func, line, fmt, ap); 97 svc_header(func, line, fmt, ap);
98 va_end(ap); 98 va_end(ap);
99 99
100 fprintf(stderr, "%p[%d] <", fds->fdset, fds->fdmax); 100 fprintf(stderr, "%p[%d] fd_set<", fds->fdset, fds->fdmax);
101 for (int i = 0; i <= fds->fdmax; i++) { 101 for (int i = 0; i <= fds->fdmax; i++) {
102 if (!FD_ISSET(i, fds->fdset)) 102 if (!FD_ISSET(i, fds->fdset))
103 continue; 103 continue;
104 fprintf(stderr, "%s%d", did, i); 104 fprintf(stderr, "%s%d", did, i);
105 did = ", "; 105 did = ", ";
106 } 106 }
 107 did = "";
 108 fprintf(stderr, "> poll<");
 109 for (int i = 0; i < fds->fdused; i++) {
 110 int fd = fds->fdp[i].fd;
 111 if (fd == -1)
 112 continue;
 113 fprintf(stderr, "%s%d", did, fd);
 114 did = ", ";
 115 }
107 fprintf(stderr, ">\n"); 116 fprintf(stderr, ">\n");
108} 117}
109 118
110static void __printflike(3, 4) 119static void __printflike(3, 4)
111svc_print(const char *func, size_t line, const char *fmt, ...) 120svc_print(const char *func, size_t line, const char *fmt, ...)
112{ 121{
113 va_list ap; 122 va_list ap;
114 123
115 va_start(ap, fmt); 124 va_start(ap, fmt);
116 svc_header(func, line, fmt, ap); 125 svc_header(func, line, fmt, ap);
117 va_end(ap); 126 va_end(ap);
118 fprintf(stderr, "\n"); 127 fprintf(stderr, "\n");
119} 128}
@@ -157,85 +166,95 @@ svc_fdset_free(void *v) @@ -157,85 +166,95 @@ svc_fdset_free(void *v)
157static void 166static void
158svc_pollfd_init(struct pollfd *pfd, int nfd) 167svc_pollfd_init(struct pollfd *pfd, int nfd)
159{ 168{
160 for (int i = 0; i < nfd; i++) { 169 for (int i = 0; i < nfd; i++) {
161 pfd[i].fd = -1; 170 pfd[i].fd = -1;
162 pfd[i].events = POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND; 171 pfd[i].events = POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND;
163 pfd[i].revents = 0; 172 pfd[i].revents = 0;
164 } 173 }
165} 174}
166 175
167static struct pollfd * 176static struct pollfd *
168svc_pollfd_alloc(struct svc_fdset *fds) 177svc_pollfd_alloc(struct svc_fdset *fds)
169{ 178{
 179 if (fds->fdp != NULL)
 180 return fds->fdp;
 181
170 fds->fdnum = FD_SETSIZE; 182 fds->fdnum = FD_SETSIZE;
171 fds->fdp = calloc(fds->fdnum, sizeof(*fds->fdp)); 183 fds->fdp = calloc(fds->fdnum, sizeof(*fds->fdp));
172 if (fds->fdp == NULL) 184 if (fds->fdp == NULL)
173 return NULL; 185 return NULL;
174 svc_pollfd_init(fds->fdp, fds->fdnum); 186 svc_pollfd_init(fds->fdp, fds->fdnum);
175 return fds->fdp; 187 return fds->fdp;
176} 188}
177 189
178 190
179static struct svc_fdset * 191static struct svc_fdset *
180svc_pollfd_add(int fd, struct svc_fdset *fds) 192svc_pollfd_add(int fd, struct svc_fdset *fds)
181{ 193{
182 struct pollfd *pfd; 194 struct pollfd *pfd;
183 195
184 if ((pfd = svc_pollfd_alloc(fds)) == NULL) 196 if ((pfd = svc_pollfd_alloc(fds)) == NULL)
185 return NULL; 197 return NULL;
186 198
187 for (int i = 0; i < fds->fdnum; i++) 199 for (int i = 0; i < fds->fdnum; i++)
188 if (pfd[i].fd == -1) { 200 if (pfd[i].fd == -1) {
189 if (i > fds->fdused) 201 if (i >= fds->fdused)
190 fds->fdused = i + 1; 202 fds->fdused = i + 1;
 203 DPRINTF("add fd=%d slot=%d fdused=%d",
 204 fd, i, fds->fdused);
191 pfd[i].fd = fd; 205 pfd[i].fd = fd;
192 return fds; 206 return fds;
193 } 207 }
194 208
195 pfd = realloc(fds->fdp, (fds->fdnum + FD_SETSIZE) * sizeof(*fds->fdp)); 209 pfd = realloc(fds->fdp, (fds->fdnum + FD_SETSIZE) * sizeof(*fds->fdp));
196 if (pfd == NULL) 210 if (pfd == NULL)
197 return NULL; 211 return NULL;
198 212
199 svc_pollfd_init(pfd + fds->fdnum, FD_SETSIZE); 213 svc_pollfd_init(pfd + fds->fdnum, FD_SETSIZE);
200 pfd[fds->fdnum].fd = fd; 214 pfd[fds->fdnum].fd = fd;
201 fds->fdused = fds->fdnum + 1; 215 fds->fdused = fds->fdnum + 1;
 216 DPRINTF("add fd=%d slot=%d fdused=%d", fd, fds->fdnum, fds->fdused);
202 fds->fdnum += FD_SETSIZE; 217 fds->fdnum += FD_SETSIZE;
203 return fds; 218 return fds;
204} 219}
205 220
206static struct svc_fdset * 221static struct svc_fdset *
207svc_pollfd_del(int fd, struct svc_fdset *fds) 222svc_pollfd_del(int fd, struct svc_fdset *fds)
208{ 223{
209 struct pollfd *pfd; 224 struct pollfd *pfd;
210 225
211 if ((pfd = svc_pollfd_alloc(fds)) == NULL) 226 if ((pfd = svc_pollfd_alloc(fds)) == NULL)
212 return NULL; 227 return NULL;
213 228
214 for (int i = 0; i < fds->fdnum; i++) { 229 for (int i = 0; i < fds->fdnum; i++) {
215 if (pfd[i].fd != fd) 230 if (pfd[i].fd != fd)
216 continue; 231 continue;
217 232
218 pfd[i].fd = -1; 233 pfd[i].fd = -1;
 234 DPRINTF("del fd=%d slot=%d", fd, fds->fdused);
219 if (i != fds->fdused - 1) 235 if (i != fds->fdused - 1)
220 return fds; 236 return fds;
221 237
222 do 238 do
223 if (pfd[i].fd != -1)  239 if (pfd[i].fd != -1)
224 break; 240 break;
225 while (--i >= 0); 241 while (--i >= 0);
 242
226 fds->fdused = i + 1; 243 fds->fdused = i + 1;
 244 DPRINTF("del fd=%d fdused=%d", fd, fds->fdused);
227 return fds; 245 return fds;
228 } 246 }
 247 DPRINTF("del fd=%d not found", fd);
229 return NULL; 248 return NULL;
230} 249}
231 250
232static struct svc_fdset * 251static struct svc_fdset *
233svc_fdset_resize(int fd, struct svc_fdset *fds) 252svc_fdset_resize(int fd, struct svc_fdset *fds)
234{ 253{
235 if (fds->fdset && fd < fds->fdsize) { 254 if (fds->fdset && fd < fds->fdsize) {
236 DPRINTF_FDSET(fds, "keeping %d < %d", fd, fds->fdsize); 255 DPRINTF_FDSET(fds, "keeping %d < %d", fd, fds->fdsize);
237 return fds; 256 return fds;
238 } 257 }
239 258
240 fd += FD_SETSIZE;  259 fd += FD_SETSIZE;
241 260
@@ -314,58 +333,61 @@ svc_fdset_zero(void) @@ -314,58 +333,61 @@ svc_fdset_zero(void)
314 333
315int 334int
316svc_fdset_set(int fd) 335svc_fdset_set(int fd)
317{ 336{
318 struct svc_fdset *fds = svc_fdset_alloc(fd); 337 struct svc_fdset *fds = svc_fdset_alloc(fd);
319 338
320 if (fds == NULL) 339 if (fds == NULL)
321 return -1; 340 return -1;
322 341
323 FD_SET(fd, fds->fdset); 342 FD_SET(fd, fds->fdset);
324 if (fd > fds->fdmax) 343 if (fd > fds->fdmax)
325 fds->fdmax = fd; 344 fds->fdmax = fd;
326 345
 346 int rv = svc_pollfd_add(fd, fds) ? 0 : -1;
327 DPRINTF_FDSET(fds, "%d", fd); 347 DPRINTF_FDSET(fds, "%d", fd);
328 348
329 svc_fdset_sanitize(fds); 349 svc_fdset_sanitize(fds);
330 return svc_pollfd_add(fd, fds) ? 0 : -1; 350 return rv;
331} 351}
332 352
333int 353int
334svc_fdset_isset(int fd) 354svc_fdset_isset(int fd)
335{ 355{
336 struct svc_fdset *fds = svc_fdset_alloc(fd); 356 struct svc_fdset *fds = svc_fdset_alloc(fd);
337 357
338 if (fds == NULL) 358 if (fds == NULL)
339 return -1; 359 return -1;
340 360
341 DPRINTF_FDSET(fds, "%d", fd); 361 DPRINTF_FDSET(fds, "%d", fd);
342 362
343 return FD_ISSET(fd, fds->fdset) != 0; 363 return FD_ISSET(fd, fds->fdset) != 0;
344} 364}
345 365
346int 366int
347svc_fdset_clr(int fd) 367svc_fdset_clr(int fd)
348{ 368{
349 struct svc_fdset *fds = svc_fdset_alloc(fd); 369 struct svc_fdset *fds = svc_fdset_alloc(fd);
350 370
351 if (fds == NULL) 371 if (fds == NULL)
352 return -1; 372 return -1;
353 373
354 FD_CLR(fd, fds->fdset); 374 FD_CLR(fd, fds->fdset);
 375
 376 int rv = svc_pollfd_del(fd, fds) ? 0 : -1;
355 DPRINTF_FDSET(fds, "%d", fd); 377 DPRINTF_FDSET(fds, "%d", fd);
356 378
357 svc_fdset_sanitize(fds); 379 svc_fdset_sanitize(fds);
358 return svc_pollfd_del(fd, fds) ? 0 : -1; 380 return rv;
359} 381}
360 382
361fd_set * 383fd_set *
362svc_fdset_copy(const fd_set *orig) 384svc_fdset_copy(const fd_set *orig)
363{ 385{
364 int size = svc_fdset_getsize(0); 386 int size = svc_fdset_getsize(0);
365 fd_set *copy = calloc(1, __NFD_BYTES(size)); 387 fd_set *copy = calloc(1, __NFD_BYTES(size));
366 if (copy == NULL) 388 if (copy == NULL)
367 return NULL; 389 return NULL;
368 if (orig) 390 if (orig)
369 memcpy(copy, orig, __NFD_BYTES(size)); 391 memcpy(copy, orig, __NFD_BYTES(size));
370 return copy; 392 return copy;
371} 393}