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