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