]> git.ipfire.org Git - thirdparty/squid.git/blame - src/comm_select_win32.cc
Portability fix: u_int*_t types are deprecated, replaced with uint*_t
[thirdparty/squid.git] / src / comm_select_win32.cc
CommitLineData
663c0a38 1/*
262a0e14 2 * $Id$
663c0a38 3 *
b510f3a1 4 * DEBUG: section 05 Socket Functions
663c0a38 5 *
6 * SQUID Web Proxy Cache http://www.squid-cache.org/
7 * ----------------------------------------------------------
8 *
9 * Squid is the result of efforts by numerous individuals from
10 * the Internet community; see the CONTRIBUTORS file for full
11 * details. Many organizations have provided support for Squid's
12 * development; see the SPONSORS file for full details. Squid is
13 * Copyrighted (C) 2001 by the Regents of the University of
14 * California; see the COPYRIGHT file for full details. Squid
15 * incorporates software developed and/or copyrighted by other
16 * sources; see the CREDITS file for full details.
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
26ac0430 22 *
663c0a38 23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
26ac0430 27 *
663c0a38 28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
31 *
32 */
33
34#include "squid.h"
35#include "comm_select.h"
36#include "CacheManager.h"
37#include "SquidTime.h"
38
32d002cb 39#if USE_SELECT_WIN32
663c0a38 40#include "Store.h"
41#include "fde.h"
42
43static int MAX_POLL_TIME = 1000; /* see also comm_quick_poll_required() */
44
45#ifndef howmany
46#define howmany(x, y) (((x)+((y)-1))/(y))
47#endif
48#ifndef NBBY
49#define NBBY 8
50#endif
51#define FD_MASK_BYTES sizeof(fd_mask)
52#define FD_MASK_BITS (FD_MASK_BYTES*NBBY)
53
54/* STATIC */
55static int examine_select(fd_set *, fd_set *);
56static int fdIsHttp(int fd);
57static int fdIsIcp(int fd);
58static int fdIsDns(int fd);
59static OBJH commIncomingStats;
60static int comm_check_incoming_select_handlers(int nfds, int *fds);
61static void comm_select_dns_incoming(void);
62static void commUpdateReadBits(int fd, PF * handler);
63static void commUpdateWriteBits(int fd, PF * handler);
64
65
66static struct timeval zero_tv;
67static fd_set global_readfds;
68static fd_set global_writefds;
69static int nreadfds;
70static int nwritefds;
71
72/*
73 * Automatic tuning for incoming requests:
74 *
75 * INCOMING sockets are the ICP and HTTP ports. We need to check these
76 * fairly regularly, but how often? When the load increases, we
77 * want to check the incoming sockets more often. If we have a lot
78 * of incoming ICP, then we need to check these sockets more than
79 * if we just have HTTP.
80 *
26ac0430 81 * The variables 'incoming_icp_interval' and 'incoming_http_interval'
663c0a38 82 * determine how many normal I/O events to process before checking
83 * incoming sockets again. Note we store the incoming_interval
84 * multipled by a factor of (2^INCOMING_FACTOR) to have some
85 * pseudo-floating point precision.
86 *
87 * The variable 'icp_io_events' and 'http_io_events' counts how many normal
88 * I/O events have been processed since the last check on the incoming
89 * sockets. When io_events > incoming_interval, its time to check incoming
90 * sockets.
91 *
92 * Every time we check incoming sockets, we count how many new messages
93 * or connections were processed. This is used to adjust the
94 * incoming_interval for the next iteration. The new incoming_interval
95 * is calculated as the current incoming_interval plus what we would
96 * like to see as an average number of events minus the number of
97 * events just processed.
98 *
99 * incoming_interval = incoming_interval + target_average - number_of_events_processed
100 *
101 * There are separate incoming_interval counters for both HTTP and ICP events
26ac0430 102 *
663c0a38 103 * You can see the current values of the incoming_interval's, as well as
104 * a histogram of 'incoming_events' by asking the cache manager
105 * for 'comm_incoming', e.g.:
106 *
107 * % ./client mgr:comm_incoming
108 *
109 * Caveats:
110 *
111 * - We have MAX_INCOMING_INTEGER as a magic upper limit on
112 * incoming_interval for both types of sockets. At the
113 * largest value the cache will effectively be idling.
114 *
115 * - The higher the INCOMING_FACTOR, the slower the algorithm will
116 * respond to load spikes/increases/decreases in demand. A value
117 * between 3 and 8 is recommended.
118 */
119
120#define MAX_INCOMING_INTEGER 256
121#define INCOMING_FACTOR 5
122#define MAX_INCOMING_INTERVAL (MAX_INCOMING_INTEGER << INCOMING_FACTOR)
123static int icp_io_events = 0;
124static int dns_io_events = 0;
125static int http_io_events = 0;
126static int incoming_icp_interval = 16 << INCOMING_FACTOR;
127static int incoming_dns_interval = 16 << INCOMING_FACTOR;
128static int incoming_http_interval = 16 << INCOMING_FACTOR;
129#define commCheckICPIncoming (++icp_io_events > (incoming_icp_interval>> INCOMING_FACTOR))
130#define commCheckDNSIncoming (++dns_io_events > (incoming_dns_interval>> INCOMING_FACTOR))
131#define commCheckHTTPIncoming (++http_io_events > (incoming_http_interval>> INCOMING_FACTOR))
132
133void
134commSetSelect(int fd, unsigned int type, PF * handler, void *client_data,
135 time_t timeout)
136{
137 fde *F = &fd_table[fd];
138 assert(fd >= 0);
139 assert(F->flags.open);
bf8fe701 140 debugs(5, 5, "commSetSelect: FD " << fd << " type " << type);
663c0a38 141
142 if (type & COMM_SELECT_READ) {
143 F->read_handler = handler;
144 F->read_data = client_data;
145 commUpdateReadBits(fd, handler);
146 }
147
148 if (type & COMM_SELECT_WRITE) {
149 F->write_handler = handler;
150 F->write_data = client_data;
151 commUpdateWriteBits(fd, handler);
152 }
153
154 if (timeout)
155 F->timeout = squid_curtime + timeout;
156}
157
3a5a4930 158void
159commResetSelect(int fd)
160{
161}
162
663c0a38 163static int
164fdIsIcp(int fd)
165{
166 if (fd == theInIcpConnection)
167 return 1;
168
169 if (fd == theOutIcpConnection)
170 return 1;
171
172 return 0;
173}
174
175static int
176fdIsDns(int fd)
177{
4d6c8504
AJ
178 if (fd == DnsSocketA)
179 return 1;
180
181 if (fd == DnsSocketB)
663c0a38 182 return 1;
183
184 return 0;
185}
186
187static int
188fdIsHttp(int fd)
189{
190 int j;
191
192 for (j = 0; j < NHttpSockets; j++) {
193 if (fd == HttpSockets[j])
194 return 1;
195 }
196
197 return 0;
198}
199
663c0a38 200static int
201comm_check_incoming_select_handlers(int nfds, int *fds)
202{
203 int i;
204 int fd;
205 int maxfd = 0;
206 PF *hdl = NULL;
207 fd_set read_mask;
208 fd_set write_mask;
209 fd_set errfds;
210 FD_ZERO(&errfds);
211 FD_ZERO(&read_mask);
212 FD_ZERO(&write_mask);
213 incoming_sockets_accepted = 0;
214
215 for (i = 0; i < nfds; i++) {
216 fd = fds[i];
217
218 if (fd_table[fd].read_handler) {
219 FD_SET(fd, &read_mask);
220
221 if (fd > maxfd)
222 maxfd = fd;
223 }
224
225 if (fd_table[fd].write_handler) {
226 FD_SET(fd, &write_mask);
227
228 if (fd > maxfd)
229 maxfd = fd;
230 }
231 }
232
233 if (maxfd++ == 0)
234 return -1;
235
236 getCurrentTime();
237
238 statCounter.syscalls.selects++;
239
240 if (select(maxfd, &read_mask, &write_mask, &errfds, &zero_tv) < 1)
241
242 return incoming_sockets_accepted;
243
244 for (i = 0; i < nfds; i++) {
245 fd = fds[i];
246
90545b82 247 if (__WSAFDIsSet(fd_table[fd].win32.handle, &read_mask)) {
663c0a38 248 if ((hdl = fd_table[fd].read_handler) != NULL) {
249 fd_table[fd].read_handler = NULL;
250 commUpdateReadBits(fd, NULL);
251 hdl(fd, fd_table[fd].read_data);
252 } else {
bf8fe701 253 debugs(5, 1, "comm_select_incoming: FD " << fd << " NULL read handler");
663c0a38 254 }
255 }
256
90545b82 257 if (__WSAFDIsSet(fd_table[fd].win32.handle, &write_mask)) {
663c0a38 258 if ((hdl = fd_table[fd].write_handler) != NULL) {
259 fd_table[fd].write_handler = NULL;
260 commUpdateWriteBits(fd, NULL);
261 hdl(fd, fd_table[fd].write_data);
262 } else {
bf8fe701 263 debugs(5, 1, "comm_select_incoming: FD " << fd << " NULL write handler");
663c0a38 264 }
265 }
266 }
267
268 return incoming_sockets_accepted;
269}
270
271static void
272comm_select_icp_incoming(void)
273{
274 int nfds = 0;
275 int fds[2];
276 int nevents;
277 icp_io_events = 0;
278
279 if (theInIcpConnection >= 0)
280 fds[nfds++] = theInIcpConnection;
281
282 if (theInIcpConnection != theOutIcpConnection)
283 if (theOutIcpConnection >= 0)
284 fds[nfds++] = theOutIcpConnection;
285
286 if (nfds == 0)
287 return;
288
289 nevents = comm_check_incoming_select_handlers(nfds, fds);
290
291 incoming_icp_interval += Config.comm_incoming.icp_average - nevents;
292
293 if (incoming_icp_interval < 0)
294 incoming_icp_interval = 0;
295
296 if (incoming_icp_interval > MAX_INCOMING_INTERVAL)
297 incoming_icp_interval = MAX_INCOMING_INTERVAL;
298
299 if (nevents > INCOMING_ICP_MAX)
300 nevents = INCOMING_ICP_MAX;
301
302 statHistCount(&statCounter.comm_icp_incoming, nevents);
303}
304
305static void
306comm_select_http_incoming(void)
307{
308 int nfds = 0;
309 int fds[MAXHTTPPORTS];
310 int j;
311 int nevents;
312 http_io_events = 0;
313
314 for (j = 0; j < NHttpSockets; j++) {
315 if (HttpSockets[j] < 0)
316 continue;
317
318 fds[nfds++] = HttpSockets[j];
319 }
320
321 nevents = comm_check_incoming_select_handlers(nfds, fds);
322 incoming_http_interval += Config.comm_incoming.http_average - nevents;
323
324 if (incoming_http_interval < 0)
325 incoming_http_interval = 0;
326
327 if (incoming_http_interval > MAX_INCOMING_INTERVAL)
328 incoming_http_interval = MAX_INCOMING_INTERVAL;
329
330 if (nevents > INCOMING_HTTP_MAX)
331 nevents = INCOMING_HTTP_MAX;
332
333 statHistCount(&statCounter.comm_http_incoming, nevents);
334}
335
336#define DEBUG_FDBITS 0
337/* Select on all sockets; call handlers for those that are ready. */
338comm_err_t
339comm_select(int msec)
340{
341 fd_set readfds;
342 fd_set pendingfds;
343 fd_set writefds;
663c0a38 344
345 PF *hdl = NULL;
346 int fd;
347 int maxfd;
348 int num;
349 int pending;
350 int callicp = 0, callhttp = 0;
351 int calldns = 0;
352 int j;
353#if DEBUG_FDBITS
354
355 int i;
356#endif
663c0a38 357 struct timeval poll_time;
358 double timeout = current_dtime + (msec / 1000.0);
359 fde *F;
360
361 int no_bits;
362 fd_set errfds;
363 FD_ZERO(&errfds);
364
365 do {
366 double start;
367 getCurrentTime();
368 start = current_dtime;
663c0a38 369
370 if (commCheckICPIncoming)
371 comm_select_icp_incoming();
372
373 if (commCheckDNSIncoming)
374 comm_select_dns_incoming();
375
376 if (commCheckHTTPIncoming)
377 comm_select_http_incoming();
378
379 callicp = calldns = callhttp = 0;
380
381 maxfd = Biggest_FD + 1;
382
383 xmemcpy(&readfds, &global_readfds, sizeof(global_readfds));
384
385 xmemcpy(&writefds, &global_writefds, sizeof(global_writefds));
386
387 xmemcpy(&errfds, &global_writefds, sizeof(global_writefds));
388
389 /* remove stalled FDs, and deal with pending descriptors */
390 pending = 0;
391
392 FD_ZERO(&pendingfds);
393
394 for (j = 0; j < (int) readfds.fd_count; j++) {
395 register int readfds_handle = readfds.fd_array[j];
396 no_bits = 1;
397
398 for ( fd = Biggest_FD; fd; fd-- ) {
399 if ( fd_table[fd].win32.handle == readfds_handle ) {
400 if (fd_table[fd].flags.open) {
401 no_bits = 0;
402 break;
403 }
404 }
405 }
406
407 if (no_bits)
408 continue;
409
90545b82 410 if (__WSAFDIsSet(fd_table[fd].win32.handle, &readfds) && fd_table[fd].flags.read_pending) {
663c0a38 411 FD_SET(fd, &pendingfds);
412 pending++;
413 }
414 }
415
416#if DEBUG_FDBITS
417 for (i = 0; i < maxfd; i++) {
418 /* Check each open socket for a handler. */
419
420 if (fd_table[i].read_handler) {
90545b82 421 assert(__WSAFDIsSet(fd_table[i].win32.handle, readfds));
663c0a38 422 }
423
424 if (fd_table[i].write_handler) {
90545b82 425 assert(__WSAFDIsSet(fd_table[i].win32.handle, writefds));
663c0a38 426 }
427 }
428
429#endif
430 if (nreadfds + nwritefds == 0) {
431 assert(shutting_down);
432 return COMM_SHUTDOWN;
433 }
434
435 if (msec > MAX_POLL_TIME)
436 msec = MAX_POLL_TIME;
437
663c0a38 438 if (pending)
439 msec = 0;
440
441 for (;;) {
442 poll_time.tv_sec = msec / 1000;
443 poll_time.tv_usec = (msec % 1000) * 1000;
0a515876 444 ++statCounter.syscalls.selects;
663c0a38 445 num = select(maxfd, &readfds, &writefds, &errfds, &poll_time);
0a515876 446 ++statCounter.select_loops;
663c0a38 447
448 if (num >= 0 || pending > 0)
449 break;
450
451 if (ignoreErrno(errno))
452 break;
453
bf8fe701 454 debugs(5, 0, "comm_select: select failure: " << xstrerror());
663c0a38 455
456 examine_select(&readfds, &writefds);
457
458 return COMM_ERROR;
459
460 /* NOTREACHED */
461 }
462
463 if (num < 0 && !pending)
464 continue;
465
466 getCurrentTime();
467
1b826af5 468 debugs(5, num ? 5 : 8, "comm_select: " << num << "+" << pending << " FDs ready");
663c0a38 469
470 statHistCount(&statCounter.select_fds_hist, num);
471
663c0a38 472 if (num == 0 && pending == 0)
473 continue;
474
475 /* Scan return fd masks for ready descriptors */
663c0a38 476 assert(readfds.fd_count <= (unsigned int) Biggest_FD);
663c0a38 477 assert(pendingfds.fd_count <= (unsigned int) Biggest_FD);
478
479 for (j = 0; j < (int) readfds.fd_count; j++) {
480 register int readfds_handle = readfds.fd_array[j];
481 register int pendingfds_handle = pendingfds.fd_array[j];
482 register int osfhandle;
483 no_bits = 1;
484
485 for ( fd = Biggest_FD; fd; fd-- ) {
486 osfhandle = fd_table[fd].win32.handle;
487
488 if (( osfhandle == readfds_handle ) ||
489 ( osfhandle == pendingfds_handle )) {
490 if (fd_table[fd].flags.open) {
491 no_bits = 0;
492 break;
493 }
494 }
495 }
496
497 if (no_bits)
498 continue;
499
500#if DEBUG_FDBITS
501
bf8fe701 502 debugs(5, 9, "FD " << fd << " bit set for reading");
663c0a38 503
90545b82 504 assert(__WSAFDIsSet(fd_table[fd].win32.handle, readfds));
663c0a38 505
506#endif
507
508 if (fdIsIcp(fd)) {
509 callicp = 1;
510 continue;
511 }
512
513 if (fdIsDns(fd)) {
514 calldns = 1;
515 continue;
516 }
517
518 if (fdIsHttp(fd)) {
519 callhttp = 1;
520 continue;
521 }
522
523 F = &fd_table[fd];
bf8fe701 524 debugs(5, 6, "comm_select: FD " << fd << " ready for reading");
663c0a38 525
526 if (NULL == (hdl = F->read_handler))
527 (void) 0;
663c0a38 528 else {
529 F->read_handler = NULL;
1b826af5 530 F->flags.read_pending = 0;
663c0a38 531 commUpdateReadBits(fd, NULL);
532 hdl(fd, F->read_data);
533 statCounter.select_fds++;
534
535 if (commCheckICPIncoming)
536 comm_select_icp_incoming();
537
538 if (commCheckDNSIncoming)
539 comm_select_dns_incoming();
540
541 if (commCheckHTTPIncoming)
542 comm_select_http_incoming();
543 }
544 }
545
546 assert(errfds.fd_count <= (unsigned int) Biggest_FD);
547
548 for (j = 0; j < (int) errfds.fd_count; j++) {
549 register int errfds_handle = errfds.fd_array[j];
550
551 for ( fd = Biggest_FD; fd; fd-- ) {
552 if ( fd_table[fd].win32.handle == errfds_handle )
553 break;
554 }
555
556 if (fd_table[fd].flags.open) {
557 F = &fd_table[fd];
558
559 if ((hdl = F->write_handler)) {
560 F->write_handler = NULL;
561 commUpdateWriteBits(fd, NULL);
562 hdl(fd, F->write_data);
563 statCounter.select_fds++;
564 }
565 }
566 }
567
568 assert(writefds.fd_count <= (unsigned int) Biggest_FD);
569
570 for (j = 0; j < (int) writefds.fd_count; j++) {
571 register int writefds_handle = writefds.fd_array[j];
572 no_bits = 1;
573
574 for ( fd = Biggest_FD; fd; fd-- ) {
575 if ( fd_table[fd].win32.handle == writefds_handle ) {
576 if (fd_table[fd].flags.open) {
577 no_bits = 0;
578 break;
579 }
580 }
581 }
582
583 if (no_bits)
584 continue;
585
586#if DEBUG_FDBITS
587
bf8fe701 588 debugs(5, 9, "FD " << fd << " bit set for writing");
663c0a38 589
90545b82 590 assert(__WSAFDIsSet(fd_table[fd].win32.handle, writefds));
663c0a38 591
592#endif
593
594 if (fdIsIcp(fd)) {
595 callicp = 1;
596 continue;
597 }
598
599 if (fdIsDns(fd)) {
600 calldns = 1;
601 continue;
602 }
603
604 if (fdIsHttp(fd)) {
605 callhttp = 1;
606 continue;
607 }
608
609 F = &fd_table[fd];
bf8fe701 610 debugs(5, 5, "comm_select: FD " << fd << " ready for writing");
663c0a38 611
612 if ((hdl = F->write_handler)) {
613 F->write_handler = NULL;
614 commUpdateWriteBits(fd, NULL);
615 hdl(fd, F->write_data);
616 statCounter.select_fds++;
617
618 if (commCheckICPIncoming)
619 comm_select_icp_incoming();
620
621 if (commCheckDNSIncoming)
622 comm_select_dns_incoming();
623
624 if (commCheckHTTPIncoming)
625 comm_select_http_incoming();
663c0a38 626 }
627 }
628
629 if (callicp)
630 comm_select_icp_incoming();
631
632 if (calldns)
633 comm_select_dns_incoming();
634
635 if (callhttp)
636 comm_select_http_incoming();
637
663c0a38 638 getCurrentTime();
639
640 statCounter.select_time += (current_dtime - start);
641
642 return COMM_OK;
3d0ac046 643 } while (timeout > current_dtime);
4a7a3d56 644 debugs(5, 8, "comm_select: time out: " << squid_curtime);
663c0a38 645
646 return COMM_TIMEOUT;
647}
648
649static void
650comm_select_dns_incoming(void)
651{
652 int nfds = 0;
4d6c8504 653 int fds[3];
663c0a38 654 int nevents;
655 dns_io_events = 0;
656
055421ee 657 if (DnsSocketA < 0 && DnsSocketB < 0)
663c0a38 658 return;
659
055421ee
AJ
660 if (DnsSocketA >= 0)
661 fds[nfds++] = DnsSocketA;
4d6c8504 662
055421ee 663 if (DnsSocketB >= 0)
4d6c8504 664 fds[nfds++] = DnsSocketB;
663c0a38 665
666 nevents = comm_check_incoming_select_handlers(nfds, fds);
667
668 if (nevents < 0)
669 return;
670
671 incoming_dns_interval += Config.comm_incoming.dns_average - nevents;
672
673 if (incoming_dns_interval < Config.comm_incoming.dns_min_poll)
674 incoming_dns_interval = Config.comm_incoming.dns_min_poll;
675
676 if (incoming_dns_interval > MAX_INCOMING_INTERVAL)
677 incoming_dns_interval = MAX_INCOMING_INTERVAL;
678
679 if (nevents > INCOMING_DNS_MAX)
680 nevents = INCOMING_DNS_MAX;
681
682 statHistCount(&statCounter.comm_dns_incoming, nevents);
683}
684
07468826
HN
685static void
686commSelectRegisterWithCacheManager(void)
687{
688 CacheManager::GetInstance()->
26ac0430
AJ
689 registerAction("comm_select_incoming",
690 "comm_incoming() stats",
691 commIncomingStats, 0, 1);
07468826
HN
692}
693
663c0a38 694void
695comm_select_init(void)
696{
697 zero_tv.tv_sec = 0;
698 zero_tv.tv_usec = 0;
699 FD_ZERO(&global_readfds);
700 FD_ZERO(&global_writefds);
701 nreadfds = nwritefds = 0;
da9b2c49
FC
702
703 commSelectRegisterWithCacheManager();
663c0a38 704}
705
663c0a38 706/*
707 * examine_select - debug routine.
708 *
709 * I spend the day chasing this core dump that occurs when both the client
710 * and the server side of a cache fetch simultaneoulsy abort the
711 * connection. While I haven't really studied the code to figure out how
712 * it happens, the snippet below may prevent the cache from exitting:
26ac0430 713 *
663c0a38 714 * Call this from where the select loop fails.
715 */
716static int
717examine_select(fd_set * readfds, fd_set * writefds)
718{
719 int fd = 0;
720 fd_set read_x;
721 fd_set write_x;
722
723 struct timeval tv;
6d527e0a 724 AsyncCall::Pointer ch = NULL;
663c0a38 725 fde *F = NULL;
726
727 struct stat sb;
bf8fe701 728 debugs(5, 0, "examine_select: Examining open file descriptors...");
663c0a38 729
730 for (fd = 0; fd < Squid_MaxFD; fd++) {
731 FD_ZERO(&read_x);
732 FD_ZERO(&write_x);
733 tv.tv_sec = tv.tv_usec = 0;
734
90545b82 735 if (__WSAFDIsSet(fd_table[fd].win32.handle, readfds))
663c0a38 736 FD_SET(fd, &read_x);
90545b82 737 else if (__WSAFDIsSet(fd_table[fd].win32.handle, writefds))
663c0a38 738 FD_SET(fd, &write_x);
739 else
740 continue;
741
742 statCounter.syscalls.selects++;
663c0a38 743 errno = 0;
744
745 if (!fstat(fd, &sb)) {
bf8fe701 746 debugs(5, 5, "FD " << fd << " is valid.");
663c0a38 747 continue;
748 }
749
750 F = &fd_table[fd];
bf8fe701 751 debugs(5, 0, "FD " << fd << ": " << xstrerror());
752 debugs(5, 0, "WARNING: FD " << fd << " has handlers, but it's invalid.");
753 debugs(5, 0, "FD " << fd << " is a " << fdTypeStr[F->type] << " called '" << F->desc << "'");
6d527e0a 754 debugs(5, 0, "tmout:" << F->timeoutHandler << " read:" << F->read_handler << " write:" << F->write_handler);
663c0a38 755
1b826af5 756 for (ch = F->closeHandler; ch != NULL; ch = ch->Next())
6d527e0a 757 debugs(5, 0, " close handler: " << ch);
663c0a38 758
6d527e0a 759 if (F->closeHandler != NULL) {
663c0a38 760 commCallCloseHandlers(fd);
6d527e0a 761 } else if (F->timeoutHandler != NULL) {
bf8fe701 762 debugs(5, 0, "examine_select: Calling Timeout Handler");
26ac0430 763 ScheduleCallHere(F->timeoutHandler);
663c0a38 764 }
765
766 F->closeHandler = NULL;
6d527e0a 767 F->timeoutHandler = NULL;
663c0a38 768 F->read_handler = NULL;
769 F->write_handler = NULL;
770 FD_CLR(fd, readfds);
771 FD_CLR(fd, writefds);
772 }
773
774 return 0;
775}
776
777
778static void
779commIncomingStats(StoreEntry * sentry)
780{
781 StatCounters *f = &statCounter;
782 storeAppendPrintf(sentry, "Current incoming_icp_interval: %d\n",
783 incoming_icp_interval >> INCOMING_FACTOR);
784 storeAppendPrintf(sentry, "Current incoming_dns_interval: %d\n",
785 incoming_dns_interval >> INCOMING_FACTOR);
786 storeAppendPrintf(sentry, "Current incoming_http_interval: %d\n",
787 incoming_http_interval >> INCOMING_FACTOR);
788 storeAppendPrintf(sentry, "\n");
789 storeAppendPrintf(sentry, "Histogram of events per incoming socket type\n");
790 storeAppendPrintf(sentry, "ICP Messages handled per comm_select_icp_incoming() call:\n");
791 statHistDump(&f->comm_icp_incoming, sentry, statHistIntDumper);
792 storeAppendPrintf(sentry, "DNS Messages handled per comm_select_dns_incoming() call:\n");
793 statHistDump(&f->comm_dns_incoming, sentry, statHistIntDumper);
794 storeAppendPrintf(sentry, "HTTP Messages handled per comm_select_http_incoming() call:\n");
795 statHistDump(&f->comm_http_incoming, sentry, statHistIntDumper);
796}
797
798void
799commUpdateReadBits(int fd, PF * handler)
800{
90545b82 801 if (handler && !__WSAFDIsSet(fd_table[fd].win32.handle, &global_readfds)) {
663c0a38 802 FD_SET(fd, &global_readfds);
803 nreadfds++;
90545b82 804 } else if (!handler && __WSAFDIsSet(fd_table[fd].win32.handle, &global_readfds)) {
663c0a38 805 FD_CLR(fd, &global_readfds);
806 nreadfds--;
807 }
808}
809
810void
811commUpdateWriteBits(int fd, PF * handler)
812{
90545b82 813 if (handler && !__WSAFDIsSet(fd_table[fd].win32.handle, &global_writefds)) {
663c0a38 814 FD_SET(fd, &global_writefds);
815 nwritefds++;
90545b82 816 } else if (!handler && __WSAFDIsSet(fd_table[fd].win32.handle, &global_writefds)) {
663c0a38 817 FD_CLR(fd, &global_writefds);
818 nwritefds--;
819 }
820}
821
822/* Called by async-io or diskd to speed up the polling */
823void
824comm_quick_poll_required(void)
825{
826 MAX_POLL_TIME = 10;
827}
828
829#endif /* USE_SELECT_WIN32 */