3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006, 2007, 2008, 2009 Red Hat, Inc.
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
12 /* The following line means that the BSD socket definitions for
13 fd_set, FD_ISSET etc. are used in this file. */
15 #define __INSIDE_CYGWIN_NET__
19 #include <sys/param.h>
25 #define USE_SYS_TYPES_FD_SET
39 * All these defines below should be in sys/types.h
40 * but because of the includes above, they may not have
41 * been included. We create special UNIX_xxxx versions here.
45 #define NBBY 8 /* number of bits in a byte */
49 * Select uses bit masks of file descriptors in longs.
50 * These macros manipulate such bit fields (the filesystem macros use chars).
51 * FD_SETSIZE may be defined by the user, but the default here
52 * should be >= NOFILE (param.h).
56 #define UNIX_NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */
58 #define unix_howmany(x,y) (((x)+((y)-1))/(y))
61 #define unix_fd_set fd_set
63 #define NULL_fd_set ((fd_set *) NULL)
64 #define sizeof_fd_set(n) \
65 ((unsigned) (NULL_fd_set->fds_bits + unix_howmany ((n), UNIX_NFDBITS)))
66 #define UNIX_FD_SET(n, p) \
67 ((p)->fds_bits[(n)/UNIX_NFDBITS] |= (1L << ((n) % UNIX_NFDBITS)))
68 #define UNIX_FD_CLR(n, p) \
69 ((p)->fds_bits[(n)/UNIX_NFDBITS] &= ~(1L << ((n) % UNIX_NFDBITS)))
70 #define UNIX_FD_ISSET(n, p) \
71 ((p)->fds_bits[(n)/UNIX_NFDBITS] & (1L << ((n) % UNIX_NFDBITS)))
72 #define UNIX_FD_ZERO(p, n) \
73 memset ((caddr_t) (p), 0, sizeof_fd_set ((n)))
75 #define allocfd_set(n) ((fd_set *) memset (alloca (sizeof_fd_set (n)), 0, sizeof_fd_set (n)))
76 #define copyfd_set(to, from, n) memcpy (to, from, sizeof_fd_set (n));
78 #define set_handle_or_return_if_not_open(h, s) \
79 h = (s)->fh->get_handle (); \
80 if (cygheap->fdtab.not_open ((s)->fd)) \
82 (s)->thread_errno = EBADF; \
86 /* The main select code.
89 cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
93 fd_set *dummy_readfds = allocfd_set (maxfds);
94 fd_set *dummy_writefds = allocfd_set (maxfds);
95 fd_set *dummy_exceptfds = allocfd_set (maxfds);
97 select_printf ("%d, %p, %p, %p, %p", maxfds, readfds, writefds, exceptfds, to);
100 readfds = dummy_readfds;
102 writefds = dummy_writefds;
104 exceptfds = dummy_exceptfds;
106 for (int i = 0; i < maxfds; i++)
107 if (!sel.test_and_set (i, readfds, writefds, exceptfds))
109 select_printf ("aborting due to test_and_set error");
110 return -1; /* Invalid fd, maybe? */
113 /* Convert to milliseconds or INFINITE if to == NULL */
114 DWORD ms = to ? (to->tv_sec * 1000) + (to->tv_usec / 1000) : INFINITE;
115 if (ms == 0 && to->tv_usec)
116 ms = 1; /* At least 1 ms granularity */
119 select_printf ("to->tv_sec %d, to->tv_usec %d, ms %d", to->tv_sec, to->tv_usec, ms);
121 select_printf ("to NULL, ms %x", ms);
123 select_printf ("sel.always_ready %d", sel.always_ready);
126 /* Allocate some fd_set structures using the number of fds as a guide. */
127 fd_set *r = allocfd_set (maxfds);
128 fd_set *w = allocfd_set (maxfds);
129 fd_set *e = allocfd_set (maxfds);
131 /* Degenerate case. No fds to wait for. Just wait. */
132 if (sel.start.next == NULL)
134 if (WaitForSingleObject (signal_arrived, ms) == WAIT_OBJECT_0)
136 select_printf ("signal received");
137 set_sig_errno (EINTR);
142 else if (sel.always_ready || ms == 0)
143 /* Don't bother waiting. */;
144 else if ((timeout = sel.wait (r, w, e, ms) < 0))
145 return -1; /* some kind of error */
148 copyfd_set (readfds, r, maxfds);
149 copyfd_set (writefds, w, maxfds);
150 copyfd_set (exceptfds, e, maxfds);
151 return timeout ? 0 : sel.poll (readfds, writefds, exceptfds);
155 pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
156 const struct timespec *ts, const sigset_t *set)
159 sigset_t oldset = _my_tls.sigmask;
162 if (efault.faulted (EFAULT))
166 tv.tv_sec = ts->tv_sec;
167 tv.tv_usec = ts->tv_nsec / 1000;
170 set_signal_mask (*set, _my_tls.sigmask);
171 int ret = cygwin_select (maxfds, readfds, writefds, exceptfds,
174 set_signal_mask (oldset, _my_tls.sigmask);
178 /* Call cleanup functions for all inspected fds. Gets rid of any
179 executing threads. */
181 select_stuff::cleanup ()
183 select_record *s = &start;
185 select_printf ("calling cleanup routines");
186 while ((s = s->next))
189 s->cleanup (s, this);
194 /* Destroy all storage associated with select stuff. */
195 select_stuff::~select_stuff ()
198 select_record *s = &start;
199 select_record *snext = start.next;
201 select_printf ("deleting select records");
209 /* Add a record to the select chain */
211 select_stuff::test_and_set (int i, fd_set *readfds, fd_set *writefds,
214 if (!UNIX_FD_ISSET (i, readfds) && !UNIX_FD_ISSET (i, writefds)
215 && ! UNIX_FD_ISSET (i, exceptfds))
218 select_record *s = new select_record;
222 s->next = start.next;
225 if (UNIX_FD_ISSET (i, readfds) && !cygheap->fdtab.select_read (i, this))
227 if (UNIX_FD_ISSET (i, writefds) && !cygheap->fdtab.select_write (i, this))
229 if (UNIX_FD_ISSET (i, exceptfds) && !cygheap->fdtab.select_except (i, this))
230 goto err; /* error */
232 if (s->read_ready || s->write_ready || s->except_ready)
235 if (s->windows_handle)
241 start.next = s->next;
246 /* The heart of select. Waits for an fd to do something interesting. */
248 select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
252 HANDLE w4[MAXIMUM_WAIT_OBJECTS];
253 select_record *s = &start;
257 w4[m++] = signal_arrived; /* Always wait for the arrival of a signal. */
258 /* Loop through the select chain, starting up anything appropriate and
259 counting the number of active fds. */
260 while ((s = s->next))
262 if (m >= MAXIMUM_WAIT_OBJECTS)
264 set_sig_errno (EINVAL);
267 if (!s->startup (s, this))
269 s->set_select_errno ();
274 for (int i = 1; i < m; i++)
282 LONGLONG start_time = gtod.msecs (); /* Record the current time for later use. */
284 debug_printf ("m %d, ms %u", m, ms);
288 wait_ret = WaitForMultipleObjects (m, w4, FALSE, ms);
290 wait_ret = MsgWaitForMultipleObjects (m, w4, FALSE, ms, QS_ALLINPUT);
295 select_printf ("signal received");
296 set_sig_errno (EINTR);
299 select_printf ("WaitForMultipleObjects failed");
300 s->set_select_errno ();
303 select_printf ("timed out");
308 select_printf ("woke up. wait_ret %d. verifying", wait_ret);
311 /* Some types of objects (e.g., consoles) wake up on "inappropriate" events
312 like mouse movements. The verify function will detect these situations.
313 If it returns false, then this wakeup was a false alarm and we should go
315 while ((s = s->next))
318 set_errno (s->saw_error ());
319 return -1; /* Somebody detected an error */
321 else if ((((wait_ret >= m && s->windows_handle) || s->h == w4[wait_ret])) &&
322 s->verify (s, readfds, writefds, exceptfds))
325 select_printf ("gotone %d", gotone);
331 select_printf ("looping");
334 select_printf ("recalculating ms");
336 LONGLONG now = gtod.msecs ();
337 if (now > (start_time + ms))
339 select_printf ("timed out after verification");
342 ms -= (now - start_time);
344 select_printf ("ms now %u", ms);
348 select_printf ("returning %d", res);
353 set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
357 fhandler_socket *sock;
358 select_printf ("me %p, testing fd %d (%s)", me, me->fd, me->fh->get_name ());
359 if (me->read_selected && me->read_ready)
361 UNIX_FD_SET (me->fd, readfds);
364 if (me->write_selected && me->write_ready)
366 UNIX_FD_SET (me->fd, writefds);
367 if (me->except_on_write && (sock = me->fh->is_socket ()))
369 /* Special AF_LOCAL handling. */
370 if (!me->read_ready && sock->connect_state () == connect_pending
371 && sock->af_local_connect ())
373 if (me->read_selected)
374 UNIX_FD_SET (me->fd, readfds);
375 sock->connect_state (connect_failed);
378 sock->connect_state (connected);
382 if (me->except_selected && me->except_ready)
384 UNIX_FD_SET (me->fd, exceptfds);
387 select_printf ("ready %d", ready);
391 /* Poll every fd in the select chain. Set appropriate fd in mask. */
393 select_stuff::poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
396 select_record *s = &start;
397 while ((s = s->next))
398 n += (!s->peek || s->peek (s, true)) ?
399 set_bits (s, readfds, writefds, exceptfds) : 0;
400 select_printf ("returning %d", n);
405 verify_true (select_record *, fd_set *, fd_set *, fd_set *)
411 verify_ok (select_record *me, fd_set *readfds, fd_set *writefds,
414 return set_bits (me, readfds, writefds, exceptfds);
418 no_startup (select_record *, select_stuff *)
424 no_verify (select_record *, fd_set *, fd_set *, fd_set *)
430 peek_pipe (select_record *s, bool from_select)
434 fhandler_base *fh = s->fh;
437 set_handle_or_return_if_not_open (h, s);
439 /* Don't perform complicated tests if we don't need to. */
440 if (!s->read_selected && !s->except_selected)
443 if (s->read_selected)
447 select_printf ("%s, already ready for read", fh->get_name ());
452 switch (fh->get_major ())
455 if (((fhandler_pty_master *) fh)->need_nl)
457 gotone = s->read_ready = true;
462 if (fh->get_readahead_valid ())
464 select_printf ("readahead");
465 gotone = s->read_ready = true;
470 if (fh->bg_check (SIGTTIN) <= bg_eof)
472 gotone = s->read_ready = true;
477 if (fh->get_device () == FH_PIPEW)
478 select_printf ("%s, select for read/except on write end of pipe",
480 else if (!PeekNamedPipe (h, NULL, 0, NULL, (DWORD *) &n, NULL))
481 switch (GetLastError ())
484 case ERROR_PIPE_BUSY:
486 case ERROR_PIPE_NOT_CONNECTED:
490 select_printf ("%s, PeekNamedPipe failed, %E", fh->get_name ());
497 select_printf ("%s, n %d", fh->get_name (), n);
498 if (s->except_selected)
499 gotone += s->except_ready = true;
500 if (s->read_selected)
501 gotone += s->read_ready = true;
503 if (n > 0 && s->read_selected)
505 select_printf ("%s, ready for read: avail %d", fh->get_name (), n);
506 gotone += s->read_ready = true;
508 if (!gotone && s->fh->hit_eof ())
510 select_printf ("%s, saw EOF", fh->get_name ());
511 if (s->except_selected)
512 gotone += s->except_ready = true;
513 if (s->read_selected)
514 gotone += s->read_ready = true;
518 if (s->write_selected)
522 select_printf ("%s, already ready for write", fh->get_name ());
525 /* Do we need to do anything about SIGTTOU here? */
526 else if (fh->get_device () == FH_PIPER)
527 select_printf ("%s, select for write on read end of pipe",
529 else if (fh->has_ongoing_io (true))
530 s->write_ready = false;
533 IO_STATUS_BLOCK iosb = {0};
534 FILE_PIPE_LOCAL_INFORMATION fpli = {0};
536 if (NtQueryInformationFile (h,
540 FilePipeLocalInformation))
542 /* If NtQueryInformationFile fails, optimistically assume the
543 pipe is writable. This could happen if we somehow
544 inherit a pipe that doesn't permit FILE_READ_ATTRIBUTES
545 access on the write end. */
546 select_printf ("%s, NtQueryInformationFile failed",
548 gotone += s->write_ready = true;
550 /* If there is anything available in the pipe buffer then signal
551 that. This means that a pipe could still block since you could
552 be trying to write more to the pipe than is available in the
553 buffer but that is the hazard of select(). */
554 else if ((fpli.WriteQuotaAvailable = (fpli.OutboundQuota - fpli.ReadDataAvailable)))
556 select_printf ("%s, ready for write: size %lu, avail %lu",
559 fpli.WriteQuotaAvailable);
560 gotone += s->write_ready = true;
562 /* If we somehow inherit a tiny pipe (size < PIPE_BUF), then consider
563 the pipe writable only if it is completely empty, to minimize the
564 probability that a subsequent write will block. */
565 else if (fpli.OutboundQuota < PIPE_BUF &&
566 fpli.WriteQuotaAvailable == fpli.OutboundQuota)
568 select_printf ("%s, tiny pipe: size %lu, avail %lu",
571 fpli.WriteQuotaAvailable);
572 gotone += s->write_ready = true;
580 static int start_thread_pipe (select_record *me, select_stuff *stuff);
582 select_pipe_info::select_pipe_info ()
585 w4[0] = CreateEvent (&sec_none_nih, true, false, NULL);
588 select_pipe_info::~select_pipe_info ()
596 ForceCloseHandle (w4[0]);
600 select_pipe_info::add_watch_handle (fhandler_pipe *fh)
602 if (fh->get_overlapped () && fh->get_overlapped ()->hEvent)
603 w4[n++] = fh->get_overlapped ()->hEvent;
607 thread_pipe (void *arg)
609 select_pipe_info *pi = (select_pipe_info *) arg;
611 DWORD sleep_time = 0;
615 select_record *s = pi->start;
617 switch (WaitForMultipleObjects (pi->n, pi->w4, false, INFINITE))
624 while ((s = s->next))
625 if (s->startup == start_thread_pipe)
627 if (peek_pipe (s, true))
631 select_printf ("stopping");
638 select_printf ("stopping from outer loop");
643 Sleep (sleep_time >> 3);
652 start_thread_pipe (select_record *me, select_stuff *stuff)
654 select_pipe_info *pi = stuff->device_specific_pipe;
656 me->h = *((select_pipe_info *) stuff->device_specific_pipe)->thread;
659 pi->start = &stuff->start;
660 pi->stop_thread = false;
661 pi->thread = new cygthread (thread_pipe, 0, pi, "select_pipe");
670 pipe_cleanup (select_record *, select_stuff *stuff)
672 if (stuff->device_specific_pipe)
674 delete stuff->device_specific_pipe;
675 stuff->device_specific_pipe = NULL;
680 fhandler_pipe::ready_for_read (int fd, DWORD howlong)
684 res = fhandler_base::ready_for_read (fd, howlong);
691 fhandler_pipe::select_read (select_stuff *ss)
693 if (!ss->device_specific_pipe
694 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
696 ss->device_specific_pipe->add_watch_handle (this);
698 select_record *s = ss->start.next;
699 s->startup = start_thread_pipe;
701 s->verify = verify_ok;
702 s->cleanup = pipe_cleanup;
703 s->read_selected = true;
704 s->read_ready = false;
709 fhandler_pipe::select_write (select_stuff *ss)
711 if (!ss->device_specific_pipe
712 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
714 ss->device_specific_pipe->add_watch_handle (this);
715 select_record *s = ss->start.next;
716 s->startup = start_thread_pipe;
718 s->verify = verify_ok;
719 s->cleanup = pipe_cleanup;
720 s->write_selected = true;
721 s->write_ready = false;
726 fhandler_pipe::select_except (select_stuff *ss)
728 if (!ss->device_specific_pipe
729 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
731 ss->device_specific_pipe->add_watch_handle (this);
732 select_record *s = ss->start.next;
733 s->startup = start_thread_pipe;
735 s->verify = verify_ok;
736 s->cleanup = pipe_cleanup;
737 s->except_selected = true;
738 s->except_ready = false;
743 fhandler_fifo::select_read (select_stuff *ss)
745 select_record *s = ss->start.next;
746 s->startup = start_thread_pipe;
748 s->verify = verify_ok;
749 s->cleanup = pipe_cleanup;
750 s->read_selected = true;
751 s->read_ready = false;
756 fhandler_fifo::select_write (select_stuff *ss)
758 select_record *s = ss->start.next;
759 s->startup = start_thread_pipe;
761 s->verify = verify_ok;
762 s->cleanup = pipe_cleanup;
763 s->write_selected = true;
764 s->write_ready = false;
769 fhandler_fifo::select_except (select_stuff *ss)
771 select_record *s = ss->start.next;
772 s->startup = start_thread_pipe;
774 s->verify = verify_ok;
775 s->cleanup = pipe_cleanup;
776 s->except_selected = true;
777 s->except_ready = false;
782 peek_console (select_record *me, bool)
784 extern const char * get_nonascii_key (INPUT_RECORD& input_rec, char *);
785 fhandler_console *fh = (fhandler_console *) me->fh;
787 if (!me->read_selected)
788 return me->write_ready;
790 if (fh->get_readahead_valid ())
792 select_printf ("readahead");
793 return me->read_ready = true;
798 select_printf ("already ready");
806 set_handle_or_return_if_not_open (h, me);
809 if (fh->bg_check (SIGTTIN) <= bg_eof)
810 return me->read_ready = true;
811 else if (!PeekConsoleInput (h, &irec, 1, &events_read) || !events_read)
815 fh->send_winch_maybe ();
816 if (irec.EventType == KEY_EVENT)
818 if (irec.Event.KeyEvent.bKeyDown
819 && (irec.Event.KeyEvent.uChar.AsciiChar
820 || get_nonascii_key (irec, tmpbuf)))
821 return me->read_ready = true;
825 if (irec.EventType == MOUSE_EVENT
826 && fh->mouse_aware (irec.Event.MouseEvent))
827 return me->read_ready = true;
828 if (irec.EventType == FOCUS_EVENT && fh->focus_aware ())
829 return me->read_ready = true;
832 /* Read and discard the event */
833 ReadConsoleInput (h, &irec, 1, &events_read);
836 return me->write_ready;
840 verify_console (select_record *me, fd_set *rfds, fd_set *wfds,
843 return peek_console (me, true);
848 fhandler_console::select_read (select_stuff *ss)
850 select_record *s = ss->start.next;
853 s->startup = no_startup;
854 s->verify = verify_console;
858 s->peek = peek_console;
859 s->h = get_handle ();
860 s->read_selected = true;
861 s->read_ready = false;
866 fhandler_console::select_write (select_stuff *ss)
868 select_record *s = ss->start.next;
871 s->startup = no_startup;
872 s->verify = no_verify;
876 s->peek = peek_console;
877 s->write_selected = true;
878 s->write_ready = true;
883 fhandler_console::select_except (select_stuff *ss)
885 select_record *s = ss->start.next;
888 s->startup = no_startup;
889 s->verify = no_verify;
893 s->peek = peek_console;
894 s->except_selected = true;
895 s->except_ready = false;
900 fhandler_tty_common::select_read (select_stuff *ss)
902 return ((fhandler_pipe *) this)->fhandler_pipe::select_read (ss);
906 fhandler_tty_common::select_write (select_stuff *ss)
908 return ((fhandler_pipe *) this)->fhandler_pipe::select_write (ss);
912 fhandler_tty_common::select_except (select_stuff *ss)
914 return ((fhandler_pipe *) this)->fhandler_pipe::select_except (ss);
918 verify_tty_slave (select_record *me, fd_set *readfds, fd_set *writefds,
921 if (WaitForSingleObject (me->h, 0) == WAIT_OBJECT_0)
922 me->read_ready = true;
923 return set_bits (me, readfds, writefds, exceptfds);
927 fhandler_tty_slave::select_read (select_stuff *ss)
929 select_record *s = ss->start.next;
930 s->h = input_available_event;
931 s->startup = no_startup;
933 s->verify = verify_tty_slave;
934 s->read_selected = true;
935 s->read_ready = false;
941 fhandler_dev_null::select_read (select_stuff *ss)
943 select_record *s = ss->start.next;
946 s->startup = no_startup;
947 s->verify = no_verify;
949 s->h = get_handle ();
950 s->read_selected = true;
951 s->read_ready = true;
956 fhandler_dev_null::select_write (select_stuff *ss)
958 select_record *s = ss->start.next;
961 s->startup = no_startup;
962 s->verify = no_verify;
964 s->h = get_handle ();
965 s->write_selected = true;
966 s->write_ready = true;
971 fhandler_dev_null::select_except (select_stuff *ss)
973 select_record *s = ss->start.next;
976 s->startup = no_startup;
977 s->verify = no_verify;
979 s->h = get_handle ();
980 s->except_selected = true;
981 s->except_ready = false;
985 static int start_thread_serial (select_record *me, select_stuff *stuff);
988 peek_serial (select_record *s, bool)
992 fhandler_serial *fh = (fhandler_serial *) s->fh;
994 if (fh->get_readahead_valid () || fh->overlapped_armed < 0)
995 return s->read_ready = true;
997 select_printf ("fh->overlapped_armed %d", fh->overlapped_armed);
1000 set_handle_or_return_if_not_open (h, s);
1003 if ((s->read_selected && s->read_ready) || (s->write_selected && s->write_ready))
1005 select_printf ("already ready");
1010 /* This is apparently necessary for the com0com driver.
1011 See: http://cygwin.com/ml/cygwin/2009-01/msg00667.html */
1014 SetCommMask (h, EV_RXCHAR);
1016 if (!fh->overlapped_armed)
1020 ResetEvent (fh->io_status.hEvent);
1022 if (!ClearCommError (h, &fh->ev, &st))
1024 debug_printf ("ClearCommError");
1027 else if (st.cbInQue)
1028 return s->read_ready = true;
1029 else if (WaitCommEvent (h, &fh->ev, &fh->io_status))
1030 return s->read_ready = true;
1031 else if (GetLastError () == ERROR_IO_PENDING)
1032 fh->overlapped_armed = 1;
1035 debug_printf ("WaitCommEvent");
1043 w4[0] = fh->io_status.hEvent;
1044 w4[1] = signal_arrived;
1047 switch (WaitForMultipleObjects (2, w4, FALSE, to))
1050 if (!ClearCommError (h, &fh->ev, &st))
1052 debug_printf ("ClearCommError");
1055 else if (!st.cbInQue)
1059 return s->read_ready = true;
1060 select_printf ("got something");
1063 case WAIT_OBJECT_0 + 1:
1064 select_printf ("interrupt");
1065 set_sig_errno (EINTR);
1071 debug_printf ("WaitForMultipleObjects");
1079 if (GetLastError () == ERROR_OPERATION_ABORTED)
1081 select_printf ("operation aborted");
1085 s->set_select_errno ();
1086 select_printf ("error %E");
1091 thread_serial (void *arg)
1093 select_serial_info *si = (select_serial_info *) arg;
1094 bool gotone = false;
1098 select_record *s = si->start;
1099 while ((s = s->next))
1100 if (s->startup == start_thread_serial)
1102 if (peek_serial (s, true))
1105 if (si->stop_thread)
1107 select_printf ("stopping");
1114 select_printf ("exiting");
1119 start_thread_serial (select_record *me, select_stuff *stuff)
1121 if (stuff->device_specific_serial)
1122 me->h = *((select_serial_info *) stuff->device_specific_serial)->thread;
1125 select_serial_info *si = new select_serial_info;
1126 si->start = &stuff->start;
1127 si->stop_thread = false;
1128 si->thread = new cygthread (thread_serial, 0, si, "select_serial");
1129 me->h = *si->thread;
1130 stuff->device_specific_serial = si;
1136 serial_cleanup (select_record *, select_stuff *stuff)
1138 select_serial_info *si = (select_serial_info *) stuff->device_specific_serial;
1139 if (si && si->thread)
1141 si->stop_thread = true;
1142 si->thread->detach ();
1144 stuff->device_specific_serial = NULL;
1149 fhandler_serial::select_read (select_stuff *ss)
1151 select_record *s = ss->start.next;
1154 s->startup = start_thread_serial;
1155 s->verify = verify_ok;
1156 s->cleanup = serial_cleanup;
1158 s->peek = peek_serial;
1159 s->read_selected = true;
1160 s->read_ready = false;
1165 fhandler_serial::select_write (select_stuff *ss)
1167 select_record *s = ss->start.next;
1170 s->startup = no_startup;
1171 s->verify = verify_ok;
1173 s->peek = peek_serial;
1174 s->h = get_handle ();
1175 s->write_selected = true;
1176 s->write_ready = true;
1181 fhandler_serial::select_except (select_stuff *ss)
1183 select_record *s = ss->start.next;
1186 s->startup = no_startup;
1187 s->verify = verify_ok;
1190 s->peek = peek_serial;
1191 s->except_selected = false; // Can't do this
1192 s->except_ready = false;
1197 fhandler_base::ready_for_read (int fd, DWORD howlong)
1202 fd_set *thisfd = allocfd_set (fd + 1);
1203 fd_set *dummy_writefds = allocfd_set (fd + 1);
1204 fd_set *dummy_exceptfds = allocfd_set (fd + 1);
1205 UNIX_FD_SET(fd, thisfd);
1207 if (!sel.test_and_set (fd, thisfd, dummy_writefds, dummy_exceptfds))
1208 select_printf ("aborting due to test_and_set error");
1211 select_record *me = sel.start.next;
1214 avail = me->read_ready ?: me->peek (me, false);
1216 if (fd >= 0 && cygheap->fdtab.not_open (fd))
1218 set_sig_errno (EBADF);
1223 if (howlong != INFINITE)
1226 set_sig_errno (EAGAIN);
1230 if (WaitForSingleObject (signal_arrived, avail ? 0 : 10) == WAIT_OBJECT_0)
1232 debug_printf ("interrupted");
1233 set_sig_errno (EINTR);
1240 select_printf ("read_ready %d, avail %d", sel.start.next->read_ready, avail);
1246 fhandler_base::select_read (select_stuff *ss)
1248 select_record *s = ss->start.next;
1251 s->startup = no_startup;
1252 s->verify = verify_ok;
1254 s->h = get_handle ();
1255 s->read_selected = true;
1256 s->read_ready = true;
1261 fhandler_base::select_write (select_stuff *ss)
1263 select_record *s = ss->start.next;
1266 s->startup = no_startup;
1267 s->verify = verify_ok;
1269 s->h = get_handle ();
1270 s->write_selected = true;
1271 s->write_ready = true;
1276 fhandler_base::select_except (select_stuff *ss)
1278 select_record *s = ss->start.next;
1281 s->startup = no_startup;
1282 s->verify = verify_ok;
1285 s->except_selected = true;
1286 s->except_ready = false;
1291 peek_socket (select_record *me, bool)
1293 fhandler_socket *fh = (fhandler_socket *) me->fh;
1295 /* Don't play with the settings again, unless having taken a deep look into
1296 Richard W. Stevens Network Programming book. Thank you. */
1297 long evt_mask = (me->read_selected ? (FD_READ | FD_ACCEPT | FD_CLOSE) : 0)
1298 | (me->write_selected ? (FD_WRITE | FD_CONNECT | FD_CLOSE) : 0)
1299 | (me->except_selected ? FD_OOB : 0);
1300 int ret = fh->evaluate_events (evt_mask, events, false);
1301 if (me->read_selected)
1302 me->read_ready |= ret || !!(events & (FD_READ | FD_ACCEPT | FD_CLOSE));
1303 if (me->write_selected)
1304 me->write_ready |= ret || !!(events & (FD_WRITE | FD_CONNECT | FD_CLOSE));
1305 if (me->except_selected)
1306 me->except_ready |= !!(events & FD_OOB);
1308 select_printf ("read_ready: %d, write_ready: %d, except_ready: %d",
1309 me->read_ready, me->write_ready, me->except_ready);
1310 return me->read_ready || me->write_ready || me->except_ready;
1313 static int start_thread_socket (select_record *, select_stuff *);
1316 thread_socket (void *arg)
1318 select_socket_info *si = (select_socket_info *) arg;
1319 DWORD timeout = (si->num_w4 <= MAXIMUM_WAIT_OBJECTS)
1321 : (64 / (roundup2 (si->num_w4, MAXIMUM_WAIT_OBJECTS)
1322 / MAXIMUM_WAIT_OBJECTS));
1325 select_printf ("stuff_start %p", si->start);
1328 for (select_record *s = si->start; (s = s->next); )
1329 if (s->startup == start_thread_socket)
1330 if (peek_socket (s, false))
1333 for (int i = 0; i < si->num_w4; i += MAXIMUM_WAIT_OBJECTS)
1334 switch (WaitForMultipleObjects (min (si->num_w4 - i,
1335 MAXIMUM_WAIT_OBJECTS),
1336 si->w4 + i, FALSE, timeout))
1343 if (!i) /* Socket event set. */
1351 select_printf ("leaving thread_socket");
1355 static inline bool init_tls_select_info () __attribute__ ((always_inline));
1357 init_tls_select_info ()
1359 if (!_my_tls.locals.select.sockevt)
1361 _my_tls.locals.select.sockevt = CreateEvent (&sec_none_nih, TRUE, FALSE,
1363 if (!_my_tls.locals.select.sockevt)
1366 if (!_my_tls.locals.select.ser_num)
1368 _my_tls.locals.select.ser_num
1369 = (LONG *) malloc (MAXIMUM_WAIT_OBJECTS * sizeof (LONG));
1370 if (!_my_tls.locals.select.ser_num)
1372 _my_tls.locals.select.w4
1373 = (HANDLE *) malloc (MAXIMUM_WAIT_OBJECTS * sizeof (HANDLE));
1374 if (!_my_tls.locals.select.w4)
1376 free (_my_tls.locals.select.ser_num);
1377 _my_tls.locals.select.ser_num = NULL;
1380 _my_tls.locals.select.max_w4 = MAXIMUM_WAIT_OBJECTS;
1386 start_thread_socket (select_record *me, select_stuff *stuff)
1388 select_socket_info *si;
1390 if ((si = (select_socket_info *) stuff->device_specific_socket))
1392 me->h = *si->thread;
1396 si = new select_socket_info;
1398 if (!init_tls_select_info ())
1401 si->ser_num = _my_tls.locals.select.ser_num;
1402 si->w4 = _my_tls.locals.select.w4;
1404 si->w4[0] = _my_tls.locals.select.sockevt;
1407 select_record *s = &stuff->start;
1408 while ((s = s->next))
1409 if (s->startup == start_thread_socket)
1411 /* No event/socket should show up multiple times. Every socket
1412 is uniquely identified by its serial number in the global
1413 wsock_events record. */
1414 const LONG ser_num = ((fhandler_socket *) s->fh)->serial_number ();
1415 for (int i = 1; i < si->num_w4; ++i)
1416 if (si->ser_num[i] == ser_num)
1417 goto continue_outer_loop;
1418 if (si->num_w4 >= _my_tls.locals.select.max_w4)
1420 LONG *nser = (LONG *) realloc (si->ser_num,
1421 (_my_tls.locals.select.max_w4
1422 + MAXIMUM_WAIT_OBJECTS)
1426 _my_tls.locals.select.ser_num = si->ser_num = nser;
1427 HANDLE *nw4 = (HANDLE *) realloc (si->w4,
1428 (_my_tls.locals.select.max_w4
1429 + MAXIMUM_WAIT_OBJECTS)
1433 _my_tls.locals.select.w4 = si->w4 = nw4;
1434 _my_tls.locals.select.max_w4 += MAXIMUM_WAIT_OBJECTS;
1436 si->ser_num[si->num_w4] = ser_num;
1437 si->w4[si->num_w4++] = ((fhandler_socket *) s->fh)->wsock_event ();
1438 continue_outer_loop:
1441 stuff->device_specific_socket = si;
1442 si->start = &stuff->start;
1443 select_printf ("stuff_start %p", &stuff->start);
1444 si->thread = new cygthread (thread_socket, 0, si, "select_socket");
1445 me->h = *si->thread;
1450 socket_cleanup (select_record *, select_stuff *stuff)
1452 select_socket_info *si = (select_socket_info *) stuff->device_specific_socket;
1453 select_printf ("si %p si->thread %p", si, si ? si->thread : NULL);
1454 if (si && si->thread)
1456 SetEvent (si->w4[0]);
1457 /* Wait for thread to go away */
1458 si->thread->detach ();
1459 ResetEvent (si->w4[0]);
1460 stuff->device_specific_socket = NULL;
1463 select_printf ("returning");
1467 fhandler_socket::select_read (select_stuff *ss)
1469 select_record *s = ss->start.next;
1472 s->startup = start_thread_socket;
1473 s->verify = verify_true;
1474 s->cleanup = socket_cleanup;
1476 s->peek = peek_socket;
1477 s->read_ready = saw_shutdown_read ();
1478 s->read_selected = true;
1483 fhandler_socket::select_write (select_stuff *ss)
1485 select_record *s = ss->start.next;
1488 s->startup = start_thread_socket;
1489 s->verify = verify_true;
1490 s->cleanup = socket_cleanup;
1492 s->peek = peek_socket;
1493 s->write_ready = saw_shutdown_write () || connect_state () == unconnected;
1494 s->write_selected = true;
1495 if (connect_state () != unconnected)
1497 s->except_ready = saw_shutdown_write () || saw_shutdown_read ();
1498 s->except_on_write = true;
1504 fhandler_socket::select_except (select_stuff *ss)
1506 select_record *s = ss->start.next;
1509 s->startup = start_thread_socket;
1510 s->verify = verify_true;
1511 s->cleanup = socket_cleanup;
1513 s->peek = peek_socket;
1514 /* FIXME: Is this right? Should these be used as criteria for except? */
1515 s->except_ready = saw_shutdown_write () || saw_shutdown_read ();
1516 s->except_selected = true;
1521 peek_windows (select_record *me, bool)
1525 set_handle_or_return_if_not_open (h, me);
1527 if (me->read_selected && me->read_ready)
1530 if (PeekMessage (&m, (HWND) h, 0, 0, PM_NOREMOVE))
1532 me->read_ready = true;
1533 select_printf ("window %d(%p) ready", me->fd, me->fh->get_handle ());
1537 select_printf ("window %d(%p) not ready", me->fd, me->fh->get_handle ());
1538 return me->write_ready;
1542 verify_windows (select_record *me, fd_set *rfds, fd_set *wfds,
1545 return peek_windows (me, true);
1549 fhandler_windows::select_read (select_stuff *ss)
1551 select_record *s = ss->start.next;
1554 s->startup = no_startup;
1556 s->verify = verify_windows;
1557 s->peek = peek_windows;
1558 s->read_selected = true;
1559 s->read_ready = false;
1560 s->h = get_handle ();
1561 s->windows_handle = true;
1566 fhandler_windows::select_write (select_stuff *ss)
1568 select_record *s = ss->start.next;
1571 s->startup = no_startup;
1572 s->verify = verify_ok;
1574 s->peek = peek_windows;
1575 s->h = get_handle ();
1576 s->write_selected = true;
1577 s->write_ready = true;
1578 s->windows_handle = true;
1583 fhandler_windows::select_except (select_stuff *ss)
1585 select_record *s = ss->start.next;
1588 s->startup = no_startup;
1589 s->verify = verify_ok;
1591 s->peek = peek_windows;
1592 s->h = get_handle ();
1593 s->except_selected = true;
1594 s->except_ready = false;
1595 s->windows_handle = true;
1600 peek_mailslot (select_record *me, bool)
1603 set_handle_or_return_if_not_open (h, me);
1605 if (me->read_selected && me->read_ready)
1608 if (!GetMailslotInfo (h, NULL, NULL, &msgcnt, NULL))
1610 select_printf ("mailslot %d(%p) error %E", me->fd, h);
1615 me->read_ready = true;
1616 select_printf ("mailslot %d(%p) ready", me->fd, h);
1619 select_printf ("mailslot %d(%p) not ready", me->fd, h);
1624 verify_mailslot (select_record *me, fd_set *rfds, fd_set *wfds,
1627 return peek_mailslot (me, true);
1630 static int start_thread_mailslot (select_record *me, select_stuff *stuff);
1633 thread_mailslot (void *arg)
1635 select_mailslot_info *mi = (select_mailslot_info *) arg;
1636 bool gotone = false;
1637 DWORD sleep_time = 0;
1641 select_record *s = mi->start;
1642 while ((s = s->next))
1643 if (s->startup == start_thread_mailslot)
1645 if (peek_mailslot (s, true))
1647 if (mi->stop_thread)
1649 select_printf ("stopping");
1653 /* Paranoid check */
1654 if (mi->stop_thread)
1656 select_printf ("stopping from outer loop");
1661 Sleep (sleep_time >> 3);
1662 if (sleep_time < 80)
1670 start_thread_mailslot (select_record *me, select_stuff *stuff)
1672 if (stuff->device_specific_mailslot)
1674 me->h = *((select_mailslot_info *) stuff->device_specific_mailslot)->thread;
1677 select_mailslot_info *mi = new select_mailslot_info;
1678 mi->start = &stuff->start;
1679 mi->stop_thread = false;
1680 mi->thread = new cygthread (thread_mailslot, 0, mi, "select_mailslot");
1681 me->h = *mi->thread;
1684 stuff->device_specific_mailslot = mi;
1689 mailslot_cleanup (select_record *, select_stuff *stuff)
1691 select_mailslot_info *mi = (select_mailslot_info *) stuff->device_specific_mailslot;
1692 if (mi && mi->thread)
1694 mi->stop_thread = true;
1695 mi->thread->detach ();
1697 stuff->device_specific_mailslot = NULL;
1702 fhandler_mailslot::select_read (select_stuff *ss)
1704 select_record *s = ss->start.next;
1705 s->startup = start_thread_mailslot;
1706 s->peek = peek_mailslot;
1707 s->verify = verify_mailslot;
1708 s->cleanup = mailslot_cleanup;
1709 s->read_selected = true;
1710 s->read_ready = false;