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__
24 #define USE_SYS_TYPES_FD_SET
38 * All these defines below should be in sys/types.h
39 * but because of the includes above, they may not have
40 * been included. We create special UNIX_xxxx versions here.
44 #define NBBY 8 /* number of bits in a byte */
48 * Select uses bit masks of file descriptors in longs.
49 * These macros manipulate such bit fields (the filesystem macros use chars).
50 * FD_SETSIZE may be defined by the user, but the default here
51 * should be >= NOFILE (param.h).
55 #define UNIX_NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */
57 #define unix_howmany(x,y) (((x)+((y)-1))/(y))
60 #define unix_fd_set fd_set
62 #define NULL_fd_set ((fd_set *) NULL)
63 #define sizeof_fd_set(n) \
64 ((unsigned) (NULL_fd_set->fds_bits + unix_howmany ((n), UNIX_NFDBITS)))
65 #define UNIX_FD_SET(n, p) \
66 ((p)->fds_bits[(n)/UNIX_NFDBITS] |= (1L << ((n) % UNIX_NFDBITS)))
67 #define UNIX_FD_CLR(n, p) \
68 ((p)->fds_bits[(n)/UNIX_NFDBITS] &= ~(1L << ((n) % UNIX_NFDBITS)))
69 #define UNIX_FD_ISSET(n, p) \
70 ((p)->fds_bits[(n)/UNIX_NFDBITS] & (1L << ((n) % UNIX_NFDBITS)))
71 #define UNIX_FD_ZERO(p, n) \
72 memset ((caddr_t) (p), 0, sizeof_fd_set ((n)))
74 #define allocfd_set(n) ((fd_set *) memset (alloca (sizeof_fd_set (n)), 0, sizeof_fd_set (n)))
75 #define copyfd_set(to, from, n) memcpy (to, from, sizeof_fd_set (n));
77 #define set_handle_or_return_if_not_open(h, s) \
78 h = (s)->fh->get_handle (); \
79 if (cygheap->fdtab.not_open ((s)->fd)) \
81 (s)->thread_errno = EBADF; \
85 /* The main select code.
88 cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
92 fd_set *dummy_readfds = allocfd_set (maxfds);
93 fd_set *dummy_writefds = allocfd_set (maxfds);
94 fd_set *dummy_exceptfds = allocfd_set (maxfds);
96 select_printf ("%d, %p, %p, %p, %p", maxfds, readfds, writefds, exceptfds, to);
99 readfds = dummy_readfds;
101 writefds = dummy_writefds;
103 exceptfds = dummy_exceptfds;
105 for (int i = 0; i < maxfds; i++)
106 if (!sel.test_and_set (i, readfds, writefds, exceptfds))
108 select_printf ("aborting due to test_and_set error");
109 return -1; /* Invalid fd, maybe? */
112 /* Convert to milliseconds or INFINITE if to == NULL */
113 DWORD ms = to ? (to->tv_sec * 1000) + (to->tv_usec / 1000) : INFINITE;
114 if (ms == 0 && to->tv_usec)
115 ms = 1; /* At least 1 ms granularity */
118 select_printf ("to->tv_sec %d, to->tv_usec %d, ms %d", to->tv_sec, to->tv_usec, ms);
120 select_printf ("to NULL, ms %x", ms);
122 select_printf ("sel.always_ready %d", sel.always_ready);
125 /* Allocate some fd_set structures using the number of fds as a guide. */
126 fd_set *r = allocfd_set (maxfds);
127 fd_set *w = allocfd_set (maxfds);
128 fd_set *e = allocfd_set (maxfds);
130 /* Degenerate case. No fds to wait for. Just wait. */
131 if (sel.start.next == NULL)
133 if (WaitForSingleObject (signal_arrived, ms) == WAIT_OBJECT_0)
135 select_printf ("signal received");
136 set_sig_errno (EINTR);
141 else if (sel.always_ready || ms == 0)
142 /* Don't bother waiting. */;
143 else if ((timeout = sel.wait (r, w, e, ms) < 0))
144 return -1; /* some kind of error */
147 copyfd_set (readfds, r, maxfds);
148 copyfd_set (writefds, w, maxfds);
149 copyfd_set (exceptfds, e, maxfds);
150 return timeout ? 0 : sel.poll (readfds, writefds, exceptfds);
154 pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
155 const struct timespec *ts, const sigset_t *set)
158 sigset_t oldset = _my_tls.sigmask;
161 if (efault.faulted (EFAULT))
165 tv.tv_sec = ts->tv_sec;
166 tv.tv_usec = ts->tv_nsec / 1000;
169 set_signal_mask (*set, _my_tls.sigmask);
170 int ret = cygwin_select (maxfds, readfds, writefds, exceptfds,
173 set_signal_mask (oldset, _my_tls.sigmask);
177 /* Call cleanup functions for all inspected fds. Gets rid of any
178 executing threads. */
180 select_stuff::cleanup ()
182 select_record *s = &start;
184 select_printf ("calling cleanup routines");
185 while ((s = s->next))
188 s->cleanup (s, this);
193 /* Destroy all storage associated with select stuff. */
194 select_stuff::~select_stuff ()
197 select_record *s = &start;
198 select_record *snext = start.next;
200 select_printf ("deleting select records");
208 /* Add a record to the select chain */
210 select_stuff::test_and_set (int i, fd_set *readfds, fd_set *writefds,
213 if (!UNIX_FD_ISSET (i, readfds) && !UNIX_FD_ISSET (i, writefds)
214 && ! UNIX_FD_ISSET (i, exceptfds))
217 select_record *s = new select_record;
221 s->next = start.next;
224 if (UNIX_FD_ISSET (i, readfds) && !cygheap->fdtab.select_read (i, this))
226 if (UNIX_FD_ISSET (i, writefds) && !cygheap->fdtab.select_write (i, this))
228 if (UNIX_FD_ISSET (i, exceptfds) && !cygheap->fdtab.select_except (i, this))
229 goto err; /* error */
231 if (s->read_ready || s->write_ready || s->except_ready)
234 if (s->windows_handle)
240 start.next = s->next;
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;
256 w4[m++] = signal_arrived; /* Always wait for the arrival of a signal. */
257 /* Loop through the select chain, starting up anything appropriate and
258 counting the number of active fds. */
259 while ((s = s->next))
261 if (m >= MAXIMUM_WAIT_OBJECTS)
263 set_sig_errno (EINVAL);
266 if (!s->startup (s, this))
268 s->set_select_errno ();
273 for (int i = 1; i < m; i++)
281 LONGLONG start_time = gtod.msecs (); /* Record the current time for later use. */
283 debug_printf ("m %d, ms %u", m, ms);
287 wait_ret = WaitForMultipleObjects (m, w4, FALSE, ms);
289 wait_ret = MsgWaitForMultipleObjects (m, w4, FALSE, ms, QS_ALLINPUT);
294 select_printf ("signal received");
295 set_sig_errno (EINTR);
298 select_printf ("WaitForMultipleObjects failed");
299 s->set_select_errno ();
302 select_printf ("timed out");
307 select_printf ("woke up. wait_ret %d. verifying", wait_ret);
310 /* Some types of objects (e.g., consoles) wake up on "inappropriate" events
311 like mouse movements. The verify function will detect these situations.
312 If it returns false, then this wakeup was a false alarm and we should go
314 while ((s = s->next))
317 set_errno (s->saw_error ());
318 return -1; /* Somebody detected an error */
320 else if ((((wait_ret >= m && s->windows_handle) || s->h == w4[wait_ret])) &&
321 s->verify (s, readfds, writefds, exceptfds))
324 select_printf ("gotone %d", gotone);
330 select_printf ("looping");
333 select_printf ("recalculating ms");
335 LONGLONG now = gtod.msecs ();
336 if (now > (start_time + ms))
338 select_printf ("timed out after verification");
341 ms -= (now - start_time);
343 select_printf ("ms now %u", ms);
347 select_printf ("returning %d", res);
352 set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
356 fhandler_socket *sock;
357 select_printf ("me %p, testing fd %d (%s)", me, me->fd, me->fh->get_name ());
358 if (me->read_selected && me->read_ready)
360 UNIX_FD_SET (me->fd, readfds);
363 if (me->write_selected && me->write_ready)
365 UNIX_FD_SET (me->fd, writefds);
366 if (me->except_on_write && (sock = me->fh->is_socket ()))
368 /* Special AF_LOCAL handling. */
369 if (!me->read_ready && sock->connect_state () == connect_pending
370 && sock->af_local_connect ())
372 if (me->read_selected)
373 UNIX_FD_SET (me->fd, readfds);
374 sock->connect_state (connect_failed);
377 sock->connect_state (connected);
381 if (me->except_selected && me->except_ready)
383 UNIX_FD_SET (me->fd, exceptfds);
386 select_printf ("ready %d", ready);
390 /* Poll every fd in the select chain. Set appropriate fd in mask. */
392 select_stuff::poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
395 select_record *s = &start;
396 while ((s = s->next))
397 n += (!s->peek || s->peek (s, true)) ?
398 set_bits (s, readfds, writefds, exceptfds) : 0;
399 select_printf ("returning %d", n);
404 verify_true (select_record *, fd_set *, fd_set *, fd_set *)
410 verify_ok (select_record *me, fd_set *readfds, fd_set *writefds,
413 return set_bits (me, readfds, writefds, exceptfds);
417 no_startup (select_record *, select_stuff *)
423 no_verify (select_record *, fd_set *, fd_set *, fd_set *)
429 peek_pipe (select_record *s, bool from_select)
433 fhandler_base *fh = s->fh;
436 set_handle_or_return_if_not_open (h, s);
438 /* Don't perform complicated tests if we don't need to. */
439 if (!s->read_selected && !s->except_selected)
442 if (s->read_selected)
446 select_printf ("%s, already ready for read", fh->get_name ());
451 switch (fh->get_major ())
454 if (((fhandler_pty_master *) fh)->need_nl)
456 gotone = s->read_ready = true;
461 if (fh->get_readahead_valid ())
463 select_printf ("readahead");
464 gotone = s->read_ready = true;
469 if (fh->bg_check (SIGTTIN) <= bg_eof)
471 gotone = s->read_ready = true;
476 if (fh->get_device () == FH_PIPEW)
477 select_printf ("%s, select for read/except on write end of pipe",
479 else if (!PeekNamedPipe (h, NULL, 0, NULL, (DWORD *) &n, NULL))
480 switch (GetLastError ())
483 case ERROR_PIPE_BUSY:
485 case ERROR_PIPE_NOT_CONNECTED:
489 select_printf ("%s, PeekNamedPipe failed, %E", fh->get_name ());
496 select_printf ("%s, n %d", fh->get_name (), n);
497 if (s->except_selected)
498 gotone += s->except_ready = true;
499 if (s->read_selected)
500 gotone += s->read_ready = true;
502 if (n > 0 && s->read_selected)
504 select_printf ("%s, ready for read: avail %d", fh->get_name (), n);
505 gotone += s->read_ready = true;
507 if (!gotone && s->fh->hit_eof ())
509 select_printf ("%s, saw EOF", fh->get_name ());
510 if (s->except_selected)
511 gotone += s->except_ready = true;
512 if (s->read_selected)
513 gotone += s->read_ready = true;
517 if (s->write_selected)
521 select_printf ("%s, already ready for write", fh->get_name ());
524 /* Do we need to do anything about SIGTTOU here? */
525 else if (fh->get_device () == FH_PIPER)
526 select_printf ("%s, select for write on read end of pipe",
528 else if (fh->has_ongoing_io (true))
529 s->write_ready = false;
532 IO_STATUS_BLOCK iosb = {0};
533 FILE_PIPE_LOCAL_INFORMATION fpli = {0};
535 if (NtQueryInformationFile (h,
539 FilePipeLocalInformation))
541 /* If NtQueryInformationFile fails, optimistically assume the
542 pipe is writable. This could happen if we somehow
543 inherit a pipe that doesn't permit FILE_READ_ATTRIBUTES
544 access on the write end. */
545 select_printf ("%s, NtQueryInformationFile failed",
547 gotone += s->write_ready = true;
549 /* If there is anything available in the pipe buffer then signal
550 that. This means that a pipe could still block since you could
551 be trying to write more to the pipe than is available in the
552 buffer but that is the hazard of select(). */
553 else if ((fpli.WriteQuotaAvailable = (fpli.OutboundQuota - fpli.ReadDataAvailable)))
555 select_printf ("%s, ready for write: size %lu, avail %lu",
558 fpli.WriteQuotaAvailable);
559 gotone += s->write_ready = true;
561 /* If we somehow inherit a tiny pipe (size < PIPE_BUF), then consider
562 the pipe writable only if it is completely empty, to minimize the
563 probability that a subsequent write will block. */
564 else if (fpli.OutboundQuota < PIPE_BUF &&
565 fpli.WriteQuotaAvailable == fpli.OutboundQuota)
567 select_printf ("%s, tiny pipe: size %lu, avail %lu",
570 fpli.WriteQuotaAvailable);
571 gotone += s->write_ready = true;
579 static int start_thread_pipe (select_record *me, select_stuff *stuff);
581 select_pipe_info::select_pipe_info ()
584 w4[0] = CreateEvent (&sec_none_nih, true, false, NULL);
587 select_pipe_info::~select_pipe_info ()
595 ForceCloseHandle (w4[0]);
599 select_pipe_info::add_watch_handle (fhandler_pipe *fh)
601 if (fh->get_overlapped () && fh->get_overlapped ()->hEvent)
602 w4[n++] = fh->get_overlapped ()->hEvent;
606 thread_pipe (void *arg)
608 select_pipe_info *pi = (select_pipe_info *) arg;
610 DWORD sleep_time = 0;
614 select_record *s = pi->start;
616 switch (WaitForMultipleObjects (pi->n, pi->w4, false, INFINITE))
623 while ((s = s->next))
624 if (s->startup == start_thread_pipe)
626 if (peek_pipe (s, true))
630 select_printf ("stopping");
637 select_printf ("stopping from outer loop");
642 Sleep (sleep_time >> 3);
651 start_thread_pipe (select_record *me, select_stuff *stuff)
653 select_pipe_info *pi = stuff->device_specific_pipe;
655 me->h = *((select_pipe_info *) stuff->device_specific_pipe)->thread;
658 pi->start = &stuff->start;
659 pi->stop_thread = false;
660 pi->thread = new cygthread (thread_pipe, 0, pi, "select_pipe");
669 pipe_cleanup (select_record *, select_stuff *stuff)
671 if (stuff->device_specific_pipe)
673 delete stuff->device_specific_pipe;
674 stuff->device_specific_pipe = NULL;
679 fhandler_pipe::ready_for_read (int fd, DWORD howlong)
683 res = fhandler_base::ready_for_read (fd, howlong);
690 fhandler_pipe::select_read (select_stuff *ss)
692 if (!ss->device_specific_pipe
693 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
695 ss->device_specific_pipe->add_watch_handle (this);
697 select_record *s = ss->start.next;
698 s->startup = start_thread_pipe;
700 s->verify = verify_ok;
701 s->cleanup = pipe_cleanup;
702 s->read_selected = true;
703 s->read_ready = false;
708 fhandler_pipe::select_write (select_stuff *ss)
710 if (!ss->device_specific_pipe
711 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
713 ss->device_specific_pipe->add_watch_handle (this);
714 select_record *s = ss->start.next;
715 s->startup = start_thread_pipe;
717 s->verify = verify_ok;
718 s->cleanup = pipe_cleanup;
719 s->write_selected = true;
720 s->write_ready = false;
725 fhandler_pipe::select_except (select_stuff *ss)
727 if (!ss->device_specific_pipe
728 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
730 ss->device_specific_pipe->add_watch_handle (this);
731 select_record *s = ss->start.next;
732 s->startup = start_thread_pipe;
734 s->verify = verify_ok;
735 s->cleanup = pipe_cleanup;
736 s->except_selected = true;
737 s->except_ready = false;
742 fhandler_fifo::select_read (select_stuff *ss)
744 select_record *s = ss->start.next;
745 s->startup = start_thread_pipe;
747 s->verify = verify_ok;
748 s->cleanup = pipe_cleanup;
749 s->read_selected = true;
750 s->read_ready = false;
755 fhandler_fifo::select_write (select_stuff *ss)
757 select_record *s = ss->start.next;
758 s->startup = start_thread_pipe;
760 s->verify = verify_ok;
761 s->cleanup = pipe_cleanup;
762 s->write_selected = true;
763 s->write_ready = false;
768 fhandler_fifo::select_except (select_stuff *ss)
770 select_record *s = ss->start.next;
771 s->startup = start_thread_pipe;
773 s->verify = verify_ok;
774 s->cleanup = pipe_cleanup;
775 s->except_selected = true;
776 s->except_ready = false;
781 peek_console (select_record *me, bool)
783 extern const char * get_nonascii_key (INPUT_RECORD& input_rec, char *);
784 fhandler_console *fh = (fhandler_console *) me->fh;
786 if (!me->read_selected)
787 return me->write_ready;
789 if (fh->get_readahead_valid ())
791 select_printf ("readahead");
792 return me->read_ready = true;
797 select_printf ("already ready");
805 set_handle_or_return_if_not_open (h, me);
808 if (fh->bg_check (SIGTTIN) <= bg_eof)
809 return me->read_ready = true;
810 else if (!PeekConsoleInput (h, &irec, 1, &events_read) || !events_read)
814 if (irec.EventType == KEY_EVENT)
816 if (irec.Event.KeyEvent.bKeyDown
817 && (irec.Event.KeyEvent.uChar.AsciiChar
818 || get_nonascii_key (irec, tmpbuf)))
819 return me->read_ready = true;
823 fh->send_winch_maybe ();
824 if (irec.EventType == MOUSE_EVENT
825 && fh->mouse_aware ()
826 && (irec.Event.MouseEvent.dwEventFlags == 0
827 || irec.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK))
828 return me->read_ready = true;
831 /* Read and discard the event */
832 ReadConsoleInput (h, &irec, 1, &events_read);
835 return me->write_ready;
839 verify_console (select_record *me, fd_set *rfds, fd_set *wfds,
842 return peek_console (me, true);
847 fhandler_console::select_read (select_stuff *ss)
849 select_record *s = ss->start.next;
852 s->startup = no_startup;
853 s->verify = verify_console;
857 s->peek = peek_console;
858 s->h = get_handle ();
859 s->read_selected = true;
860 s->read_ready = false;
865 fhandler_console::select_write (select_stuff *ss)
867 select_record *s = ss->start.next;
870 s->startup = no_startup;
871 s->verify = no_verify;
875 s->peek = peek_console;
876 s->write_selected = true;
877 s->write_ready = true;
882 fhandler_console::select_except (select_stuff *ss)
884 select_record *s = ss->start.next;
887 s->startup = no_startup;
888 s->verify = no_verify;
892 s->peek = peek_console;
893 s->except_selected = true;
894 s->except_ready = false;
899 fhandler_tty_common::select_read (select_stuff *ss)
901 return ((fhandler_pipe *) this)->fhandler_pipe::select_read (ss);
905 fhandler_tty_common::select_write (select_stuff *ss)
907 return ((fhandler_pipe *) this)->fhandler_pipe::select_write (ss);
911 fhandler_tty_common::select_except (select_stuff *ss)
913 return ((fhandler_pipe *) this)->fhandler_pipe::select_except (ss);
917 verify_tty_slave (select_record *me, fd_set *readfds, fd_set *writefds,
920 if (WaitForSingleObject (me->h, 0) == WAIT_OBJECT_0)
921 me->read_ready = true;
922 return set_bits (me, readfds, writefds, exceptfds);
926 fhandler_tty_slave::select_read (select_stuff *ss)
928 select_record *s = ss->start.next;
929 s->h = input_available_event;
930 s->startup = no_startup;
932 s->verify = verify_tty_slave;
933 s->read_selected = true;
934 s->read_ready = false;
940 fhandler_dev_null::select_read (select_stuff *ss)
942 select_record *s = ss->start.next;
945 s->startup = no_startup;
946 s->verify = no_verify;
948 s->h = get_handle ();
949 s->read_selected = true;
950 s->read_ready = true;
955 fhandler_dev_null::select_write (select_stuff *ss)
957 select_record *s = ss->start.next;
960 s->startup = no_startup;
961 s->verify = no_verify;
963 s->h = get_handle ();
964 s->write_selected = true;
965 s->write_ready = true;
970 fhandler_dev_null::select_except (select_stuff *ss)
972 select_record *s = ss->start.next;
975 s->startup = no_startup;
976 s->verify = no_verify;
978 s->h = get_handle ();
979 s->except_selected = true;
980 s->except_ready = false;
984 static int start_thread_serial (select_record *me, select_stuff *stuff);
987 peek_serial (select_record *s, bool)
991 fhandler_serial *fh = (fhandler_serial *) s->fh;
993 if (fh->get_readahead_valid () || fh->overlapped_armed < 0)
994 return s->read_ready = true;
996 select_printf ("fh->overlapped_armed %d", fh->overlapped_armed);
999 set_handle_or_return_if_not_open (h, s);
1002 if ((s->read_selected && s->read_ready) || (s->write_selected && s->write_ready))
1004 select_printf ("already ready");
1009 /* This is apparently necessary for the com0com driver.
1010 See: http://cygwin.com/ml/cygwin/2009-01/msg00667.html */
1013 SetCommMask (h, EV_RXCHAR);
1015 if (!fh->overlapped_armed)
1019 ResetEvent (fh->io_status.hEvent);
1021 if (!ClearCommError (h, &fh->ev, &st))
1023 debug_printf ("ClearCommError");
1026 else if (st.cbInQue)
1027 return s->read_ready = true;
1028 else if (WaitCommEvent (h, &fh->ev, &fh->io_status))
1029 return s->read_ready = true;
1030 else if (GetLastError () == ERROR_IO_PENDING)
1031 fh->overlapped_armed = 1;
1034 debug_printf ("WaitCommEvent");
1042 w4[0] = fh->io_status.hEvent;
1043 w4[1] = signal_arrived;
1046 switch (WaitForMultipleObjects (2, w4, FALSE, to))
1049 if (!ClearCommError (h, &fh->ev, &st))
1051 debug_printf ("ClearCommError");
1054 else if (!st.cbInQue)
1058 return s->read_ready = true;
1059 select_printf ("got something");
1062 case WAIT_OBJECT_0 + 1:
1063 select_printf ("interrupt");
1064 set_sig_errno (EINTR);
1070 debug_printf ("WaitForMultipleObjects");
1078 if (GetLastError () == ERROR_OPERATION_ABORTED)
1080 select_printf ("operation aborted");
1084 s->set_select_errno ();
1085 select_printf ("error %E");
1090 thread_serial (void *arg)
1092 select_serial_info *si = (select_serial_info *) arg;
1093 bool gotone = false;
1097 select_record *s = si->start;
1098 while ((s = s->next))
1099 if (s->startup == start_thread_serial)
1101 if (peek_serial (s, true))
1104 if (si->stop_thread)
1106 select_printf ("stopping");
1113 select_printf ("exiting");
1118 start_thread_serial (select_record *me, select_stuff *stuff)
1120 if (stuff->device_specific_serial)
1121 me->h = *((select_serial_info *) stuff->device_specific_serial)->thread;
1124 select_serial_info *si = new select_serial_info;
1125 si->start = &stuff->start;
1126 si->stop_thread = false;
1127 si->thread = new cygthread (thread_serial, 0, si, "select_serial");
1128 me->h = *si->thread;
1129 stuff->device_specific_serial = si;
1135 serial_cleanup (select_record *, select_stuff *stuff)
1137 select_serial_info *si = (select_serial_info *) stuff->device_specific_serial;
1138 if (si && si->thread)
1140 si->stop_thread = true;
1141 si->thread->detach ();
1143 stuff->device_specific_serial = NULL;
1148 fhandler_serial::select_read (select_stuff *ss)
1150 select_record *s = ss->start.next;
1153 s->startup = start_thread_serial;
1154 s->verify = verify_ok;
1155 s->cleanup = serial_cleanup;
1157 s->peek = peek_serial;
1158 s->read_selected = true;
1159 s->read_ready = false;
1164 fhandler_serial::select_write (select_stuff *ss)
1166 select_record *s = ss->start.next;
1169 s->startup = no_startup;
1170 s->verify = verify_ok;
1172 s->peek = peek_serial;
1173 s->h = get_handle ();
1174 s->write_selected = true;
1175 s->write_ready = true;
1180 fhandler_serial::select_except (select_stuff *ss)
1182 select_record *s = ss->start.next;
1185 s->startup = no_startup;
1186 s->verify = verify_ok;
1189 s->peek = peek_serial;
1190 s->except_selected = false; // Can't do this
1191 s->except_ready = false;
1196 fhandler_base::ready_for_read (int fd, DWORD howlong)
1201 fd_set *thisfd = allocfd_set (fd + 1);
1202 fd_set *dummy_writefds = allocfd_set (fd + 1);
1203 fd_set *dummy_exceptfds = allocfd_set (fd + 1);
1204 UNIX_FD_SET(fd, thisfd);
1206 if (!sel.test_and_set (fd, thisfd, dummy_writefds, dummy_exceptfds))
1207 select_printf ("aborting due to test_and_set error");
1210 select_record *me = sel.start.next;
1213 avail = me->read_ready ?: me->peek (me, false);
1215 if (fd >= 0 && cygheap->fdtab.not_open (fd))
1217 set_sig_errno (EBADF);
1222 if (howlong != INFINITE)
1225 set_sig_errno (EAGAIN);
1229 if (WaitForSingleObject (signal_arrived, avail ? 0 : 10) == WAIT_OBJECT_0)
1231 debug_printf ("interrupted");
1232 set_sig_errno (EINTR);
1239 select_printf ("read_ready %d, avail %d", sel.start.next->read_ready, avail);
1245 fhandler_base::select_read (select_stuff *ss)
1247 select_record *s = ss->start.next;
1250 s->startup = no_startup;
1251 s->verify = verify_ok;
1253 s->h = get_handle ();
1254 s->read_selected = true;
1255 s->read_ready = true;
1260 fhandler_base::select_write (select_stuff *ss)
1262 select_record *s = ss->start.next;
1265 s->startup = no_startup;
1266 s->verify = verify_ok;
1268 s->h = get_handle ();
1269 s->write_selected = true;
1270 s->write_ready = true;
1275 fhandler_base::select_except (select_stuff *ss)
1277 select_record *s = ss->start.next;
1280 s->startup = no_startup;
1281 s->verify = verify_ok;
1284 s->except_selected = true;
1285 s->except_ready = false;
1290 peek_socket (select_record *me, bool)
1292 fhandler_socket *fh = (fhandler_socket *) me->fh;
1294 /* Don't play with the settings again, unless having taken a deep look into
1295 Richard W. Stevens Network Programming book. Thank you. */
1296 long evt_mask = (me->read_selected ? (FD_READ | FD_ACCEPT | FD_CLOSE) : 0)
1297 | (me->write_selected ? (FD_WRITE | FD_CONNECT | FD_CLOSE) : 0)
1298 | (me->except_selected ? FD_OOB : 0);
1299 int ret = fh->evaluate_events (evt_mask, events, false);
1300 if (me->read_selected)
1301 me->read_ready |= ret || !!(events & (FD_READ | FD_ACCEPT | FD_CLOSE));
1302 if (me->write_selected)
1303 me->write_ready |= ret || !!(events & (FD_WRITE | FD_CONNECT | FD_CLOSE));
1304 if (me->except_selected)
1305 me->except_ready |= !!(events & FD_OOB);
1307 select_printf ("read_ready: %d, write_ready: %d, except_ready: %d",
1308 me->read_ready, me->write_ready, me->except_ready);
1309 return me->read_ready || me->write_ready || me->except_ready;
1312 static int start_thread_socket (select_record *, select_stuff *);
1315 thread_socket (void *arg)
1317 select_socket_info *si = (select_socket_info *) arg;
1318 DWORD timeout = 64 / (si->max_w4 / MAXIMUM_WAIT_OBJECTS);
1321 select_printf ("stuff_start %p", si->start);
1324 for (select_record *s = si->start; (s = s->next); )
1325 if (s->startup == start_thread_socket)
1326 if (peek_socket (s, false))
1329 for (int i = 0; i < si->max_w4; i += MAXIMUM_WAIT_OBJECTS)
1330 switch (WaitForMultipleObjects (min (si->num_w4 - i,
1331 MAXIMUM_WAIT_OBJECTS),
1332 si->w4 + i, FALSE, timeout))
1337 if (!i) /* Socket event set. */
1346 select_printf ("leaving thread_socket");
1351 start_thread_socket (select_record *me, select_stuff *stuff)
1353 select_socket_info *si;
1355 if ((si = (select_socket_info *) stuff->device_specific_socket))
1357 me->h = *si->thread;
1361 si = new select_socket_info;
1362 si->ser_num = (LONG *) malloc (MAXIMUM_WAIT_OBJECTS * sizeof (LONG));
1363 si->w4 = (HANDLE *) malloc (MAXIMUM_WAIT_OBJECTS * sizeof (HANDLE));
1364 if (!si->ser_num || !si->w4)
1366 si->max_w4 = MAXIMUM_WAIT_OBJECTS;
1367 select_record *s = &stuff->start;
1368 if (_my_tls.locals.select_sockevt != INVALID_HANDLE_VALUE)
1369 si->w4[0] = _my_tls.locals.select_sockevt;
1370 else if (!(si->w4[0] = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL)))
1373 _my_tls.locals.select_sockevt = si->w4[0];
1375 while ((s = s->next))
1376 if (s->startup == start_thread_socket)
1378 /* No event/socket should show up multiple times. Every socket
1379 is uniquely identified by its serial number in the global
1380 wsock_events record. */
1381 const LONG ser_num = ((fhandler_socket *) s->fh)->serial_number ();
1382 for (int i = 1; i < si->num_w4; ++i)
1383 if (si->ser_num[i] == ser_num)
1384 goto continue_outer_loop;
1385 if (si->num_w4 >= si->max_w4)
1387 LONG *nser = (LONG *) realloc (si->ser_num,
1388 (si->max_w4 + MAXIMUM_WAIT_OBJECTS)
1393 HANDLE *nw4 = (HANDLE *) realloc (si->w4,
1394 (si->max_w4 + MAXIMUM_WAIT_OBJECTS)
1399 si->max_w4 += MAXIMUM_WAIT_OBJECTS;
1401 si->ser_num[si->num_w4] = ser_num;
1402 si->w4[si->num_w4++] = ((fhandler_socket *) s->fh)->wsock_event ();
1403 continue_outer_loop:
1406 stuff->device_specific_socket = si;
1407 si->start = &stuff->start;
1408 select_printf ("stuff_start %p", &stuff->start);
1409 si->thread = new cygthread (thread_socket, 0, si, "select_socket");
1410 me->h = *si->thread;
1415 socket_cleanup (select_record *, select_stuff *stuff)
1417 select_socket_info *si = (select_socket_info *) stuff->device_specific_socket;
1418 select_printf ("si %p si->thread %p", si, si ? si->thread : NULL);
1419 if (si && si->thread)
1421 SetEvent (si->w4[0]);
1422 /* Wait for thread to go away */
1423 si->thread->detach ();
1424 ResetEvent (si->w4[0]);
1425 stuff->device_specific_socket = NULL;
1432 select_printf ("returning");
1436 fhandler_socket::select_read (select_stuff *ss)
1438 select_record *s = ss->start.next;
1441 s->startup = start_thread_socket;
1442 s->verify = verify_true;
1443 s->cleanup = socket_cleanup;
1445 s->peek = peek_socket;
1446 s->read_ready = saw_shutdown_read ();
1447 s->read_selected = true;
1452 fhandler_socket::select_write (select_stuff *ss)
1454 select_record *s = ss->start.next;
1457 s->startup = start_thread_socket;
1458 s->verify = verify_true;
1459 s->cleanup = socket_cleanup;
1461 s->peek = peek_socket;
1462 s->write_ready = saw_shutdown_write () || connect_state () == unconnected;
1463 s->write_selected = true;
1464 if (connect_state () != unconnected)
1466 s->except_ready = saw_shutdown_write () || saw_shutdown_read ();
1467 s->except_on_write = true;
1473 fhandler_socket::select_except (select_stuff *ss)
1475 select_record *s = ss->start.next;
1478 s->startup = start_thread_socket;
1479 s->verify = verify_true;
1480 s->cleanup = socket_cleanup;
1482 s->peek = peek_socket;
1483 /* FIXME: Is this right? Should these be used as criteria for except? */
1484 s->except_ready = saw_shutdown_write () || saw_shutdown_read ();
1485 s->except_selected = true;
1490 peek_windows (select_record *me, bool)
1494 set_handle_or_return_if_not_open (h, me);
1496 if (me->read_selected && me->read_ready)
1499 if (PeekMessage (&m, (HWND) h, 0, 0, PM_NOREMOVE))
1501 me->read_ready = true;
1502 select_printf ("window %d(%p) ready", me->fd, me->fh->get_handle ());
1506 select_printf ("window %d(%p) not ready", me->fd, me->fh->get_handle ());
1507 return me->write_ready;
1511 verify_windows (select_record *me, fd_set *rfds, fd_set *wfds,
1514 return peek_windows (me, true);
1518 fhandler_windows::select_read (select_stuff *ss)
1520 select_record *s = ss->start.next;
1523 s->startup = no_startup;
1525 s->verify = verify_windows;
1526 s->peek = peek_windows;
1527 s->read_selected = true;
1528 s->read_ready = false;
1529 s->h = get_handle ();
1530 s->windows_handle = true;
1535 fhandler_windows::select_write (select_stuff *ss)
1537 select_record *s = ss->start.next;
1540 s->startup = no_startup;
1541 s->verify = verify_ok;
1543 s->peek = peek_windows;
1544 s->h = get_handle ();
1545 s->write_selected = true;
1546 s->write_ready = true;
1547 s->windows_handle = true;
1552 fhandler_windows::select_except (select_stuff *ss)
1554 select_record *s = ss->start.next;
1557 s->startup = no_startup;
1558 s->verify = verify_ok;
1560 s->peek = peek_windows;
1561 s->h = get_handle ();
1562 s->except_selected = true;
1563 s->except_ready = false;
1564 s->windows_handle = true;
1569 peek_mailslot (select_record *me, bool)
1572 set_handle_or_return_if_not_open (h, me);
1574 if (me->read_selected && me->read_ready)
1577 if (!GetMailslotInfo (h, NULL, NULL, &msgcnt, NULL))
1579 select_printf ("mailslot %d(%p) error %E", me->fd, h);
1584 me->read_ready = true;
1585 select_printf ("mailslot %d(%p) ready", me->fd, h);
1588 select_printf ("mailslot %d(%p) not ready", me->fd, h);
1593 verify_mailslot (select_record *me, fd_set *rfds, fd_set *wfds,
1596 return peek_mailslot (me, true);
1599 static int start_thread_mailslot (select_record *me, select_stuff *stuff);
1602 thread_mailslot (void *arg)
1604 select_mailslot_info *mi = (select_mailslot_info *) arg;
1605 bool gotone = false;
1606 DWORD sleep_time = 0;
1610 select_record *s = mi->start;
1611 while ((s = s->next))
1612 if (s->startup == start_thread_mailslot)
1614 if (peek_mailslot (s, true))
1616 if (mi->stop_thread)
1618 select_printf ("stopping");
1622 /* Paranoid check */
1623 if (mi->stop_thread)
1625 select_printf ("stopping from outer loop");
1630 Sleep (sleep_time >> 3);
1631 if (sleep_time < 80)
1639 start_thread_mailslot (select_record *me, select_stuff *stuff)
1641 if (stuff->device_specific_mailslot)
1643 me->h = *((select_mailslot_info *) stuff->device_specific_mailslot)->thread;
1646 select_mailslot_info *mi = new select_mailslot_info;
1647 mi->start = &stuff->start;
1648 mi->stop_thread = false;
1649 mi->thread = new cygthread (thread_mailslot, 0, mi, "select_mailslot");
1650 me->h = *mi->thread;
1653 stuff->device_specific_mailslot = mi;
1658 mailslot_cleanup (select_record *, select_stuff *stuff)
1660 select_mailslot_info *mi = (select_mailslot_info *) stuff->device_specific_mailslot;
1661 if (mi && mi->thread)
1663 mi->stop_thread = true;
1664 mi->thread->detach ();
1666 stuff->device_specific_mailslot = NULL;
1671 fhandler_mailslot::select_read (select_stuff *ss)
1673 select_record *s = ss->start.next;
1674 s->startup = start_thread_mailslot;
1675 s->peek = peek_mailslot;
1676 s->verify = verify_mailslot;
1677 s->cleanup = mailslot_cleanup;
1678 s->read_selected = true;
1679 s->read_ready = false;