3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006, 2007, 2008, 2009, 2010, 2011 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);
99 pthread_testcancel ();
102 readfds = dummy_readfds;
104 writefds = dummy_writefds;
106 exceptfds = dummy_exceptfds;
108 for (int i = 0; i < maxfds; i++)
109 if (!sel.test_and_set (i, readfds, writefds, exceptfds))
111 select_printf ("aborting due to test_and_set error");
112 return -1; /* Invalid fd, maybe? */
115 /* Convert to milliseconds or INFINITE if to == NULL */
116 DWORD ms = to ? (to->tv_sec * 1000) + (to->tv_usec / 1000) : INFINITE;
117 if (ms == 0 && to->tv_usec)
118 ms = 1; /* At least 1 ms granularity */
121 select_printf ("to->tv_sec %d, to->tv_usec %d, ms %d", to->tv_sec, to->tv_usec, ms);
123 select_printf ("to NULL, ms %x", ms);
125 select_printf ("sel.always_ready %d", sel.always_ready);
128 /* Allocate some fd_set structures using the number of fds as a guide. */
129 fd_set *r = allocfd_set (maxfds);
130 fd_set *w = allocfd_set (maxfds);
131 fd_set *e = allocfd_set (maxfds);
133 /* Degenerate case. No fds to wait for. Just wait. */
134 if (sel.start.next == NULL)
136 HANDLE w4[2] = { signal_arrived, pthread::get_cancel_event () };
137 DWORD cnt = w4[1] ? 2 : 1;
139 switch (WaitForMultipleObjects (cnt, w4, FALSE, ms))
142 select_printf ("signal received");
143 set_sig_errno (EINTR);
145 case WAIT_OBJECT_0 + 1:
147 pthread::static_cancel_self ();
154 else if (sel.always_ready || ms == 0)
155 /* Don't bother waiting. */;
156 else if ((timeout = sel.wait (r, w, e, ms) < 0))
157 return -1; /* some kind of error */
159 copyfd_set (readfds, r, maxfds);
160 copyfd_set (writefds, w, maxfds);
161 copyfd_set (exceptfds, e, maxfds);
162 return timeout ? 0 : sel.poll (readfds, writefds, exceptfds);
166 pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
167 const struct timespec *ts, const sigset_t *set)
170 sigset_t oldset = _my_tls.sigmask;
173 if (efault.faulted (EFAULT))
177 tv.tv_sec = ts->tv_sec;
178 tv.tv_usec = ts->tv_nsec / 1000;
181 set_signal_mask (*set, _my_tls.sigmask);
182 int ret = cygwin_select (maxfds, readfds, writefds, exceptfds,
185 set_signal_mask (oldset, _my_tls.sigmask);
189 /* Call cleanup functions for all inspected fds. Gets rid of any
190 executing threads. */
192 select_stuff::cleanup ()
194 select_record *s = &start;
196 select_printf ("calling cleanup routines");
197 while ((s = s->next))
200 s->cleanup (s, this);
205 /* Destroy all storage associated with select stuff. */
207 select_stuff::destroy ()
209 select_record *s = &start;
210 select_record *snext = start.next;
212 select_printf ("deleting select records");
220 select_stuff::~select_stuff ()
226 /* Add a record to the select chain */
228 select_stuff::test_and_set (int i, fd_set *readfds, fd_set *writefds,
231 if (!UNIX_FD_ISSET (i, readfds) && !UNIX_FD_ISSET (i, writefds)
232 && ! UNIX_FD_ISSET (i, exceptfds))
235 select_record *s = new select_record;
239 s->next = start.next;
242 if (UNIX_FD_ISSET (i, readfds) && !cygheap->fdtab.select_read (i, this))
244 if (UNIX_FD_ISSET (i, writefds) && !cygheap->fdtab.select_write (i, this))
246 if (UNIX_FD_ISSET (i, exceptfds) && !cygheap->fdtab.select_except (i, this))
247 goto err; /* error */
249 if (s->read_ready || s->write_ready || s->except_ready)
252 if (s->windows_handle)
258 start.next = s->next;
263 /* The heart of select. Waits for an fd to do something interesting. */
265 select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
269 HANDLE w4[MAXIMUM_WAIT_OBJECTS];
270 select_record *s = &start;
273 bool is_cancelable = false;
275 w4[m++] = signal_arrived; /* Always wait for the arrival of a signal. */
276 if ((w4[m] = pthread::get_cancel_event ()) != NULL)
279 is_cancelable = true;
282 /* Loop through the select chain, starting up anything appropriate and
283 counting the number of active fds. */
284 while ((s = s->next))
286 if (m >= MAXIMUM_WAIT_OBJECTS)
288 set_sig_errno (EINVAL);
291 if (!s->startup (s, this))
293 s->set_select_errno ();
298 for (int i = 1; i < m; i++)
306 LONGLONG start_time = gtod.msecs (); /* Record the current time for later use. */
308 debug_printf ("m %d, ms %u", m, ms);
312 wait_ret = WaitForMultipleObjectsEx (m, w4, FALSE, ms, true);
314 /* Using MWMO_INPUTAVAILABLE is the officially supported solution for
315 the problem that the call to PeekMessage disarms the queue state
316 so that a subsequent MWFMO hangs, even if there are still messages
318 wait_ret = MsgWaitForMultipleObjectsEx (m, w4, ms,
319 QS_ALLINPUT | QS_ALLPOSTMESSAGE,
320 MWMO_INPUTAVAILABLE | MWMO_ALERTABLE);
324 case WAIT_IO_COMPLETION:
325 syscall_printf ("woke due to apc");
326 continue; /* Keep going */
330 select_printf ("signal received");
331 set_sig_errno (EINTR);
333 case WAIT_OBJECT_0 + 1:
338 pthread::static_cancel_self ();
343 system_printf ("WaitForMultipleObjects failed");
345 s->set_select_errno ();
349 select_printf ("timed out");
354 select_printf ("woke up. wait_ret %d. verifying", wait_ret);
357 /* Some types of objects (e.g., consoles) wake up on "inappropriate" events
358 like mouse movements. The verify function will detect these situations.
359 If it returns false, then this wakeup was a false alarm and we should go
361 while ((s = s->next))
365 set_errno (s->saw_error ());
366 return -1; /* Somebody detected an error */
368 else if ((((wait_ret >= m && s->windows_handle) || s->h == w4[wait_ret])) &&
369 s->verify (s, readfds, writefds, exceptfds))
372 select_printf ("gotone %d", gotone);
381 select_printf ("looping");
384 select_printf ("recalculating ms");
386 LONGLONG now = gtod.msecs ();
387 if (now > (start_time + ms))
390 select_printf ("timed out after verification");
393 ms -= (now - start_time);
395 select_printf ("ms now %u", ms);
399 select_printf ("returning %d", res);
404 set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
408 fhandler_socket *sock;
409 select_printf ("me %p, testing fd %d (%s)", me, me->fd, me->fh->get_name ());
410 if (me->read_selected && me->read_ready)
412 UNIX_FD_SET (me->fd, readfds);
415 if (me->write_selected && me->write_ready)
417 UNIX_FD_SET (me->fd, writefds);
418 if (me->except_on_write && (sock = me->fh->is_socket ()))
420 /* Special AF_LOCAL handling. */
421 if (!me->read_ready && sock->connect_state () == connect_pending
422 && sock->af_local_connect ())
424 if (me->read_selected)
425 UNIX_FD_SET (me->fd, readfds);
426 sock->connect_state (connect_failed);
429 sock->connect_state (connected);
433 if (me->except_selected && me->except_ready)
435 UNIX_FD_SET (me->fd, exceptfds);
438 select_printf ("ready %d", ready);
442 /* Poll every fd in the select chain. Set appropriate fd in mask. */
444 select_stuff::poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
447 select_record *s = &start;
448 while ((s = s->next))
449 n += (!s->peek || s->peek (s, true)) ?
450 set_bits (s, readfds, writefds, exceptfds) : 0;
451 select_printf ("returning %d", n);
456 verify_true (select_record *, fd_set *, fd_set *, fd_set *)
462 verify_ok (select_record *me, fd_set *readfds, fd_set *writefds,
465 return set_bits (me, readfds, writefds, exceptfds);
469 no_startup (select_record *, select_stuff *)
475 no_verify (select_record *, fd_set *, fd_set *, fd_set *)
481 pipe_data_available (int fd, fhandler_base *fh, HANDLE h, bool writing)
483 IO_STATUS_BLOCK iosb = {0};
484 FILE_PIPE_LOCAL_INFORMATION fpli = {0};
487 if (!fh->has_ongoing_io ())
489 if (NtQueryInformationFile (h,
493 FilePipeLocalInformation))
495 /* If NtQueryInformationFile fails, optimistically assume the
496 pipe is writable. This could happen if we somehow
497 inherit a pipe that doesn't permit FILE_READ_ATTRIBUTES
498 access on the write end. */
499 select_printf ("fd %d, %s, NtQueryInformationFile failed",
500 fd, fh->get_name ());
501 res = writing ? true : -1;
505 res = !!fpli.ReadDataAvailable;
506 paranoid_printf ("fd %d, %s, read avail %u", fd, fh->get_name (), fpli.ReadDataAvailable);
510 /* If there is anything available in the pipe buffer then signal
511 that. This means that a pipe could still block since you could
512 be trying to write more to the pipe than is available in the
513 buffer but that is the hazard of select(). */
514 if ((fpli.WriteQuotaAvailable = (fpli.OutboundQuota - fpli.ReadDataAvailable)))
516 paranoid_printf ("fd %d, %s, write: size %lu, avail %lu", fd,
517 fh->get_name (), fpli.OutboundQuota,
518 fpli.WriteQuotaAvailable);
521 /* If we somehow inherit a tiny pipe (size < PIPE_BUF), then consider
522 the pipe writable only if it is completely empty, to minimize the
523 probability that a subsequent write will block. */
524 else if (fpli.OutboundQuota < PIPE_BUF &&
525 fpli.WriteQuotaAvailable == fpli.OutboundQuota)
527 select_printf ("fd, %s, write tiny pipe: size %lu, avail %lu",
528 fd, fh->get_name (), fpli.OutboundQuota,
529 fpli.WriteQuotaAvailable);
534 return res ?: -!!(fpli.NamedPipeState & FILE_PIPE_CLOSING_STATE);
538 peek_pipe (select_record *s, bool from_select)
541 set_handle_or_return_if_not_open (h, s);
544 fhandler_base *fh = (fhandler_base *) s->fh;
546 DWORD dev = fh->get_device ();
547 if (s->read_selected && dev != FH_PIPEW)
551 select_printf ("%s, already ready for read", fh->get_name ());
556 switch (fh->get_major ())
559 if (((fhandler_pty_master *) fh)->need_nl)
561 gotone = s->read_ready = true;
566 if (fh->get_readahead_valid ())
568 select_printf ("readahead");
569 gotone = s->read_ready = true;
574 if (fh->bg_check (SIGTTIN) <= bg_eof)
576 gotone = s->read_ready = true;
579 int n = pipe_data_available (s->fd, fh, h, false);
583 select_printf ("read: %s, n %d", fh->get_name (), n);
584 if (s->except_selected)
585 gotone += s->except_ready = true;
586 if (s->read_selected)
587 gotone += s->read_ready = true;
591 select_printf ("read: %s, ready for read: avail %d", fh->get_name (), n);
592 gotone += s->read_ready = true;
594 if (!gotone && s->fh->hit_eof ())
596 select_printf ("read: %s, saw EOF", fh->get_name ());
597 if (s->except_selected)
598 gotone += s->except_ready = true;
599 if (s->read_selected)
600 gotone += s->read_ready = true;
605 if (s->write_selected && dev != FH_PIPER)
607 gotone += s->write_ready = pipe_data_available (s->fd, fh, h, true);
608 select_printf ("write: %s, gotone %d", fh->get_name (), gotone);
613 static int start_thread_pipe (select_record *me, select_stuff *stuff);
616 thread_pipe (void *arg)
618 select_pipe_info *pi = (select_pipe_info *) arg;
619 DWORD sleep_time = 0;
624 for (select_record *s = pi->start; (s = s->next); )
625 if (s->startup == start_thread_pipe)
627 if (peek_pipe (s, true))
631 select_printf ("stopping");
638 Sleep (sleep_time >> 3);
648 start_thread_pipe (select_record *me, select_stuff *stuff)
650 select_pipe_info *pi = stuff->device_specific_pipe;
652 me->h = *((select_pipe_info *) stuff->device_specific_pipe)->thread;
655 pi->start = &stuff->start;
656 pi->stop_thread = false;
657 pi->thread = new cygthread (thread_pipe, pi, "select_pipe");
666 pipe_cleanup (select_record *, select_stuff *stuff)
668 select_pipe_info *pi = (select_pipe_info *) stuff->device_specific_pipe;
673 pi->stop_thread = true;
674 pi->thread->detach ();
677 stuff->device_specific_pipe = NULL;
681 fhandler_pipe::select_read (select_stuff *ss)
683 if (!ss->device_specific_pipe
684 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
687 select_record *s = ss->start.next;
688 s->startup = start_thread_pipe;
690 s->verify = verify_ok;
691 s->cleanup = pipe_cleanup;
692 s->read_selected = true;
693 s->read_ready = false;
698 fhandler_pipe::select_write (select_stuff *ss)
700 if (!ss->device_specific_pipe
701 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
703 select_record *s = ss->start.next;
704 s->startup = start_thread_pipe;
706 s->verify = verify_ok;
707 s->cleanup = pipe_cleanup;
708 s->write_selected = true;
709 s->write_ready = false;
714 fhandler_pipe::select_except (select_stuff *ss)
716 if (!ss->device_specific_pipe
717 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
719 select_record *s = ss->start.next;
720 s->startup = start_thread_pipe;
722 s->verify = verify_ok;
723 s->cleanup = pipe_cleanup;
724 s->except_selected = true;
725 s->except_ready = false;
730 fhandler_fifo::select_read (select_stuff *ss)
732 if (!ss->device_specific_pipe
733 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
735 select_record *s = ss->start.next;
736 s->startup = start_thread_pipe;
738 s->verify = verify_ok;
739 s->cleanup = pipe_cleanup;
740 s->read_selected = true;
741 s->read_ready = false;
746 fhandler_fifo::select_write (select_stuff *ss)
748 if (!ss->device_specific_pipe
749 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
751 select_record *s = ss->start.next;
752 s->startup = start_thread_pipe;
754 s->verify = verify_ok;
755 s->cleanup = pipe_cleanup;
756 s->write_selected = true;
757 s->write_ready = false;
762 fhandler_fifo::select_except (select_stuff *ss)
764 if (!ss->device_specific_pipe
765 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
767 select_record *s = ss->start.next;
768 s->startup = start_thread_pipe;
770 s->verify = verify_ok;
771 s->cleanup = pipe_cleanup;
772 s->except_selected = true;
773 s->except_ready = false;
778 peek_console (select_record *me, bool)
780 extern const char * get_nonascii_key (INPUT_RECORD& input_rec, char *);
781 fhandler_console *fh = (fhandler_console *) me->fh;
783 if (!me->read_selected)
784 return me->write_ready;
786 if (fh->get_readahead_valid ())
788 select_printf ("readahead");
789 return me->read_ready = true;
794 select_printf ("already ready");
802 set_handle_or_return_if_not_open (h, me);
805 if (fh->bg_check (SIGTTIN) <= bg_eof)
806 return me->read_ready = true;
807 else if (!PeekConsoleInput (h, &irec, 1, &events_read) || !events_read)
811 fh->send_winch_maybe ();
812 if (irec.EventType == KEY_EVENT)
814 if (irec.Event.KeyEvent.bKeyDown
815 && (irec.Event.KeyEvent.uChar.AsciiChar
816 || get_nonascii_key (irec, tmpbuf)))
817 return me->read_ready = true;
821 if (irec.EventType == MOUSE_EVENT
822 && fh->mouse_aware (irec.Event.MouseEvent))
823 return me->read_ready = true;
824 if (irec.EventType == FOCUS_EVENT && fh->focus_aware ())
825 return me->read_ready = true;
828 /* Read and discard the event */
829 ReadConsoleInput (h, &irec, 1, &events_read);
832 return me->write_ready;
836 verify_console (select_record *me, fd_set *rfds, fd_set *wfds,
839 return peek_console (me, true);
844 fhandler_console::select_read (select_stuff *ss)
846 select_record *s = ss->start.next;
849 s->startup = no_startup;
850 s->verify = verify_console;
854 s->peek = peek_console;
855 s->h = get_handle ();
856 s->read_selected = true;
857 s->read_ready = false;
862 fhandler_console::select_write (select_stuff *ss)
864 select_record *s = ss->start.next;
867 s->startup = no_startup;
868 s->verify = no_verify;
872 s->peek = peek_console;
873 s->write_selected = true;
874 s->write_ready = true;
879 fhandler_console::select_except (select_stuff *ss)
881 select_record *s = ss->start.next;
884 s->startup = no_startup;
885 s->verify = no_verify;
889 s->peek = peek_console;
890 s->except_selected = true;
891 s->except_ready = false;
896 fhandler_pty_common::select_read (select_stuff *ss)
898 if (!ss->device_specific_pipe
899 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
902 select_record *s = ss->start.next;
903 s->startup = start_thread_pipe;
905 s->verify = verify_ok;
906 s->cleanup = pipe_cleanup;
907 s->read_selected = true;
908 s->read_ready = false;
913 fhandler_pty_common::select_write (select_stuff *ss)
915 if (!ss->device_specific_pipe
916 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
918 select_record *s = ss->start.next;
919 s->startup = start_thread_pipe;
921 s->verify = verify_ok;
922 s->cleanup = pipe_cleanup;
923 s->write_selected = true;
924 s->write_ready = false;
929 fhandler_pty_common::select_except (select_stuff *ss)
931 if (!ss->device_specific_pipe
932 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
934 select_record *s = ss->start.next;
935 s->startup = start_thread_pipe;
937 s->verify = verify_ok;
938 s->cleanup = pipe_cleanup;
939 s->except_selected = true;
940 s->except_ready = false;
945 verify_tty_slave (select_record *me, fd_set *readfds, fd_set *writefds,
948 if (IsEventSignalled (me->h))
949 me->read_ready = true;
950 return set_bits (me, readfds, writefds, exceptfds);
954 fhandler_pty_slave::select_read (select_stuff *ss)
956 select_record *s = ss->start.next;
957 s->h = input_available_event;
958 s->startup = no_startup;
960 s->verify = verify_tty_slave;
961 s->read_selected = true;
962 s->read_ready = false;
968 fhandler_dev_null::select_read (select_stuff *ss)
970 select_record *s = ss->start.next;
973 s->startup = no_startup;
974 s->verify = no_verify;
976 s->h = get_handle ();
977 s->read_selected = true;
978 s->read_ready = true;
983 fhandler_dev_null::select_write (select_stuff *ss)
985 select_record *s = ss->start.next;
988 s->startup = no_startup;
989 s->verify = no_verify;
991 s->h = get_handle ();
992 s->write_selected = true;
993 s->write_ready = true;
998 fhandler_dev_null::select_except (select_stuff *ss)
1000 select_record *s = ss->start.next;
1003 s->startup = no_startup;
1004 s->verify = no_verify;
1006 s->h = get_handle ();
1007 s->except_selected = true;
1008 s->except_ready = false;
1012 static int start_thread_serial (select_record *me, select_stuff *stuff);
1015 peek_serial (select_record *s, bool)
1019 fhandler_serial *fh = (fhandler_serial *) s->fh;
1021 if (fh->get_readahead_valid () || fh->overlapped_armed < 0)
1022 return s->read_ready = true;
1024 select_printf ("fh->overlapped_armed %d", fh->overlapped_armed);
1027 set_handle_or_return_if_not_open (h, s);
1030 if ((s->read_selected && s->read_ready) || (s->write_selected && s->write_ready))
1032 select_printf ("already ready");
1037 /* This is apparently necessary for the com0com driver.
1038 See: http://cygwin.com/ml/cygwin/2009-01/msg00667.html */
1041 SetCommMask (h, EV_RXCHAR);
1043 if (!fh->overlapped_armed)
1047 ResetEvent (fh->io_status.hEvent);
1049 if (!ClearCommError (h, &fh->ev, &st))
1051 debug_printf ("ClearCommError");
1054 else if (st.cbInQue)
1055 return s->read_ready = true;
1056 else if (WaitCommEvent (h, &fh->ev, &fh->io_status))
1057 return s->read_ready = true;
1058 else if (GetLastError () == ERROR_IO_PENDING)
1059 fh->overlapped_armed = 1;
1062 debug_printf ("WaitCommEvent");
1067 switch (WaitForSingleObject (fh->io_status.hEvent, 10L))
1070 if (!ClearCommError (h, &fh->ev, &st))
1072 debug_printf ("ClearCommError");
1075 else if (!st.cbInQue)
1079 return s->read_ready = true;
1080 select_printf ("got something");
1086 debug_printf ("WaitForMultipleObjects");
1094 if (GetLastError () == ERROR_OPERATION_ABORTED)
1096 select_printf ("operation aborted");
1100 s->set_select_errno ();
1101 select_printf ("error %E");
1106 thread_serial (void *arg)
1108 select_serial_info *si = (select_serial_info *) arg;
1109 bool looping = true;
1112 for (select_record *s = si->start; (s = s->next); )
1113 if (s->startup != start_thread_serial)
1117 if (peek_serial (s, true))
1119 if (si->stop_thread)
1121 select_printf ("stopping");
1127 select_printf ("exiting");
1132 start_thread_serial (select_record *me, select_stuff *stuff)
1134 if (stuff->device_specific_serial)
1135 me->h = *((select_serial_info *) stuff->device_specific_serial)->thread;
1138 select_serial_info *si = new select_serial_info;
1139 si->start = &stuff->start;
1140 si->stop_thread = false;
1141 si->thread = new cygthread (thread_serial, si, "select_serial");
1142 me->h = *si->thread;
1143 stuff->device_specific_serial = si;
1149 serial_cleanup (select_record *, select_stuff *stuff)
1151 select_serial_info *si = (select_serial_info *) stuff->device_specific_serial;
1156 si->stop_thread = true;
1157 si->thread->detach ();
1160 stuff->device_specific_serial = NULL;
1164 fhandler_serial::select_read (select_stuff *ss)
1166 select_record *s = ss->start.next;
1169 s->startup = start_thread_serial;
1170 s->verify = verify_ok;
1171 s->cleanup = serial_cleanup;
1173 s->peek = peek_serial;
1174 s->read_selected = true;
1175 s->read_ready = false;
1180 fhandler_serial::select_write (select_stuff *ss)
1182 select_record *s = ss->start.next;
1185 s->startup = no_startup;
1186 s->verify = verify_ok;
1188 s->peek = peek_serial;
1189 s->h = get_handle ();
1190 s->write_selected = true;
1191 s->write_ready = true;
1196 fhandler_serial::select_except (select_stuff *ss)
1198 select_record *s = ss->start.next;
1201 s->startup = no_startup;
1202 s->verify = verify_ok;
1205 s->peek = peek_serial;
1206 s->except_selected = false; // Can't do this
1207 s->except_ready = false;
1212 fhandler_base::select_read (select_stuff *ss)
1214 select_record *s = ss->start.next;
1217 s->startup = no_startup;
1218 s->verify = verify_ok;
1220 s->h = get_handle ();
1221 s->read_selected = true;
1222 s->read_ready = true;
1227 fhandler_base::select_write (select_stuff *ss)
1229 select_record *s = ss->start.next;
1232 s->startup = no_startup;
1233 s->verify = verify_ok;
1235 s->h = get_handle ();
1236 s->write_selected = true;
1237 s->write_ready = true;
1242 fhandler_base::select_except (select_stuff *ss)
1244 select_record *s = ss->start.next;
1247 s->startup = no_startup;
1248 s->verify = verify_ok;
1251 s->except_selected = true;
1252 s->except_ready = false;
1257 peek_socket (select_record *me, bool)
1259 fhandler_socket *fh = (fhandler_socket *) me->fh;
1261 /* Don't play with the settings again, unless having taken a deep look into
1262 Richard W. Stevens Network Programming book. Thank you. */
1263 long evt_mask = (me->read_selected ? (FD_READ | FD_ACCEPT | FD_CLOSE) : 0)
1264 | (me->write_selected ? (FD_WRITE | FD_CONNECT | FD_CLOSE) : 0)
1265 | (me->except_selected ? FD_OOB : 0);
1266 int ret = fh->evaluate_events (evt_mask, events, false);
1267 if (me->read_selected)
1268 me->read_ready |= ret || !!(events & (FD_READ | FD_ACCEPT | FD_CLOSE));
1269 if (me->write_selected)
1270 me->write_ready |= ret || !!(events & (FD_WRITE | FD_CONNECT | FD_CLOSE));
1271 if (me->except_selected)
1272 me->except_ready |= !!(events & FD_OOB);
1274 select_printf ("read_ready: %d, write_ready: %d, except_ready: %d",
1275 me->read_ready, me->write_ready, me->except_ready);
1276 return me->read_ready || me->write_ready || me->except_ready;
1279 static int start_thread_socket (select_record *, select_stuff *);
1282 thread_socket (void *arg)
1284 select_socket_info *si = (select_socket_info *) arg;
1285 DWORD timeout = (si->num_w4 <= MAXIMUM_WAIT_OBJECTS)
1287 : (64 / (roundup2 (si->num_w4, MAXIMUM_WAIT_OBJECTS)
1288 / MAXIMUM_WAIT_OBJECTS));
1291 select_printf ("stuff_start %p", si->start);
1294 for (select_record *s = si->start; (s = s->next); )
1295 if (s->startup == start_thread_socket)
1296 if (peek_socket (s, false))
1299 for (int i = 0; i < si->num_w4; i += MAXIMUM_WAIT_OBJECTS)
1300 switch (WaitForMultipleObjects (min (si->num_w4 - i,
1301 MAXIMUM_WAIT_OBJECTS),
1302 si->w4 + i, FALSE, timeout))
1309 if (!i) /* Socket event set. */
1317 select_printf ("leaving thread_socket");
1321 static inline bool init_tls_select_info () __attribute__ ((always_inline));
1323 init_tls_select_info ()
1325 if (!_my_tls.locals.select.sockevt)
1327 _my_tls.locals.select.sockevt = CreateEvent (&sec_none_nih, TRUE, FALSE,
1329 if (!_my_tls.locals.select.sockevt)
1332 if (!_my_tls.locals.select.ser_num)
1334 _my_tls.locals.select.ser_num
1335 = (LONG *) malloc (MAXIMUM_WAIT_OBJECTS * sizeof (LONG));
1336 if (!_my_tls.locals.select.ser_num)
1338 _my_tls.locals.select.w4
1339 = (HANDLE *) malloc (MAXIMUM_WAIT_OBJECTS * sizeof (HANDLE));
1340 if (!_my_tls.locals.select.w4)
1342 free (_my_tls.locals.select.ser_num);
1343 _my_tls.locals.select.ser_num = NULL;
1346 _my_tls.locals.select.max_w4 = MAXIMUM_WAIT_OBJECTS;
1352 start_thread_socket (select_record *me, select_stuff *stuff)
1354 select_socket_info *si;
1356 if ((si = (select_socket_info *) stuff->device_specific_socket))
1358 me->h = *si->thread;
1362 si = new select_socket_info;
1364 if (!init_tls_select_info ())
1367 si->ser_num = _my_tls.locals.select.ser_num;
1368 si->w4 = _my_tls.locals.select.w4;
1370 si->w4[0] = _my_tls.locals.select.sockevt;
1373 select_record *s = &stuff->start;
1374 while ((s = s->next))
1375 if (s->startup == start_thread_socket)
1377 /* No event/socket should show up multiple times. Every socket
1378 is uniquely identified by its serial number in the global
1379 wsock_events record. */
1380 const LONG ser_num = ((fhandler_socket *) s->fh)->serial_number ();
1381 for (int i = 1; i < si->num_w4; ++i)
1382 if (si->ser_num[i] == ser_num)
1383 goto continue_outer_loop;
1384 if (si->num_w4 >= _my_tls.locals.select.max_w4)
1386 LONG *nser = (LONG *) realloc (si->ser_num,
1387 (_my_tls.locals.select.max_w4
1388 + MAXIMUM_WAIT_OBJECTS)
1392 _my_tls.locals.select.ser_num = si->ser_num = nser;
1393 HANDLE *nw4 = (HANDLE *) realloc (si->w4,
1394 (_my_tls.locals.select.max_w4
1395 + MAXIMUM_WAIT_OBJECTS)
1399 _my_tls.locals.select.w4 = si->w4 = nw4;
1400 _my_tls.locals.select.max_w4 += MAXIMUM_WAIT_OBJECTS;
1402 si->ser_num[si->num_w4] = ser_num;
1403 si->w4[si->num_w4++] = ((fhandler_socket *) s->fh)->wsock_event ();
1404 continue_outer_loop:
1407 stuff->device_specific_socket = si;
1408 si->start = &stuff->start;
1409 select_printf ("stuff_start %p", &stuff->start);
1410 si->thread = new cygthread (thread_socket, si, "select_socket");
1411 me->h = *si->thread;
1416 socket_cleanup (select_record *, select_stuff *stuff)
1418 select_socket_info *si = (select_socket_info *) stuff->device_specific_socket;
1419 select_printf ("si %p si->thread %p", si, si ? si->thread : NULL);
1424 SetEvent (si->w4[0]);
1425 /* Wait for thread to go away */
1426 si->thread->detach ();
1427 ResetEvent (si->w4[0]);
1430 stuff->device_specific_socket = NULL;
1431 select_printf ("returning");
1435 fhandler_socket::select_read (select_stuff *ss)
1437 select_record *s = ss->start.next;
1440 s->startup = start_thread_socket;
1441 s->verify = verify_true;
1442 s->cleanup = socket_cleanup;
1444 s->peek = peek_socket;
1445 s->read_ready = saw_shutdown_read ();
1446 s->read_selected = true;
1451 fhandler_socket::select_write (select_stuff *ss)
1453 select_record *s = ss->start.next;
1456 s->startup = start_thread_socket;
1457 s->verify = verify_true;
1458 s->cleanup = socket_cleanup;
1460 s->peek = peek_socket;
1461 s->write_ready = saw_shutdown_write () || connect_state () == unconnected;
1462 s->write_selected = true;
1463 if (connect_state () != unconnected)
1465 s->except_ready = saw_shutdown_write () || saw_shutdown_read ();
1466 s->except_on_write = true;
1472 fhandler_socket::select_except (select_stuff *ss)
1474 select_record *s = ss->start.next;
1477 s->startup = start_thread_socket;
1478 s->verify = verify_true;
1479 s->cleanup = socket_cleanup;
1481 s->peek = peek_socket;
1482 /* FIXME: Is this right? Should these be used as criteria for except? */
1483 s->except_ready = saw_shutdown_write () || saw_shutdown_read ();
1484 s->except_selected = true;
1489 peek_windows (select_record *me, bool)
1493 set_handle_or_return_if_not_open (h, me);
1495 if (me->read_selected && me->read_ready)
1498 if (PeekMessageW (&m, (HWND) h, 0, 0, PM_NOREMOVE))
1500 me->read_ready = true;
1501 select_printf ("window %d(%p) ready", me->fd, me->fh->get_handle ());
1505 select_printf ("window %d(%p) not ready", me->fd, me->fh->get_handle ());
1506 return me->write_ready;
1510 verify_windows (select_record *me, fd_set *rfds, fd_set *wfds,
1513 return peek_windows (me, true);
1517 fhandler_windows::select_read (select_stuff *ss)
1519 select_record *s = ss->start.next;
1522 s->startup = no_startup;
1524 s->verify = verify_windows;
1525 s->peek = peek_windows;
1526 s->read_selected = true;
1527 s->read_ready = false;
1528 s->h = get_handle ();
1529 s->windows_handle = true;
1534 fhandler_windows::select_write (select_stuff *ss)
1536 select_record *s = ss->start.next;
1539 s->startup = no_startup;
1540 s->verify = verify_ok;
1542 s->peek = peek_windows;
1543 s->h = get_handle ();
1544 s->write_selected = true;
1545 s->write_ready = true;
1546 s->windows_handle = true;
1551 fhandler_windows::select_except (select_stuff *ss)
1553 select_record *s = ss->start.next;
1556 s->startup = no_startup;
1557 s->verify = verify_ok;
1559 s->peek = peek_windows;
1560 s->h = get_handle ();
1561 s->except_selected = true;
1562 s->except_ready = false;
1563 s->windows_handle = true;
1568 peek_mailslot (select_record *me, bool)
1571 set_handle_or_return_if_not_open (h, me);
1573 if (me->read_selected && me->read_ready)
1576 if (!GetMailslotInfo (h, NULL, NULL, &msgcnt, NULL))
1578 select_printf ("mailslot %d(%p) error %E", me->fd, h);
1583 me->read_ready = true;
1584 select_printf ("mailslot %d(%p) ready", me->fd, h);
1587 select_printf ("mailslot %d(%p) not ready", me->fd, h);
1592 verify_mailslot (select_record *me, fd_set *rfds, fd_set *wfds,
1595 return peek_mailslot (me, true);
1598 static int start_thread_mailslot (select_record *me, select_stuff *stuff);
1601 thread_mailslot (void *arg)
1603 select_mailslot_info *mi = (select_mailslot_info *) arg;
1604 bool gotone = false;
1605 DWORD sleep_time = 0;
1609 select_record *s = mi->start;
1610 while ((s = s->next))
1611 if (s->startup == start_thread_mailslot)
1613 if (peek_mailslot (s, true))
1615 if (mi->stop_thread)
1617 select_printf ("stopping");
1621 /* Paranoid check */
1622 if (mi->stop_thread)
1624 select_printf ("stopping from outer loop");
1629 Sleep (sleep_time >> 3);
1630 if (sleep_time < 80)
1638 start_thread_mailslot (select_record *me, select_stuff *stuff)
1640 if (stuff->device_specific_mailslot)
1642 me->h = *((select_mailslot_info *) stuff->device_specific_mailslot)->thread;
1645 select_mailslot_info *mi = new select_mailslot_info;
1646 mi->start = &stuff->start;
1647 mi->stop_thread = false;
1648 mi->thread = new cygthread (thread_mailslot, mi, "select_mailslot");
1649 me->h = *mi->thread;
1652 stuff->device_specific_mailslot = mi;
1657 mailslot_cleanup (select_record *, select_stuff *stuff)
1659 select_mailslot_info *mi = (select_mailslot_info *) stuff->device_specific_mailslot;
1664 mi->stop_thread = true;
1665 mi->thread->detach ();
1668 stuff->device_specific_mailslot = NULL;
1672 fhandler_mailslot::select_read (select_stuff *ss)
1674 select_record *s = ss->start.next;
1675 s->startup = start_thread_mailslot;
1676 s->peek = peek_mailslot;
1677 s->verify = verify_mailslot;
1678 s->cleanup = mailslot_cleanup;
1679 s->read_selected = true;
1680 s->read_ready = false;