3 Copyright 1996, 1997, 1998, 1999, 2000 Red Hat, Inc.
5 Written by Christopher Faylor of Cygnus Solutions
8 This file is part of Cygwin.
10 This software is a copyrighted work licensed under the terms of the
11 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
15 * The following line means that the BSD socket
16 * definitions for fd_set, FD_ISSET etc. are used in this
20 #define __INSIDE_CYGWIN_NET__
25 #include <sys/socket.h>
41 #include "perthread.h"
44 * All these defines below should be in sys/types.h
45 * but because of the includes above, they may not have
46 * been included. We create special UNIX_xxxx versions here.
50 #define NBBY 8 /* number of bits in a byte */
54 * Select uses bit masks of file descriptors in longs.
55 * These macros manipulate such bit fields (the filesystem macros use chars).
56 * FD_SETSIZE may be defined by the user, but the default here
57 * should be >= NOFILE (param.h).
61 #define UNIX_NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */
63 #define unix_howmany(x,y) (((x)+((y)-1))/(y))
66 #define unix_fd_set fd_set
68 #define NULL_fd_set ((fd_set *)NULL)
69 #define sizeof_fd_set(n) \
70 ((unsigned) (NULL_fd_set->fds_bits + unix_howmany((n), UNIX_NFDBITS)))
71 #define UNIX_FD_SET(n, p) \
72 ((p)->fds_bits[(n)/UNIX_NFDBITS] |= (1L << ((n) % UNIX_NFDBITS)))
73 #define UNIX_FD_CLR(n, p) \
74 ((p)->fds_bits[(n)/UNIX_NFDBITS] &= ~(1L << ((n) % UNIX_NFDBITS)))
75 #define UNIX_FD_ISSET(n, p) \
76 ((p)->fds_bits[(n)/UNIX_NFDBITS] & (1L << ((n) % UNIX_NFDBITS)))
77 #define UNIX_FD_ZERO(p, n) \
78 bzero ((caddr_t)(p), sizeof_fd_set ((n)))
80 #define allocfd_set(n) ((fd_set *) memset (alloca (sizeof_fd_set (n)), 0, sizeof_fd_set (n)))
81 #define copyfd_set(to, from, n) memcpy (to, from, sizeof_fd_set (n));
83 /* Make a fhandler_foo::ready_for_ready method.
84 Assumption: The "ready_for_read" methods are called with one level of
86 #define MAKEready(what) \
88 fhandler_##what::ready_for_read (int fd, DWORD howlong, int ignra) \
90 select_record me (this); \
92 (void) select_read (&me); \
93 while (!peek_##what (&me, ignra) && howlong == INFINITE) \
94 if (fd >= 0 && fdtab.not_open (fd)) \
96 else if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0) \
98 return me.read_ready; \
101 #define set_handle_or_return_if_not_open(h, s) \
102 h = (s)->fh->get_handle (); \
103 if (fdtab.not_open ((s)->fd)) \
105 (s)->saw_error = TRUE; \
110 /* The main select code.
114 cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
118 fd_set *dummy_readfds = allocfd_set (maxfds);
119 fd_set *dummy_writefds = allocfd_set (maxfds);
120 fd_set *dummy_exceptfds = allocfd_set (maxfds);
121 sigframe thisframe (mainthread, 0);
131 select_printf ("%d, %p, %p, %p, %p", maxfds, readfds, writefds, exceptfds, to);
134 readfds = dummy_readfds;
136 writefds = dummy_writefds;
138 exceptfds = dummy_exceptfds;
140 for (int i = 0; i < maxfds; i++)
141 if (!sel.test_and_set (i, readfds, writefds, exceptfds))
143 select_printf ("aborting due to test_and_set error");
144 return -1; /* Invalid fd, maybe? */
147 /* Convert to milliseconds or INFINITE if to == NULL */
148 DWORD ms = to ? (to->tv_sec * 1000) + (to->tv_usec / 1000) : INFINITE;
149 if (ms == 0 && to->tv_usec)
150 ms = 1; /* At least 1 ms granularity */
153 select_printf ("to->tv_sec %d, to->tv_usec %d, ms %d", to->tv_sec, to->tv_usec, ms);
155 select_printf ("to NULL, ms %x", ms);
157 select_printf ("sel.always_ready %d", sel.always_ready);
159 /* Degenerate case. No fds to wait for. Just wait. */
160 if (sel.start.next == NULL)
162 if (WaitForSingleObject (signal_arrived, ms) == WAIT_OBJECT_0)
164 select_printf ("signal received");
165 set_sig_errno (EINTR);
171 /* Allocate some fd_set structures using the number of fds as a guide. */
172 fd_set *r = allocfd_set (maxfds);
173 fd_set *w = allocfd_set (maxfds);
174 fd_set *e = allocfd_set (maxfds);
176 if (sel.always_ready || ms == 0)
177 /* Don't bother waiting. */;
178 else if (sel.wait (r, w, e, ms))
179 return -1; /* some kind of error */
181 copyfd_set (readfds, r, maxfds);
182 copyfd_set (writefds, w, maxfds);
183 copyfd_set (exceptfds, e, maxfds);
184 return sel.poll (readfds, writefds, exceptfds);
188 select_stuff::~select_stuff ()
190 select_record *s = &start;
192 select_printf ("calling cleanup routines");
193 while ((s = s->next))
195 s->cleanup (s, this);
197 select_record *snext = start.next;
199 select_printf ("deleting select records");
207 /* Add a record to the select chain */
209 select_stuff::test_and_set (int i, fd_set *readfds, fd_set *writefds,
212 select_record *s = NULL;
213 if (UNIX_FD_ISSET (i, readfds) && (s = fdtab.select_read (i, s)) == NULL)
214 return 0; /* error */
215 if (UNIX_FD_ISSET (i, writefds) && (s = fdtab.select_write (i, s)) == NULL)
216 return 0; /* error */
217 if (UNIX_FD_ISSET (i, exceptfds) && (s = fdtab.select_except (i, s)) == NULL)
218 return 0; /* error */
220 return 1; /* nothing to do */
222 if (s->read_ready || s->write_ready || s->except_ready)
225 if (s->windows_handle || s->windows_handle || s->windows_handle)
228 s->next = start.next;
233 /* Poll every fd in the select chain. Set appropriate fd in mask. */
235 select_stuff::poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
238 select_record *s = &start;
239 while ((s = s->next))
240 n += s->poll (s, readfds, writefds, exceptfds);
241 select_printf ("returning %d", n);
245 /* The heart of select. Waits for an fd to do something interesting. */
247 select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
251 HANDLE w4[MAXIMUM_WAIT_OBJECTS];
252 select_record *s = &start;
255 w4[m++] = signal_arrived; /* Always wait for the arrival of a signal. */
256 /* Loop through the select chain, starting up anything appropriate and
257 counting the number of active fds. */
258 while ((s = s->next))
260 if (m > MAXIMUM_WAIT_OBJECTS)
265 if (!s->startup (s, this))
272 for (int i = 1; i < m; i++)
280 DWORD start_time = GetTickCount (); /* Record the current time for later use. */
282 debug_printf ("m %d, ms %u", m, ms);
286 wait_ret = WaitForMultipleObjects (m, w4, FALSE, ms);
288 wait_ret = MsgWaitForMultipleObjects (m, w4, FALSE, ms, QS_ALLINPUT);
293 select_printf ("signal received");
294 set_sig_errno (EINTR);
297 select_printf ("WaitForMultipleObjects failed");
301 select_printf ("timed out");
305 select_printf ("woke up. wait_ret %d. verifying", wait_ret);
308 while ((s = s->next))
310 return -1; /* Somebody detected an error */
311 else if ((((wait_ret >= m && s->windows_handle) || s->h == w4[wait_ret])) &&
312 s->verify (s, readfds, writefds, exceptfds))
315 select_printf ("gotone %d", gotone);
321 select_printf ("looping");
324 select_printf ("recalculating ms");
326 DWORD now = GetTickCount ();
327 if (now > (start_time + ms))
329 select_printf ("timed out after verification");
332 ms -= (now - start_time);
334 select_printf ("ms now %u", ms);
338 select_printf ("returning 0");
343 set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
347 select_printf ("me %p, testing fd %d (%s)", me, me->fd, me->fh->get_name ());
348 if (me->read_selected && me->read_ready)
350 UNIX_FD_SET (me->fd, readfds);
353 if (me->write_selected && me->write_ready)
355 UNIX_FD_SET (me->fd, writefds);
358 if (me->except_ready && me->except_ready)
360 UNIX_FD_SET (me->fd, exceptfds);
363 select_printf ("ready %d", ready);
368 verify_true (select_record *, fd_set *, fd_set *, fd_set *)
374 verify_ok (select_record *me, fd_set *readfds, fd_set *writefds,
377 return set_bits (me, readfds, writefds, exceptfds);
381 no_startup (select_record *, select_stuff *)
387 no_verify (select_record *, fd_set *, fd_set *, fd_set *)
393 peek_pipe (select_record *s, int ignra)
397 fhandler_base *fh = s->fh;
400 set_handle_or_return_if_not_open (h, s);
402 /* Don't perform complicated tests if we don't need to. */
403 if (!s->read_selected && !s->except_selected)
406 if (s->read_selected)
410 select_printf ("already ready");
414 if (fh->bg_check (SIGTTIN) <= 0)
416 gotone = s->read_ready = 1;
420 if (!ignra && fh->get_device () != FH_PTYM && fh->get_device () != FH_TTYM &&
421 fh->get_readahead_valid ())
423 select_printf ("readahead");
424 gotone = s->read_ready = 1;
429 if (fh->get_device() != FH_PIPEW &&
430 !PeekNamedPipe (h, NULL, 0, NULL, (DWORD *) &n, NULL))
432 select_printf ("%s, PeekNamedPipe failed, %E", fh->get_name ());
438 select_printf ("%s, n %d", fh->get_name (), n);
439 if (s->except_selected)
440 gotone += s->except_ready = TRUE;
441 if (s->read_selected)
442 gotone += s->read_ready = TRUE;
444 if (n > 0 && s->read_selected)
446 select_printf ("%s, ready for read", fh->get_name ());
447 gotone += s->read_ready = TRUE;
449 if (!gotone && s->fh->hit_eof ())
451 select_printf ("%s, saw EOF", fh->get_name ());
452 if (s->except_selected)
453 gotone = s->except_ready = TRUE;
454 if (s->read_selected)
455 gotone += s->read_ready = TRUE;
456 select_printf ("saw eof on '%s'", fh->get_name ());
460 return gotone || s->write_ready;
464 poll_pipe (select_record *me, fd_set *readfds, fd_set *writefds,
467 return peek_pipe (me, 0) ?
468 set_bits (me, readfds, writefds, exceptfds) :
474 static int start_thread_pipe (select_record *me, select_stuff *stuff);
479 BOOL stop_thread_pipe;
480 select_record *start;
484 thread_pipe (void *arg)
486 pipeinf *pi = (pipeinf *)arg;
491 select_record *s = pi->start;
492 while ((s = s->next))
493 if (s->startup == start_thread_pipe)
495 if (peek_pipe (s, 0))
497 if (pi->stop_thread_pipe)
499 select_printf ("stopping");
504 if (pi->stop_thread_pipe)
506 select_printf ("stopping from outer loop");
518 start_thread_pipe (select_record *me, select_stuff *stuff)
520 if (stuff->device_specific[FHDEVN(FH_PIPE)])
522 me->h = ((pipeinf *) stuff->device_specific[FHDEVN(FH_PIPE)])->thread;
525 pipeinf *pi = new pipeinf;
526 pi->start = &stuff->start;
527 pi->stop_thread_pipe = FALSE;
528 pi->thread = me->h = makethread (thread_pipe, (LPVOID)pi, 0, "select_pipe");
531 stuff->device_specific[FHDEVN(FH_PIPE)] = (void *)pi;
536 pipe_cleanup (select_record *, select_stuff *stuff)
538 pipeinf *pi = (pipeinf *)stuff->device_specific[FHDEVN(FH_PIPE)];
539 if (pi && pi->thread)
541 pi->stop_thread_pipe = TRUE;
542 WaitForSingleObject (pi->thread, INFINITE);
543 CloseHandle (pi->thread);
545 stuff->device_specific[FHDEVN(FH_PIPE)] = NULL;
550 fhandler_pipe::select_read (select_record *s)
553 s = new select_record;
554 s->startup = start_thread_pipe;
556 s->verify = verify_ok;
557 s->read_selected = TRUE;
558 s->cleanup = pipe_cleanup;
563 fhandler_pipe::select_write (select_record *s)
567 s = new select_record;
568 s->startup = no_startup;
570 s->verify = no_verify;
572 s->write_selected = TRUE;
573 s->write_ready = TRUE;
578 fhandler_pipe::select_except (select_record *s)
581 s = new select_record;
582 s->startup = start_thread_pipe;
584 s->verify = verify_ok;
585 s->cleanup = pipe_cleanup;
586 s->except_selected = TRUE;
591 peek_console (select_record *me, int ignra)
593 extern const char * get_nonascii_key (INPUT_RECORD& input_rec, char *);
594 fhandler_console *fh = (fhandler_console *)me->fh;
596 if (!me->read_selected)
597 return me->write_ready;
599 if (!ignra && fh->get_readahead_valid ())
601 select_printf ("readahead");
602 return me->read_ready = 1;
607 select_printf ("already ready");
615 set_handle_or_return_if_not_open (h, me);
618 if (fh->bg_check (SIGTTIN) <= 0)
619 return me->read_ready = 1;
620 else if (!PeekConsoleInput (h, &irec, 1, &events_read) || !events_read)
624 if (irec.EventType == WINDOW_BUFFER_SIZE_EVENT)
625 kill_pgrp (fh->tc->getpgid (), SIGWINCH);
626 else if (irec.EventType == KEY_EVENT && irec.Event.KeyEvent.bKeyDown == TRUE &&
627 (irec.Event.KeyEvent.uChar.AsciiChar || get_nonascii_key (irec, tmpbuf)))
628 return me->read_ready = 1;
630 /* Read and discard the event */
631 ReadConsoleInput (h, &irec, 1, &events_read);
634 return me->write_ready;
638 poll_console (select_record *me, fd_set *readfds, fd_set *writefds,
641 return peek_console (me, 0) ?
642 set_bits (me, readfds, writefds, exceptfds) :
649 fhandler_console::select_read (select_record *s)
653 s = new select_record;
654 s->startup = no_startup;
655 s->poll = poll_console;
656 s->verify = poll_console;
660 s->h = get_handle ();
661 s->read_selected = TRUE;
666 fhandler_console::select_write (select_record *s)
670 s = new select_record;
671 s->startup = no_startup;
672 s->poll = poll_console;
673 s->verify = no_verify;
677 s->write_selected = TRUE;
678 s->write_ready = TRUE;
683 fhandler_console::select_except (select_record *s)
687 s = new select_record;
688 s->startup = no_startup;
689 s->poll = poll_console;
690 s->verify = no_verify;
694 s->except_selected = TRUE;
699 fhandler_tty_common::ready_for_read (int fd, DWORD howlong, int ignra)
702 if (myself->pgid && get_ttyp ()->getpgid () != myself->pgid &&
703 myself->ctty == ttynum) // background process?
704 return 1; // Yes. Let read return an error
706 return ((fhandler_pipe*)this)->fhandler_pipe::ready_for_read (fd, howlong, ignra);
710 fhandler_tty_common::select_read (select_record *s)
712 return ((fhandler_pipe*)this)->fhandler_pipe::select_read (s);
716 fhandler_tty_common::select_write (select_record *s)
718 return ((fhandler_pipe *)this)->fhandler_pipe::select_write (s);
722 fhandler_tty_common::select_except (select_record *s)
724 return ((fhandler_pipe *)this)->fhandler_pipe::select_except (s);
728 fhandler_dev_null::select_read (select_record *s)
732 s = new select_record;
733 s->startup = no_startup;
735 s->verify = no_verify;
737 s->h = get_handle ();
738 s->read_selected = TRUE;
743 fhandler_dev_null::select_write (select_record *s)
747 s = new select_record;
748 s->startup = no_startup;
750 s->verify = no_verify;
752 s->h = get_handle ();
753 s->write_selected = TRUE;
758 fhandler_dev_null::select_except (select_record *s)
762 s = new select_record;
763 s->startup = no_startup;
765 s->verify = no_verify;
767 s->h = get_handle ();
768 s->except_selected = TRUE;
769 s->except_ready = TRUE;
773 static int start_thread_serial (select_record *me, select_stuff *stuff);
778 BOOL stop_thread_serial;
779 select_record *start;
783 peek_serial (select_record *s, int)
788 fhandler_serial *fh = (fhandler_serial *)s->fh;
790 if (fh->get_readahead_valid () || fh->overlapped_armed < 0)
791 return s->read_ready = 1;
793 select_printf ("fh->overlapped_armed %d", fh->overlapped_armed);
796 set_handle_or_return_if_not_open (h, s);
799 if (s->read_selected && s->read_ready || (s->write_selected && s->write_ready))
801 select_printf ("already ready");
806 (void) SetCommMask (h, EV_RXCHAR);
808 if (!fh->overlapped_armed)
813 ResetEvent (fh->io_status.hEvent);
815 if (!ClearCommError (h, &ev, &st))
817 debug_printf ("ClearCommError");
821 return s->read_ready = 1;
822 else if (WaitCommEvent (h, &ev, &fh->io_status))
823 return s->read_ready = 1;
824 else if (GetLastError () == ERROR_IO_PENDING)
825 fh->overlapped_armed = 1;
828 debug_printf ("WaitCommEvent");
836 w4[0] = fh->io_status.hEvent;
837 w4[1] = signal_arrived;
840 switch (WaitForMultipleObjects (2, w4, FALSE, to))
843 if (!ClearCommError (h, &ev, &st))
845 debug_printf ("ClearCommError");
848 else if (!st.cbInQue)
852 return s->read_ready = 1;
853 select_printf ("got something");
855 PurgeComm (h, PURGE_TXABORT | PURGE_RXABORT);
857 case WAIT_OBJECT_0 + 1:
858 PurgeComm (h, PURGE_TXABORT | PURGE_RXABORT);
859 select_printf ("interrupt");
860 set_sig_errno (EINTR);
864 PurgeComm (h, PURGE_TXABORT | PURGE_RXABORT);
867 PurgeComm (h, PURGE_TXABORT | PURGE_RXABORT);
868 debug_printf ("WaitForMultipleObjects");
876 if (GetLastError () == ERROR_OPERATION_ABORTED)
878 select_printf ("operation aborted");
884 select_printf ("error %E");
889 thread_serial (void *arg)
891 serialinf *si = (serialinf *)arg;
896 select_record *s = si->start;
897 while ((s = s->next))
898 if (s->startup == start_thread_serial)
900 if (peek_serial (s, 0))
903 if (si->stop_thread_serial)
905 select_printf ("stopping");
912 select_printf ("exiting");
917 start_thread_serial (select_record *me, select_stuff *stuff)
919 if (stuff->device_specific[FHDEVN(FH_SERIAL)])
921 me->h = ((pipeinf *) stuff->device_specific[FHDEVN(FH_SERIAL)])->thread;
924 serialinf *si = new serialinf;
925 si->start = &stuff->start;
926 si->stop_thread_serial = FALSE;
927 si->thread = me->h = makethread (thread_serial, (LPVOID)si, 0, "select_serial");
930 stuff->device_specific[FHDEVN(FH_SERIAL)] = (void *)si;
935 serial_cleanup (select_record *, select_stuff *stuff)
937 serialinf *si = (serialinf *)stuff->device_specific[FHDEVN(FH_SERIAL)];
938 if (si && si->thread)
940 si->stop_thread_serial = TRUE;
941 WaitForSingleObject (si->thread, INFINITE);
942 CloseHandle (si->thread);
944 stuff->device_specific[FHDEVN(FH_SERIAL)] = NULL;
949 poll_serial (select_record *me, fd_set *readfds, fd_set *writefds,
953 return peek_serial (me, 0) ?
954 set_bits (me, readfds, writefds, exceptfds) :
961 fhandler_serial::select_read (select_record *s)
965 s = new select_record;
966 s->startup = start_thread_serial;
967 s->poll = poll_serial;
968 s->verify = verify_ok;
969 s->cleanup = serial_cleanup;
971 s->read_selected = TRUE;
976 fhandler_serial::select_write (select_record *s)
980 s = new select_record;
981 s->startup = no_startup;
983 s->verify = verify_ok;
985 s->h = get_handle ();
986 s->write_selected = TRUE;
987 s->write_ready = TRUE;
992 fhandler_serial::select_except (select_record *s)
996 s = new select_record;
997 s->startup = no_startup;
999 s->verify = verify_ok;
1002 s->except_selected = FALSE; // Can't do this
1007 fhandler_base::ready_for_read (int, DWORD, int)
1013 fhandler_base::select_read (select_record *s)
1017 s = new select_record;
1018 s->startup = no_startup;
1020 s->verify = verify_ok;
1022 s->h = get_handle ();
1023 s->read_selected = TRUE;
1024 s->read_ready = TRUE;
1029 fhandler_base::select_write (select_record *s)
1033 s = new select_record;
1034 s->startup = no_startup;
1036 s->verify = verify_ok;
1038 s->h = get_handle ();
1039 s->write_selected = TRUE;
1040 s->write_ready = TRUE;
1045 fhandler_base::select_except (select_record *s)
1049 s = new select_record;
1050 s->startup = no_startup;
1052 s->verify = verify_ok;
1055 s->write_selected = TRUE;
1062 winsock_fd_set readfds, writefds, exceptfds;
1064 struct sockaddr_in sin;
1065 select_record *start;
1069 peek_socket (select_record *me, int)
1071 winsock_fd_set ws_readfds, ws_writefds, ws_exceptfds;
1072 struct timeval tv = {0, 0};
1073 WINSOCK_FD_ZERO (&ws_readfds);
1074 WINSOCK_FD_ZERO (&ws_writefds);
1075 WINSOCK_FD_ZERO (&ws_exceptfds);
1079 set_handle_or_return_if_not_open (h, me);
1080 select_printf ("considering handle %p", h);
1082 if (me->read_selected)
1084 select_printf ("adding read fd_set %s, fd %d", me->fh->get_name (),
1086 WINSOCK_FD_SET (h, &ws_readfds);
1088 if (me->write_selected)
1090 select_printf ("adding write fd_set %s, fd %d", me->fh->get_name (),
1092 WINSOCK_FD_SET (h, &ws_writefds);
1094 if (me->except_selected)
1096 select_printf ("adding except fd_set %s, fd %d", me->fh->get_name (),
1098 WINSOCK_FD_SET (h, &ws_exceptfds);
1100 int r = WINSOCK_SELECT (0, &ws_readfds, &ws_writefds, &ws_exceptfds, &tv);
1101 select_printf ("WINSOCK_SELECT returned %d", r);
1104 select_printf ("error %d", WSAGetLastError ());
1108 if (WINSOCK_FD_ISSET (h, &ws_readfds) || (me->read_selected && me->read_ready))
1109 gotone = me->read_ready = TRUE;
1110 if (WINSOCK_FD_ISSET (h, &ws_writefds) || (me->write_selected && me->write_ready))
1111 gotone = me->write_ready = TRUE;
1112 if (WINSOCK_FD_ISSET (h, &ws_exceptfds) || (me->except_selected && me->except_ready))
1113 gotone = me->except_ready = TRUE;
1118 poll_socket (select_record *me, fd_set *readfds, fd_set *writefds,
1121 return peek_socket (me, 0) ?
1122 set_bits (me, readfds, writefds, exceptfds) :
1128 static int start_thread_socket (select_record *, select_stuff *);
1131 thread_socket (void *arg)
1133 socketinf *si = (socketinf *)arg;
1135 select_printf ("stuff_start %p", &si->start);
1136 int r = WINSOCK_SELECT (0, &si->readfds, &si->writefds, &si->exceptfds, NULL);
1137 select_printf ("Win32 select returned %d", r);
1139 select_printf ("error %d", WSAGetLastError ());
1140 select_record *s = si->start;
1141 while ((s = s->next))
1142 if (s->startup == start_thread_socket)
1144 HANDLE h = s->fh->get_handle ();
1145 select_printf ("s %p, testing fd %d (%s)", s, s->fd, s->fh->get_name ());
1146 if (WINSOCK_FD_ISSET (h, &si->readfds))
1148 select_printf ("read_ready");
1149 s->read_ready = TRUE;
1151 if (WINSOCK_FD_ISSET (h, &si->writefds))
1153 select_printf ("write_ready");
1154 s->write_ready = TRUE;
1156 if (WINSOCK_FD_ISSET (h, &si->exceptfds))
1158 select_printf ("except_ready");
1159 s->except_ready = TRUE;
1163 if (WINSOCK_FD_ISSET (si->exitsock, &si->readfds))
1164 select_printf ("saw exitsock read");
1169 extern "C" unsigned long htonl (unsigned long);
1172 start_thread_socket (select_record *me, select_stuff *stuff)
1176 if ((si = (socketinf *)stuff->device_specific[FHDEVN(FH_SOCKET)]))
1183 WINSOCK_FD_ZERO (&si->readfds);
1184 WINSOCK_FD_ZERO (&si->writefds);
1185 WINSOCK_FD_ZERO (&si->exceptfds);
1186 select_record *s = &stuff->start;
1187 while ((s = s->next))
1188 if (s->startup == start_thread_socket)
1190 HANDLE h = s->fh->get_handle ();
1191 select_printf ("Handle %p", h);
1192 if (s->read_selected)
1194 WINSOCK_FD_SET (h, &si->readfds);
1195 select_printf ("Added to readfds");
1197 if (s->write_selected)
1199 WINSOCK_FD_SET (h, &si->writefds);
1200 select_printf ("Added to writefds");
1202 if (s->except_selected)
1204 WINSOCK_FD_SET (h, &si->exceptfds);
1205 select_printf ("Added to exceptfds");
1209 if ((si->exitsock = socket (PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
1211 set_winsock_errno ();
1212 select_printf ("cannot create socket, %E");
1215 /* Allow rapid reuse of the port. */
1217 (void) setsockopt (si->exitsock, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp));
1219 int sin_len = sizeof(si->sin);
1220 memset (&si->sin, 0, sizeof (si->sin));
1221 si->sin.sin_family = AF_INET;
1222 si->sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1223 if (bind (si->exitsock, (struct sockaddr *) &si->sin, sizeof (si->sin)) < 0)
1225 select_printf ("cannot bind socket, %E");
1229 if (getsockname (si->exitsock, (struct sockaddr *) &si->sin, &sin_len) < 0)
1231 select_printf ("getsockname error");
1235 if (listen (si->exitsock, 1))
1237 select_printf ("listen failed, %E");
1241 select_printf ("exitsock %p", si->exitsock);
1242 WINSOCK_FD_SET ((HANDLE) si->exitsock, &si->readfds);
1243 WINSOCK_FD_SET ((HANDLE) si->exitsock, &si->exceptfds);
1244 stuff->device_specific[FHDEVN(FH_SOCKET)] = (void *) si;
1245 si->start = &stuff->start;
1246 select_printf ("stuff_start %p", &stuff->start);
1247 si->thread = me->h = makethread (thread_socket, (LPVOID)si, 0,
1252 set_winsock_errno ();
1253 closesocket (si->exitsock);
1258 socket_cleanup (select_record *, select_stuff *stuff)
1260 socketinf *si = (socketinf *)stuff->device_specific[FHDEVN(FH_SOCKET)];
1261 select_printf ("si %p si->thread %p", si, si ? si->thread : NULL);
1262 if (si && si->thread)
1264 select_printf ("connection to si->exitsock %p", si->exitsock);
1265 SOCKET s = socket (AF_INET, SOCK_STREAM, 0);
1266 /* Connecting to si->exitsock will cause any executing select to wake
1267 up. When this happens then the exitsock condition will cause the
1268 thread to terminate. */
1269 if (connect (s, (struct sockaddr *) &si->sin, sizeof (si->sin)) < 0)
1271 set_winsock_errno ();
1272 select_printf ("connect failed");
1273 /* FIXME: now what? */
1278 /* Wait for thread to go away */
1279 WaitForSingleObject (si->thread, INFINITE);
1280 shutdown (si->exitsock, 2);
1281 closesocket (si->exitsock);
1282 CloseHandle (si->thread);
1283 stuff->device_specific[FHDEVN(FH_SOCKET)] = NULL;
1286 select_printf ("returning");
1290 fhandler_socket::select_read (select_record *s)
1294 s = new select_record;
1295 s->startup = start_thread_socket;
1296 s->poll = poll_socket;
1297 s->verify = verify_true;
1298 s->cleanup = socket_cleanup;
1300 s->read_selected = TRUE;
1305 fhandler_socket::select_write (select_record *s)
1309 s = new select_record;
1310 s->startup = start_thread_socket;
1311 s->poll = poll_socket;
1312 s->verify = verify_true;
1313 s->cleanup = socket_cleanup;
1315 s->write_selected = TRUE;
1320 fhandler_socket::select_except (select_record *s)
1324 s = new select_record;
1325 s->startup = start_thread_socket;
1326 s->poll = poll_socket;
1327 s->verify = verify_true;
1328 s->cleanup = socket_cleanup;
1330 s->except_selected = TRUE;
1335 peek_windows (select_record *me, int)
1339 set_handle_or_return_if_not_open (h, me);
1341 if (me->read_selected && me->read_ready)
1344 if (PeekMessage (&m, (HWND) h, 0, 0, PM_NOREMOVE))
1346 me->read_ready = TRUE;
1347 select_printf ("window %d(%p) ready", me->fd, me->fh->get_handle ());
1351 select_printf ("window %d(%p) not ready", me->fd, me->fh->get_handle ());
1352 return me->write_ready;
1356 poll_windows (select_record *me, fd_set *readfds, fd_set *writefds,
1360 return peek_windows (me, 0) ?
1361 set_bits (me, readfds, writefds, exceptfds) :
1368 fhandler_windows::select_read (select_record *s)
1372 s = new select_record;
1373 s->startup = no_startup;
1374 s->poll = poll_windows;
1375 s->verify = poll_windows;
1377 s->h = get_handle ();
1378 s->read_selected = TRUE;
1379 s->h = get_handle ();
1380 s->windows_handle = TRUE;
1385 fhandler_windows::select_write (select_record *s)
1389 s = new select_record;
1390 s->startup = no_startup;
1392 s->verify = verify_ok;
1394 s->h = get_handle ();
1395 s->write_selected = TRUE;
1396 s->write_ready = TRUE;
1397 s->windows_handle = TRUE;
1402 fhandler_windows::select_except (select_record *s)
1406 s = new select_record;
1407 s->startup = no_startup;
1409 s->verify = verify_ok;
1411 s->h = get_handle ();
1412 s->except_selected = TRUE;
1413 s->except_ready = TRUE;
1414 s->windows_handle = TRUE;