Cygwin: (mostly) drop NT4 and Samba < 3.0 support
[newlib-cygwin.git] / winsup / cygwin / select.cc
blob725aab90c7a6acfea1bca31acbad7992faeede0b
1 /* select.cc
3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
7 details. */
9 /* The following line means that the BSD socket definitions for
10 fd_set, FD_ISSET etc. are used in this file. */
12 #define __INSIDE_CYGWIN_NET__
14 #include "winsup.h"
15 #include <stdlib.h>
16 #include <sys/param.h>
17 #include "ntdll.h"
19 #define USE_SYS_TYPES_FD_SET
20 #include <winsock2.h>
21 #include <netdb.h>
22 #include "cygerrno.h"
23 #include "security.h"
24 #include "path.h"
25 #include "fhandler.h"
26 #include "select.h"
27 #include "dtable.h"
28 #include "cygheap.h"
29 #include "pinfo.h"
30 #include "sigproc.h"
31 #include "cygtls.h"
34 * All these defines below should be in sys/types.h
35 * but because of the includes above, they may not have
36 * been included. We create special UNIX_xxxx versions here.
39 #ifndef NBBY
40 #define NBBY 8 /* number of bits in a byte */
41 #endif /* NBBY */
44 * Select uses bit masks of file descriptors in longs.
45 * These macros manipulate such bit fields (the filesystem macros use chars).
46 * FD_SETSIZE may be defined by the user, but the default here
47 * should be >= NOFILE (param.h).
50 #define UNIX_NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */
51 #ifndef unix_howmany
52 #define unix_howmany(x,y) (((x)+((y)-1))/(y))
53 #endif
55 #define unix_fd_set fd_set
57 #define NULL_fd_set ((fd_set *) NULL)
58 #define sizeof_fd_set(n) \
59 ((size_t) (NULL_fd_set->fds_bits + unix_howmany ((n), UNIX_NFDBITS)))
60 #define UNIX_FD_SET(n, p) \
61 ((p)->fds_bits[(n)/UNIX_NFDBITS] |= (1L << ((n) % UNIX_NFDBITS)))
62 #define UNIX_FD_CLR(n, p) \
63 ((p)->fds_bits[(n)/UNIX_NFDBITS] &= ~(1L << ((n) % UNIX_NFDBITS)))
64 #define UNIX_FD_ISSET(n, p) \
65 ((p)->fds_bits[(n)/UNIX_NFDBITS] & (1L << ((n) % UNIX_NFDBITS)))
66 #define UNIX_FD_ZERO(p, n) \
67 memset ((caddr_t) (p), 0, sizeof_fd_set ((n)))
69 #define allocfd_set(n) ({\
70 size_t __sfds = sizeof_fd_set (n) + 8; \
71 void *__res = alloca (__sfds); \
72 memset (__res, 0, __sfds); \
73 (fd_set *) __res; \
76 #define set_handle_or_return_if_not_open(h, s) \
77 h = (s)->fh->get_handle (); \
78 if (cygheap->fdtab.not_open ((s)->fd)) \
79 { \
80 (s)->thread_errno = EBADF; \
81 return -1; \
84 static int select (int, fd_set *, fd_set *, fd_set *, LONGLONG);
86 /* The main select code. */
87 extern "C" int
88 pselect (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
89 const struct timespec *to, const sigset_t *set)
91 sigset_t oldset = _my_tls.sigmask;
93 __try
95 if (set)
96 set_signal_mask (_my_tls.sigmask, *set);
98 select_printf ("pselect (%d, %p, %p, %p, %p, %p)", maxfds, readfds, writefds, exceptfds, to, set);
100 pthread_testcancel ();
101 int res;
102 if (maxfds < 0)
104 set_errno (EINVAL);
105 res = -1;
107 else
109 /* Convert to microseconds or -1 if to == NULL */
110 LONGLONG us = to ? to->tv_sec * USPERSEC
111 + (to->tv_nsec + (NSPERSEC/USPERSEC) - 1)
112 / (NSPERSEC/USPERSEC)
113 : -1LL;
115 if (to)
116 select_printf ("to->tv_sec %ld, to->tv_nsec %ld, us %D", to->tv_sec, to->tv_nsec, us);
117 else
118 select_printf ("to NULL, us %D", us);
120 res = select (maxfds, readfds ?: allocfd_set (maxfds),
121 writefds ?: allocfd_set (maxfds),
122 exceptfds ?: allocfd_set (maxfds), us);
124 syscall_printf ("%R = select (%d, %p, %p, %p, %p)", res, maxfds, readfds,
125 writefds, exceptfds, to);
127 if (set)
128 set_signal_mask (_my_tls.sigmask, oldset);
129 return res;
131 __except (EFAULT) {}
132 __endtry
133 return -1;
136 /* select () is just a wrapper on pselect (). */
137 extern "C" int
138 cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
139 struct timeval *to)
141 struct timespec ts;
142 if (to)
144 ts.tv_sec = to->tv_sec;
145 ts.tv_nsec = to->tv_usec * 1000;
147 return pselect (maxfds, readfds, writefds, exceptfds,
148 to ? &ts : NULL, NULL);
151 /* This function is arbitrarily split out from cygwin_select to avoid odd
152 gcc issues with the use of allocfd_set and improper constructor handling
153 for the sel variable. */
154 static int
155 select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
156 LONGLONG us)
158 select_stuff::wait_states wait_state = select_stuff::select_set_zero;
159 int ret = 0;
161 /* Record the current time for later use. */
162 LONGLONG start_time = get_clock (CLOCK_REALTIME)->usecs ();
164 select_stuff sel;
165 sel.return_on_signal = 0;
167 /* Allocate fd_set structures to store incoming fd sets. */
168 fd_set *readfds_in = allocfd_set (maxfds);
169 fd_set *writefds_in = allocfd_set (maxfds);
170 fd_set *exceptfds_in = allocfd_set (maxfds);
171 memcpy (readfds_in, readfds, sizeof_fd_set (maxfds));
172 memcpy (writefds_in, writefds, sizeof_fd_set (maxfds));
173 memcpy (exceptfds_in, exceptfds, sizeof_fd_set (maxfds));
177 /* Build the select record per fd linked list and set state as
178 needed. */
179 for (int i = 0; i < maxfds; i++)
180 if (!sel.test_and_set (i, readfds_in, writefds_in, exceptfds_in))
182 select_printf ("aborting due to test_and_set error");
183 return -1; /* Invalid fd, maybe? */
185 select_printf ("sel.always_ready %d", sel.always_ready);
187 if (sel.always_ready || us == 0)
188 /* Catch any active fds via sel.poll () below */
189 wait_state = select_stuff::select_ok;
190 else
191 /* wait for an fd to become active or time out */
192 wait_state = sel.wait (readfds, writefds, exceptfds, us);
194 select_printf ("sel.wait returns %d", wait_state);
196 if (wait_state == select_stuff::select_ok)
198 UNIX_FD_ZERO (readfds, maxfds);
199 UNIX_FD_ZERO (writefds, maxfds);
200 UNIX_FD_ZERO (exceptfds, maxfds);
201 /* Set bit mask from sel records. This also sets ret to the
202 right value >= 0, matching the number of bits set in the
203 fds records. if ret is 0, continue to loop. */
204 ret = sel.poll (readfds, writefds, exceptfds);
205 if (ret < 0)
206 wait_state = select_stuff::select_signalled;
207 else if (!ret)
208 wait_state = select_stuff::select_set_zero;
210 /* Always clean up everything here. If we're looping then build it
211 all up again. */
212 sel.cleanup ();
213 sel.destroy ();
214 /* Check and recalculate timeout. */
215 if (us != -1LL && wait_state == select_stuff::select_set_zero)
217 select_printf ("recalculating us");
218 LONGLONG now = get_clock (CLOCK_REALTIME)->usecs ();
219 if (now >= (start_time + us))
221 select_printf ("timed out after verification");
222 /* Set descriptor bits to zero per POSIX. */
223 UNIX_FD_ZERO (readfds, maxfds);
224 UNIX_FD_ZERO (writefds, maxfds);
225 UNIX_FD_ZERO (exceptfds, maxfds);
226 wait_state = select_stuff::select_ok;
227 ret = 0;
229 else
231 us -= (now - start_time);
232 start_time = now;
233 select_printf ("us now %D", us);
237 while (wait_state == select_stuff::select_set_zero);
239 if (wait_state < select_stuff::select_ok)
240 ret = -1;
241 return ret;
244 /* Call cleanup functions for all inspected fds. Gets rid of any
245 executing threads. */
246 void
247 select_stuff::cleanup ()
249 select_record *s = &start;
251 select_printf ("calling cleanup routines");
252 while ((s = s->next))
253 if (s->cleanup)
255 s->cleanup (s, this);
256 s->cleanup = NULL;
260 /* Destroy all storage associated with select stuff. */
261 inline void
262 select_stuff::destroy ()
264 select_record *s;
265 select_record *snext = start.next;
267 select_printf ("deleting select records");
268 while ((s = snext))
270 snext = s->next;
271 delete s;
273 start.next = NULL;
276 select_stuff::~select_stuff ()
278 cleanup ();
279 destroy ();
282 #ifdef DEBUGGING
283 void
284 select_record::dump_select_record ()
286 select_printf ("fd %d, h %p, fh %p, thread_errno %d, windows_handle %p",
287 fd, h, fh, thread_errno, windows_handle);
288 select_printf ("read_ready %d, write_ready %d, except_ready %d",
289 read_ready, write_ready, except_ready);
290 select_printf ("read_selected %d, write_selected %d, except_selected %d, except_on_write %d",
291 read_selected, write_selected, except_selected, except_on_write);
293 select_printf ("startup %p, peek %p, verify %p cleanup %p, next %p",
294 startup, peek, verify, cleanup, next);
296 #endif /*DEBUGGING*/
298 /* Add a record to the select chain */
299 bool
300 select_stuff::test_and_set (int i, fd_set *readfds, fd_set *writefds,
301 fd_set *exceptfds)
303 if (!UNIX_FD_ISSET (i, readfds) && !UNIX_FD_ISSET (i, writefds)
304 && ! UNIX_FD_ISSET (i, exceptfds))
305 return true;
307 select_record *s = new select_record;
308 if (!s)
309 return false;
311 s->next = start.next;
312 start.next = s;
314 if (UNIX_FD_ISSET (i, readfds) && !cygheap->fdtab.select_read (i, this))
315 goto err;
316 if (UNIX_FD_ISSET (i, writefds) && !cygheap->fdtab.select_write (i, this))
317 goto err;
318 if (UNIX_FD_ISSET (i, exceptfds) && !cygheap->fdtab.select_except (i, this))
319 goto err; /* error */
321 if (s->read_ready || s->write_ready || s->except_ready)
322 always_ready = true;
324 if (s->windows_handle)
325 windows_used = true;
327 #ifdef DEBUGGING
328 s->dump_select_record ();
329 #endif
330 return true;
332 err:
333 start.next = s->next;
334 delete s;
335 return false;
338 /* The heart of select. Waits for an fd to do something interesting. */
339 select_stuff::wait_states
340 select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
341 LONGLONG us)
343 HANDLE w4[MAXIMUM_WAIT_OBJECTS];
344 select_record *s = &start;
345 DWORD m = 0, timer_idx = 0, cancel_idx = 0;
347 /* Always wait for signals. */
348 wait_signal_arrived here (w4[m++]);
350 /* Set a timeout, or not, for WMFO. */
351 DWORD wmfo_timeout = us ? INFINITE : 0;
353 /* Optionally wait for pthread cancellation. */
354 if ((w4[m] = pthread::get_cancel_event ()) != NULL)
355 cancel_idx = m++;
357 /* Loop through the select chain, starting up anything appropriate and
358 counting the number of active fds. */
359 DWORD startfds = m;
360 while ((s = s->next))
362 /* Make sure to leave space for the timer, if we have a finite timeout. */
363 if (m >= MAXIMUM_WAIT_OBJECTS - (us > 0LL ? 1 : 0))
365 set_sig_errno (EINVAL);
366 return select_error;
368 if (!s->startup (s, this))
370 s->set_select_errno ();
371 return select_error;
373 if (s->h != NULL)
375 for (DWORD i = startfds; i < m; i++)
376 if (w4[i] == s->h)
377 goto next_while;
378 w4[m++] = s->h;
380 next_while:;
383 /* Optionally create and set a waitable timer if a finite timeout has
384 been requested. Recycle cw_timer in the cygtls area so we only have
385 to create the timer once per thread. Since WFMO checks the handles
386 in order, we append the timer as last object, otherwise it's preferred
387 over actual events on the descriptors. */
388 HANDLE &wait_timer = _my_tls.locals.cw_timer;
389 if (us > 0LL)
391 NTSTATUS status;
392 if (!wait_timer)
394 status = NtCreateTimer (&wait_timer, TIMER_ALL_ACCESS, NULL,
395 NotificationTimer);
396 if (!NT_SUCCESS (status))
398 select_printf ("%y = NtCreateTimer ()\n", status);
399 return select_error;
402 LARGE_INTEGER ms_clock_ticks = { .QuadPart = -us * 10 };
403 status = NtSetTimer (wait_timer, &ms_clock_ticks, NULL, NULL, FALSE,
404 0, NULL);
405 if (!NT_SUCCESS (status))
407 select_printf ("%y = NtSetTimer (%D)\n",
408 status, ms_clock_ticks.QuadPart);
409 return select_error;
411 w4[m] = wait_timer;
412 timer_idx = m++;
415 debug_printf ("m %d, us %U, wmfo_timeout %d", m, us, wmfo_timeout);
417 DWORD wait_ret;
418 if (!windows_used)
419 wait_ret = WaitForMultipleObjects (m, w4, FALSE, wmfo_timeout);
420 else
421 /* Using MWMO_INPUTAVAILABLE is the officially supported solution for
422 the problem that the call to PeekMessage disarms the queue state
423 so that a subsequent MWFMO hangs, even if there are still messages
424 in the queue. */
425 wait_ret = MsgWaitForMultipleObjectsEx (m, w4, wmfo_timeout,
426 QS_ALLINPUT | QS_ALLPOSTMESSAGE,
427 MWMO_INPUTAVAILABLE);
428 select_printf ("wait_ret %d, m = %d. verifying", wait_ret, m);
430 if (timer_idx)
432 BOOLEAN current_state;
433 NtCancelTimer (wait_timer, &current_state);
436 wait_states res;
437 switch (wait_ret)
439 case WAIT_OBJECT_0:
440 select_printf ("signal received");
441 /* Need to get rid of everything when a signal occurs since we can't
442 be assured that a signal handler won't jump out of select entirely. */
443 cleanup ();
444 destroy ();
445 /* select() is always interrupted by a signal so set EINTR,
446 unconditionally, ignoring any SA_RESTART detection by
447 call_signal_handler(). */
448 _my_tls.call_signal_handler ();
449 set_sig_errno (EINTR);
450 res = select_signalled; /* Cause loop exit in cygwin_select */
451 break;
452 case WAIT_FAILED:
453 system_printf ("WaitForMultipleObjects failed, %E");
454 s = &start;
455 s->set_select_errno ();
456 res = select_error;
457 break;
458 case WAIT_TIMEOUT:
459 was_timeout:
460 select_printf ("timed out");
461 res = select_set_zero;
462 break;
463 case WAIT_OBJECT_0 + 1:
464 /* Cancel event? */
465 if (wait_ret == cancel_idx)
467 cleanup ();
468 destroy ();
469 pthread::static_cancel_self ();
470 /*NOTREACHED*/
472 fallthrough;
473 default:
474 /* Timer event? */
475 if (wait_ret == timer_idx)
476 goto was_timeout;
478 s = &start;
479 res = select_set_zero;
480 /* Some types of objects (e.g., consoles) wake up on "inappropriate"
481 events like mouse movements. The verify function will detect these
482 situations. If it returns false, then this wakeup was a false alarm
483 and we should go back to waiting. */
484 int ret = 0;
485 while ((s = s->next))
486 if (s->saw_error ())
488 set_errno (s->saw_error ());
489 res = select_error; /* Somebody detected an error */
490 goto out;
492 else if ((((wait_ret >= m && s->windows_handle)
493 || s->h == w4[wait_ret]))
494 && (ret = s->verify (s, readfds, writefds, exceptfds)) > 0)
495 res = select_ok;
496 else if (ret < 0)
498 res = select_signalled;
499 goto out;
502 select_printf ("res after verify %d", res);
503 break;
505 out:
506 select_printf ("returning %d", res);
507 return res;
510 static int
511 set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
512 fd_set *exceptfds)
514 int ready = 0;
515 fhandler_socket_wsock *sock;
516 select_printf ("me %p, testing fd %d (%s)", me, me->fd, me->fh->get_name ());
517 if (me->read_selected && me->read_ready)
519 UNIX_FD_SET (me->fd, readfds);
520 ready++;
522 if (me->write_selected && me->write_ready)
524 UNIX_FD_SET (me->fd, writefds);
525 if (me->except_on_write && (sock = me->fh->is_wsock_socket ()))
527 /* Set readfds entry in case of a failed connect. */
528 if (!me->read_ready && me->read_selected
529 && sock->connect_state () == connect_failed)
531 UNIX_FD_SET (me->fd, readfds);
532 ready++;
535 ready++;
537 if (me->except_selected && me->except_ready)
539 UNIX_FD_SET (me->fd, exceptfds);
540 ready++;
542 select_printf ("ready %d", ready);
543 return ready;
546 /* Poll every fd in the select chain. Set appropriate fd in mask. */
548 select_stuff::poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
550 int n = 0;
551 select_record *s = &start;
552 while ((s = s->next))
554 int ret = s->peek ? s->peek (s, true) : 1;
555 if (ret < 0)
556 return -1;
557 n += (ret > 0) ? set_bits (s, readfds, writefds, exceptfds) : 0;
559 return n;
562 static int
563 verify_true (select_record *, fd_set *, fd_set *, fd_set *)
565 return 1;
568 static int
569 verify_ok (select_record *me, fd_set *readfds, fd_set *writefds,
570 fd_set *exceptfds)
572 return set_bits (me, readfds, writefds, exceptfds);
575 static int
576 no_startup (select_record *, select_stuff *)
578 return 1;
581 static int
582 no_verify (select_record *, fd_set *, fd_set *, fd_set *)
584 return 0;
587 static int
588 pipe_data_available (int fd, fhandler_base *fh, HANDLE h, bool writing)
590 if (fh->get_device () == FH_PIPER)
592 DWORD nbytes_in_pipe;
593 if (!writing && PeekNamedPipe (h, NULL, 0, NULL, &nbytes_in_pipe, NULL))
594 return nbytes_in_pipe > 0;
595 return -1;
598 IO_STATUS_BLOCK iosb = {{0}, 0};
599 FILE_PIPE_LOCAL_INFORMATION fpli = {0};
600 NTSTATUS status;
602 status = NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
603 FilePipeLocalInformation);
604 if (!NT_SUCCESS (status))
606 /* If NtQueryInformationFile fails, optimistically assume the
607 pipe is writable. This could happen if we somehow
608 inherit a pipe that doesn't permit FILE_READ_ATTRIBUTES
609 access on the write end. */
610 select_printf ("fd %d, %s, NtQueryInformationFile failed, status %y",
611 fd, fh->get_name (), status);
612 return writing ? 1 : -1;
614 if (writing)
616 /* If there is anything available in the pipe buffer then signal
617 that. This means that a pipe could still block since you could
618 be trying to write more to the pipe than is available in the
619 buffer but that is the hazard of select().
621 Note that WriteQuotaAvailable is unreliable.
623 Usually WriteQuotaAvailable on the write side reflects the space
624 available in the inbound buffer on the read side. However, if a
625 pipe read is currently pending, WriteQuotaAvailable on the write side
626 is decremented by the number of bytes the read side is requesting.
627 So it's possible (even likely) that WriteQuotaAvailable is 0, even
628 if the inbound buffer on the read side is not full. This can lead to
629 a deadlock situation: The reader is waiting for data, but select
630 on the writer side assumes that no space is available in the read
631 side inbound buffer.
633 Consequentially, the only reliable information is available on the
634 read side, so fetch info from the read side via the pipe-specific
635 query handle. Use fpli.WriteQuotaAvailable as storage for the actual
636 interesting value, which is the InboundQuote on the write side,
637 decremented by the number of bytes of data in that buffer. */
638 /* Note: Do not use NtQueryInformationFile() for query_hdl because
639 NtQueryInformationFile() seems to interfere with reading pipes
640 in non-cygwin apps. Instead, use PeekNamedPipe() here. */
641 if (fh->get_device () == FH_PIPEW && fpli.WriteQuotaAvailable == 0)
643 HANDLE query_hdl = ((fhandler_pipe *) fh)->get_query_handle ();
644 if (!query_hdl)
645 query_hdl = ((fhandler_pipe *) fh)->temporary_query_hdl ();
646 if (!query_hdl)
647 return 1; /* We cannot know actual write pipe space. */
648 DWORD nbytes_in_pipe;
649 BOOL res =
650 PeekNamedPipe (query_hdl, NULL, 0, NULL, &nbytes_in_pipe, NULL);
651 if (!((fhandler_pipe *) fh)->get_query_handle ())
652 CloseHandle (query_hdl); /* Close temporary query_hdl */
653 if (!res)
654 return 1;
655 fpli.WriteQuotaAvailable = fpli.InboundQuota - nbytes_in_pipe;
657 if (fpli.WriteQuotaAvailable > 0)
659 paranoid_printf ("fd %d, %s, write: size %u, avail %u", fd,
660 fh->get_name (), fpli.InboundQuota,
661 fpli.WriteQuotaAvailable);
662 return 1;
664 /* TODO: Buffer really full or non-Cygwin reader? */
666 else if (fpli.ReadDataAvailable)
668 paranoid_printf ("fd %d, %s, read avail %u", fd, fh->get_name (),
669 fpli.ReadDataAvailable);
670 return 1;
672 if (fpli.NamedPipeState & FILE_PIPE_CLOSING_STATE)
673 return -1;
674 return 0;
677 static int
678 peek_pipe (select_record *s, bool from_select)
680 HANDLE h;
681 set_handle_or_return_if_not_open (h, s);
683 int gotone = 0;
684 fhandler_base *fh = (fhandler_base *) s->fh;
686 DWORD dev = fh->get_device ();
687 if (s->read_selected && dev != FH_PIPEW)
689 if (s->read_ready)
691 select_printf ("%s, already ready for read", fh->get_name ());
692 gotone = 1;
693 goto out;
696 switch (fh->get_major ())
698 case DEV_PTYM_MAJOR:
700 fhandler_pty_master *fhm = (fhandler_pty_master *) fh;
701 fhm->flush_to_slave ();
703 break;
704 default:
705 if (fh->get_readahead_valid ())
707 select_printf ("readahead");
708 gotone = s->read_ready = true;
709 goto out;
713 if (fh->bg_check (SIGTTIN, true) <= bg_eof)
715 gotone = s->read_ready = true;
716 goto out;
718 int n = pipe_data_available (s->fd, fh, h, false);
719 /* On PTY masters, check if input from the echo pipe is available. */
720 if (n == 0 && fh->get_echo_handle ())
721 n = pipe_data_available (s->fd, fh, fh->get_echo_handle (), false);
723 if (n < 0)
725 select_printf ("read: %s, n %d", fh->get_name (), n);
726 if (s->except_selected)
727 gotone += s->except_ready = true;
728 if (s->read_selected)
729 gotone += s->read_ready = true;
731 else if (n > 0)
733 select_printf ("read: %s, ready for read: avail %d", fh->get_name (), n);
734 gotone += s->read_ready = true;
736 if (!gotone && s->fh->hit_eof ())
738 select_printf ("read: %s, saw EOF", fh->get_name ());
739 if (s->except_selected)
740 gotone += s->except_ready = true;
741 if (s->read_selected)
742 gotone += s->read_ready = true;
746 out:
747 if (fh->get_major () == DEV_PTYM_MAJOR)
749 fhandler_pty_master *fhm = (fhandler_pty_master *) fh;
750 fhm->set_mask_flusho (s->read_ready);
752 h = fh->get_output_handle ();
753 if (s->write_selected && dev != FH_PIPER)
755 if (dev == FH_PIPEW && ((fhandler_pipe *) fh)->reader_closed ())
757 gotone += s->write_ready = true;
758 if (s->except_selected)
759 gotone += s->except_ready = true;
760 return gotone;
762 int n = pipe_data_available (s->fd, fh, h, true);
763 select_printf ("write: %s, n %d", fh->get_name (), n);
764 gotone += s->write_ready = n;
765 if (n < 0 && s->except_selected)
766 gotone += s->except_ready = true;
768 return gotone;
771 static int start_thread_pipe (select_record *me, select_stuff *stuff);
773 static DWORD
774 thread_pipe (void *arg)
776 select_pipe_info *pi = (select_pipe_info *) arg;
777 DWORD sleep_time = 0;
778 bool looping = true;
780 while (looping)
782 for (select_record *s = pi->start; (s = s->next); )
783 if (s->startup == start_thread_pipe)
785 if (peek_pipe (s, true))
786 looping = false;
787 if (pi->stop_thread)
789 select_printf ("stopping");
790 looping = false;
791 break;
794 if (!looping)
795 break;
796 cygwait (pi->bye, sleep_time >> 3);
797 if (sleep_time < 80)
798 ++sleep_time;
799 if (pi->stop_thread)
800 break;
802 return 0;
805 static int
806 start_thread_pipe (select_record *me, select_stuff *stuff)
808 select_pipe_info *pi = stuff->device_specific_pipe;
809 if (pi->start)
810 me->h = *((select_pipe_info *) stuff->device_specific_pipe)->thread;
811 else
813 pi->start = &stuff->start;
814 pi->stop_thread = false;
815 pi->bye = me->fh->get_select_sem ();
816 if (pi->bye)
817 DuplicateHandle (GetCurrentProcess (), pi->bye,
818 GetCurrentProcess (), &pi->bye,
819 0, 0, DUPLICATE_SAME_ACCESS);
820 else
821 pi->bye = CreateSemaphore (&sec_none_nih, 0, INT32_MAX, NULL);
822 pi->thread = new cygthread (thread_pipe, pi, "pipesel");
823 me->h = *pi->thread;
824 if (!me->h)
825 return 0;
827 return 1;
830 static void
831 pipe_cleanup (select_record *, select_stuff *stuff)
833 select_pipe_info *pi = (select_pipe_info *) stuff->device_specific_pipe;
834 if (!pi)
835 return;
836 if (pi->thread)
838 pi->stop_thread = true;
839 ReleaseSemaphore (pi->bye, get_obj_handle_count (pi->bye), NULL);
840 pi->thread->detach ();
841 CloseHandle (pi->bye);
843 delete pi;
844 stuff->device_specific_pipe = NULL;
847 select_record *
848 fhandler_pipe::select_read (select_stuff *ss)
850 if (!ss->device_specific_pipe
851 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
852 return NULL;
854 select_record *s = ss->start.next;
855 s->startup = start_thread_pipe;
856 s->peek = peek_pipe;
857 s->verify = verify_ok;
858 s->cleanup = pipe_cleanup;
859 s->read_selected = true;
860 s->read_ready = false;
861 return s;
864 select_record *
865 fhandler_pipe::select_write (select_stuff *ss)
867 if (!ss->device_specific_pipe
868 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
869 return NULL;
870 select_record *s = ss->start.next;
871 s->startup = start_thread_pipe;
872 s->peek = peek_pipe;
873 s->verify = verify_ok;
874 s->cleanup = pipe_cleanup;
875 s->write_selected = true;
876 s->write_ready = false;
877 return s;
880 select_record *
881 fhandler_pipe::select_except (select_stuff *ss)
883 if (!ss->device_specific_pipe
884 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
885 return NULL;
886 select_record *s = ss->start.next;
887 s->startup = start_thread_pipe;
888 s->peek = peek_pipe;
889 s->verify = verify_ok;
890 s->cleanup = pipe_cleanup;
891 s->except_selected = true;
892 s->except_ready = false;
893 return s;
896 static int
897 peek_fifo (select_record *s, bool from_select)
899 if (cygheap->fdtab.not_open (s->fd))
901 s->thread_errno = EBADF;
902 return -1;
905 int gotone = 0;
906 fhandler_fifo *fh = (fhandler_fifo *) s->fh;
908 if (s->read_selected)
910 if (s->read_ready)
912 select_printf ("%s, already ready for read", fh->get_name ());
913 gotone = 1;
914 goto out;
917 if (fh->get_readahead_valid ())
919 select_printf ("readahead");
920 gotone = s->read_ready = true;
921 goto out;
924 fh->reading_lock ();
925 if (fh->take_ownership (1) < 0)
927 fh->reading_unlock ();
928 goto out;
930 fh->fifo_client_lock ();
931 int nconnected = 0;
932 for (int i = 0; i < fh->get_nhandlers (); i++)
934 fifo_client_handler &fc = fh->get_fc_handler (i);
935 fifo_client_connect_state prev_state = fc.query_and_set_state ();
936 if (fc.get_state () >= fc_connected)
938 nconnected++;
939 if (prev_state == fc_listening)
940 /* The connection was not recorded by the fifo_reader_thread. */
941 fh->record_connection (fc, false);
942 if (fc.get_state () == fc_input_avail)
944 select_printf ("read: %s, ready for read", fh->get_name ());
945 fh->fifo_client_unlock ();
946 fh->reading_unlock ();
947 gotone += s->read_ready = true;
948 goto out;
952 fh->fifo_client_unlock ();
953 /* According to POSIX and the Linux man page, we're supposed to
954 report read ready if the FIFO is at EOF, i.e., if the pipe is
955 empty and there are no writers. But there seems to be an
956 undocumented exception, observed on Linux and other platforms
957 (https://cygwin.com/pipermail/cygwin/2022-September/252223.html):
958 If no writer has ever been opened, then we do not report read
959 ready. This can happen if a reader is opened with O_NONBLOCK
960 before any writers have opened. To be consistent with other
961 platforms, we use a special EOF test that returns false if
962 there's never been a writer opened. */
963 if (!nconnected && fh->select_hit_eof ())
965 select_printf ("read: %s, saw EOF", fh->get_name ());
966 gotone += s->read_ready = true;
967 if (s->except_selected)
968 gotone += s->except_ready = true;
970 fh->reading_unlock ();
972 out:
973 if (s->write_selected)
975 int n = pipe_data_available (s->fd, fh, fh->get_handle (), true);
976 select_printf ("write: %s, n %d", fh->get_name (), n);
977 gotone += s->write_ready = n;
978 if (n < 0 && s->except_selected)
979 gotone += s->except_ready = true;
981 return gotone;
984 static int start_thread_fifo (select_record *me, select_stuff *stuff);
986 static DWORD
987 thread_fifo (void *arg)
989 select_fifo_info *pi = (select_fifo_info *) arg;
990 DWORD sleep_time = 0;
991 bool looping = true;
993 while (looping)
995 for (select_record *s = pi->start; (s = s->next); )
996 if (s->startup == start_thread_fifo)
998 if (peek_fifo (s, true))
999 looping = false;
1000 if (pi->stop_thread)
1002 select_printf ("stopping");
1003 looping = false;
1004 break;
1007 if (!looping)
1008 break;
1009 cygwait (pi->bye, sleep_time >> 3);
1010 if (sleep_time < 80)
1011 ++sleep_time;
1012 if (pi->stop_thread)
1013 break;
1015 return 0;
1018 static int
1019 start_thread_fifo (select_record *me, select_stuff *stuff)
1021 select_fifo_info *pi = stuff->device_specific_fifo;
1022 if (pi->start)
1023 me->h = *((select_fifo_info *) stuff->device_specific_fifo)->thread;
1024 else
1026 pi->start = &stuff->start;
1027 pi->stop_thread = false;
1028 pi->bye = me->fh->get_select_sem ();
1029 if (pi->bye)
1030 DuplicateHandle (GetCurrentProcess (), pi->bye,
1031 GetCurrentProcess (), &pi->bye,
1032 0, 0, DUPLICATE_SAME_ACCESS);
1033 else
1034 pi->bye = CreateSemaphore (&sec_none_nih, 0, INT32_MAX, NULL);
1035 pi->thread = new cygthread (thread_fifo, pi, "fifosel");
1036 me->h = *pi->thread;
1037 if (!me->h)
1038 return 0;
1040 return 1;
1043 static void
1044 fifo_cleanup (select_record *, select_stuff *stuff)
1046 select_fifo_info *pi = (select_fifo_info *) stuff->device_specific_fifo;
1047 if (!pi)
1048 return;
1049 if (pi->thread)
1051 pi->stop_thread = true;
1052 ReleaseSemaphore (pi->bye, get_obj_handle_count (pi->bye), NULL);
1053 pi->thread->detach ();
1054 CloseHandle (pi->bye);
1056 delete pi;
1057 stuff->device_specific_fifo = NULL;
1060 select_record *
1061 fhandler_fifo::select_read (select_stuff *ss)
1063 if (!ss->device_specific_fifo
1064 && (ss->device_specific_fifo = new select_fifo_info) == NULL)
1065 return NULL;
1066 select_record *s = ss->start.next;
1067 s->startup = start_thread_fifo;
1068 s->peek = peek_fifo;
1069 s->verify = verify_ok;
1070 s->cleanup = fifo_cleanup;
1071 s->read_selected = true;
1072 s->read_ready = false;
1073 return s;
1076 select_record *
1077 fhandler_fifo::select_write (select_stuff *ss)
1079 if (!ss->device_specific_fifo
1080 && (ss->device_specific_fifo = new select_fifo_info) == NULL)
1081 return NULL;
1082 select_record *s = ss->start.next;
1083 s->startup = start_thread_fifo;
1084 s->peek = peek_fifo;
1085 s->verify = verify_ok;
1086 s->cleanup = fifo_cleanup;
1087 s->write_selected = true;
1088 s->write_ready = false;
1089 return s;
1092 select_record *
1093 fhandler_fifo::select_except (select_stuff *ss)
1095 if (!ss->device_specific_fifo
1096 && (ss->device_specific_fifo = new select_fifo_info) == NULL)
1097 return NULL;
1098 select_record *s = ss->start.next;
1099 s->startup = start_thread_fifo;
1100 s->peek = peek_fifo;
1101 s->verify = verify_ok;
1102 s->cleanup = fifo_cleanup;
1103 s->except_selected = true;
1104 s->except_ready = false;
1105 return s;
1108 static int
1109 peek_console (select_record *me, bool)
1111 fhandler_console *fh = (fhandler_console *) me->fh;
1113 if (!me->read_selected)
1114 return me->write_ready;
1116 if (fh->get_cons_readahead_valid ())
1117 return me->read_ready = true;
1119 if (fh->input_ready)
1120 return me->read_ready = true;
1122 if (me->read_ready)
1124 select_printf ("already ready");
1125 return 1;
1128 INPUT_RECORD irec;
1129 DWORD events_read;
1130 HANDLE h;
1131 set_handle_or_return_if_not_open (h, me);
1133 fh->acquire_input_mutex (mutex_timeout);
1134 while (!fh->input_ready && !fh->get_cons_readahead_valid ())
1136 if (fh->bg_check (SIGTTIN, true) <= bg_eof)
1138 fh->release_input_mutex ();
1139 return me->read_ready = true;
1141 else
1143 acquire_attach_mutex (mutex_timeout);
1144 DWORD resume_pid = fh->attach_console (fh->get_owner ());
1145 BOOL r = PeekConsoleInputW (h, &irec, 1, &events_read);
1146 fh->detach_console (resume_pid, fh->get_owner ());
1147 release_attach_mutex ();
1148 if (!r || !events_read)
1149 break;
1151 if (fhandler_console::input_winch == fh->process_input_message ()
1152 && global_sigs[SIGWINCH].sa_handler != SIG_IGN
1153 && global_sigs[SIGWINCH].sa_handler != SIG_DFL)
1155 set_sig_errno (EINTR);
1156 fh->release_input_mutex ();
1157 return -1;
1160 fh->release_input_mutex ();
1161 if (fh->input_ready || fh->get_cons_readahead_valid ())
1162 return me->read_ready = true;
1164 return me->write_ready;
1167 static int
1168 verify_console (select_record *me, fd_set *rfds, fd_set *wfds,
1169 fd_set *efds)
1171 return peek_console (me, true);
1174 static int console_startup (select_record *me, select_stuff *stuff);
1176 static DWORD
1177 thread_console (void *arg)
1179 select_console_info *ci = (select_console_info *) arg;
1180 DWORD sleep_time = 0;
1181 bool looping = true;
1183 while (looping)
1185 for (select_record *s = ci->start; (s = s->next); )
1186 if (s->startup == console_startup)
1188 if (peek_console (s, true))
1189 looping = false;
1190 if (ci->stop_thread)
1192 select_printf ("stopping");
1193 looping = false;
1194 break;
1197 if (!looping)
1198 break;
1199 cygwait (ci->bye, sleep_time >> 3);
1200 if (sleep_time < 80)
1201 ++sleep_time;
1202 if (ci->stop_thread)
1203 break;
1205 return 0;
1208 static int
1209 console_startup (select_record *me, select_stuff *stuff)
1211 select_console_info *ci = stuff->device_specific_console;
1212 if (ci->start)
1213 me->h = *(stuff->device_specific_console)->thread;
1214 else
1216 ci->start = &stuff->start;
1217 ci->stop_thread = false;
1218 ci->bye = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
1219 ci->thread = new cygthread (thread_console, ci, "conssel");
1220 me->h = *ci->thread;
1221 if (!me->h)
1222 return 0;
1224 return 1;
1227 static void
1228 console_cleanup (select_record *me, select_stuff *stuff)
1230 select_console_info *ci = stuff->device_specific_console;
1231 if (!ci)
1232 return;
1233 if (ci->thread)
1235 ci->stop_thread = true;
1236 SetEvent (ci->bye);
1237 ci->thread->detach ();
1238 CloseHandle (ci->bye);
1240 delete ci;
1241 stuff->device_specific_console = NULL;
1244 select_record *
1245 fhandler_console::select_read (select_stuff *ss)
1247 if (!ss->device_specific_console
1248 && (ss->device_specific_console = new select_console_info) == NULL)
1249 return NULL;
1251 select_record *s = ss->start.next;
1252 if (!s->startup)
1254 s->startup = console_startup;
1255 s->verify = verify_console;
1256 set_cursor_maybe ();
1259 s->peek = peek_console;
1260 s->read_selected = true;
1261 s->read_ready = input_ready || get_cons_readahead_valid ();
1262 s->cleanup = console_cleanup;
1263 return s;
1266 select_record *
1267 fhandler_console::select_write (select_stuff *ss)
1269 select_record *s = ss->start.next;
1270 if (!s->startup)
1272 s->startup = no_startup;
1273 s->verify = no_verify;
1274 set_cursor_maybe ();
1277 s->peek = peek_console;
1278 s->write_selected = true;
1279 s->write_ready = true;
1280 return s;
1283 select_record *
1284 fhandler_console::select_except (select_stuff *ss)
1286 select_record *s = ss->start.next;
1287 if (!s->startup)
1289 s->startup = no_startup;
1290 s->verify = no_verify;
1291 set_cursor_maybe ();
1294 s->peek = peek_console;
1295 s->except_selected = true;
1296 s->except_ready = false;
1297 return s;
1300 select_record *
1301 fhandler_pty_common::select_read (select_stuff *ss)
1303 if (!ss->device_specific_pipe
1304 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
1305 return NULL;
1307 select_record *s = ss->start.next;
1308 s->startup = start_thread_pipe;
1309 s->peek = peek_pipe;
1310 s->verify = verify_ok;
1311 s->cleanup = pipe_cleanup;
1312 s->read_selected = true;
1313 s->read_ready = false;
1314 return s;
1317 select_record *
1318 fhandler_pty_common::select_write (select_stuff *ss)
1320 if (!ss->device_specific_pipe
1321 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
1322 return NULL;
1323 select_record *s = ss->start.next;
1324 s->startup = start_thread_pipe;
1325 s->peek = peek_pipe;
1326 s->verify = verify_ok;
1327 s->cleanup = pipe_cleanup;
1328 s->write_selected = true;
1329 s->write_ready = false;
1330 return s;
1333 select_record *
1334 fhandler_pty_common::select_except (select_stuff *ss)
1336 if (!ss->device_specific_pipe
1337 && (ss->device_specific_pipe = new select_pipe_info) == NULL)
1338 return NULL;
1339 select_record *s = ss->start.next;
1340 s->startup = start_thread_pipe;
1341 s->peek = peek_pipe;
1342 s->verify = verify_ok;
1343 s->cleanup = pipe_cleanup;
1344 s->except_selected = true;
1345 s->except_ready = false;
1346 return s;
1349 static int
1350 verify_tty_slave (select_record *me, fd_set *readfds, fd_set *writefds,
1351 fd_set *exceptfds)
1353 fhandler_pty_slave *ptys = (fhandler_pty_slave *) me->fh;
1354 if (me->read_selected && IsEventSignalled (ptys->input_available_event))
1355 me->read_ready = true;
1356 return set_bits (me, readfds, writefds, exceptfds);
1359 static int
1360 peek_pty_slave (select_record *s, bool from_select)
1362 int gotone = 0;
1363 fhandler_base *fh = (fhandler_base *) s->fh;
1364 fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
1366 if (s->read_selected)
1368 if (s->read_ready)
1370 select_printf ("%s, already ready for read", fh->get_name ());
1371 gotone = 1;
1372 goto out;
1375 if (fh->bg_check (SIGTTIN, true) <= bg_eof)
1377 gotone = s->read_ready = true;
1378 goto out;
1381 if (IsEventSignalled (ptys->input_available_event))
1383 gotone = s->read_ready = true;
1384 goto out;
1387 if (!gotone && s->fh->hit_eof ())
1389 select_printf ("read: %s, saw EOF", fh->get_name ());
1390 if (s->except_selected)
1391 gotone += s->except_ready = true;
1392 if (s->read_selected)
1393 gotone += s->read_ready = true;
1397 out:
1398 HANDLE h = ptys->get_output_handle ();
1399 if (s->write_selected)
1401 int n = pipe_data_available (s->fd, fh, h, true);
1402 select_printf ("write: %s, n %d", fh->get_name (), n);
1403 gotone += s->write_ready = n;
1404 if (n < 0 && s->except_selected)
1405 gotone += s->except_ready = true;
1407 return gotone;
1410 static int pty_slave_startup (select_record *me, select_stuff *stuff);
1412 static DWORD
1413 thread_pty_slave (void *arg)
1415 select_pipe_info *pi = (select_pipe_info *) arg;
1416 DWORD sleep_time = 0;
1417 bool looping = true;
1419 while (looping)
1421 for (select_record *s = pi->start; (s = s->next); )
1422 if (s->startup == pty_slave_startup)
1424 if (peek_pty_slave (s, true))
1425 looping = false;
1426 if (pi->stop_thread)
1428 select_printf ("stopping");
1429 looping = false;
1430 break;
1433 if (!looping)
1434 break;
1435 cygwait (pi->bye, sleep_time >> 3);
1436 if (sleep_time < 80)
1437 ++sleep_time;
1438 if (pi->stop_thread)
1439 break;
1441 return 0;
1444 static int
1445 pty_slave_startup (select_record *me, select_stuff *stuff)
1447 fhandler_base *fh = (fhandler_base *) me->fh;
1448 fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
1449 if (me->read_selected)
1450 ptys->mask_switch_to_nat_pipe (true, true);
1452 select_pipe_info *pi = stuff->device_specific_ptys;
1453 if (pi->start)
1454 me->h = *((select_pipe_info *) stuff->device_specific_ptys)->thread;
1455 else
1457 pi->start = &stuff->start;
1458 pi->stop_thread = false;
1459 pi->bye = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
1460 pi->thread = new cygthread (thread_pty_slave, pi, "ptyssel");
1461 me->h = *pi->thread;
1462 if (!me->h)
1463 return 0;
1465 return 1;
1468 static void
1469 pty_slave_cleanup (select_record *me, select_stuff *stuff)
1471 fhandler_base *fh = (fhandler_base *) me->fh;
1472 fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
1473 select_pipe_info *pi = (select_pipe_info *) stuff->device_specific_ptys;
1474 if (!pi)
1475 return;
1476 if (me->read_selected && pi->start)
1477 ptys->mask_switch_to_nat_pipe (false, false);
1478 if (pi->thread)
1480 pi->stop_thread = true;
1481 SetEvent (pi->bye);
1482 pi->thread->detach ();
1483 CloseHandle (pi->bye);
1485 delete pi;
1486 stuff->device_specific_ptys = NULL;
1489 select_record *
1490 fhandler_pty_slave::select_read (select_stuff *ss)
1492 if (!ss->device_specific_ptys
1493 && (ss->device_specific_ptys = new select_pipe_info) == NULL)
1494 return NULL;
1495 select_record *s = ss->start.next;
1496 s->startup = pty_slave_startup;
1497 s->peek = peek_pty_slave;
1498 s->verify = verify_tty_slave;
1499 s->read_selected = true;
1500 s->read_ready = false;
1501 s->cleanup = pty_slave_cleanup;
1502 return s;
1505 select_record *
1506 fhandler_pty_slave::select_write (select_stuff *ss)
1508 if (!ss->device_specific_ptys
1509 && (ss->device_specific_ptys = new select_pipe_info) == NULL)
1510 return NULL;
1511 select_record *s = ss->start.next;
1512 s->startup = pty_slave_startup;
1513 s->peek = peek_pty_slave;
1514 s->verify = verify_tty_slave;
1515 s->write_selected = true;
1516 s->write_ready = false;
1517 s->cleanup = pty_slave_cleanup;
1518 return s;
1521 select_record *
1522 fhandler_pty_slave::select_except (select_stuff *ss)
1524 if (!ss->device_specific_ptys
1525 && (ss->device_specific_ptys = new select_pipe_info) == NULL)
1526 return NULL;
1527 select_record *s = ss->start.next;
1528 s->startup = pty_slave_startup;
1529 s->peek = peek_pty_slave;
1530 s->verify = verify_tty_slave;
1531 s->except_selected = true;
1532 s->except_ready = false;
1533 s->cleanup = pty_slave_cleanup;
1534 return s;
1537 select_record *
1538 fhandler_dev_null::select_read (select_stuff *ss)
1540 select_record *s = ss->start.next;
1541 if (!s->startup)
1543 s->startup = no_startup;
1544 s->verify = no_verify;
1546 s->h = get_handle ();
1547 s->read_selected = true;
1548 s->read_ready = true;
1549 return s;
1552 select_record *
1553 fhandler_dev_null::select_write (select_stuff *ss)
1555 select_record *s = ss->start.next;
1556 if (!s->startup)
1558 s->startup = no_startup;
1559 s->verify = no_verify;
1561 s->h = get_handle ();
1562 s->write_selected = true;
1563 s->write_ready = true;
1564 return s;
1567 select_record *
1568 fhandler_dev_null::select_except (select_stuff *ss)
1570 select_record *s = ss->start.next;
1571 if (!s->startup)
1573 s->startup = no_startup;
1574 s->verify = no_verify;
1576 s->h = get_handle ();
1577 s->except_selected = true;
1578 s->except_ready = false;
1579 return s;
1582 static int
1583 peek_serial (select_record *s, bool)
1585 HANDLE h;
1586 COMSTAT st;
1587 DWORD io_err;
1589 fhandler_serial *fh = (fhandler_serial *) s->fh;
1591 set_handle_or_return_if_not_open (h, s);
1593 if ((s->read_selected && s->read_ready)
1594 || (s->write_selected && s->write_ready))
1596 select_printf ("already ready");
1597 return true;
1600 if (fh->get_readahead_valid ())
1601 return s->read_ready = true;
1603 if (!ClearCommError (h, &io_err, &st))
1605 select_printf ("ClearCommError %E");
1606 goto err;
1608 if (st.cbInQue)
1609 return s->read_ready = true;
1611 return 0;
1613 err:
1614 if (GetLastError () == ERROR_OPERATION_ABORTED)
1616 select_printf ("operation aborted");
1617 return false;
1620 s->set_select_errno ();
1621 return -1;
1624 static void
1625 serial_read_cleanup (select_record *s, select_stuff *stuff)
1627 if (s->h)
1629 HANDLE h = ((fhandler_serial *) s->fh)->get_handle ();
1630 DWORD undefined;
1632 if (h)
1634 CancelIo (h);
1635 GetOverlappedResult (h, &s->fh_data_serial->ov, &undefined, TRUE);
1637 CloseHandle (s->fh_data_serial->ov.hEvent);
1638 delete s->fh_data_serial;
1642 static int
1643 verify_serial (select_record *me, fd_set *rfds, fd_set *wfds, fd_set *efds)
1645 return peek_serial (me, true);
1648 select_record *
1649 fhandler_serial::select_read (select_stuff *ss)
1651 COMSTAT st;
1652 DWORD io_err;
1654 select_record *s = ss->start.next;
1656 s->startup = no_startup;
1657 s->verify = verify_serial;
1658 s->cleanup = serial_read_cleanup;
1659 s->peek = peek_serial;
1660 s->read_selected = true;
1661 s->read_ready = false;
1663 s->fh_data_serial = new (fh_select_data_serial);
1664 s->fh_data_serial->ov.hEvent = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
1666 /* This is apparently necessary for the com0com driver.
1667 See: http://cygwin.com/ml/cygwin/2009-01/msg00667.html */
1668 SetCommMask (get_handle (), 0);
1669 SetCommMask (get_handle (), EV_RXCHAR);
1670 if (ClearCommError (get_handle (), &io_err, &st) && st.cbInQue)
1671 s->read_ready = true;
1672 else if (WaitCommEvent (get_handle (), &s->fh_data_serial->event,
1673 &s->fh_data_serial->ov))
1674 s->read_ready = true;
1675 else if (GetLastError () == ERROR_IO_PENDING)
1676 s->h = s->fh_data_serial->ov.hEvent;
1677 else
1678 select_printf ("WaitCommEvent %E");
1680 /* No overlapped operation? Destroy the helper struct */
1681 if (!s->h)
1683 CloseHandle (s->fh_data_serial->ov.hEvent);
1684 delete s->fh_data_serial;
1686 return s;
1689 select_record *
1690 fhandler_serial::select_write (select_stuff *ss)
1692 select_record *s = ss->start.next;
1694 s->startup = no_startup;
1695 s->verify = verify_serial;
1696 s->peek = peek_serial;
1697 s->write_selected = true;
1698 s->write_ready = true;
1699 return s;
1702 select_record *
1703 fhandler_serial::select_except (select_stuff *ss)
1705 select_record *s = ss->start.next;
1707 s->startup = no_startup;
1708 s->verify = verify_serial;
1709 s->peek = peek_serial;
1710 s->except_selected = false; // Can't do this
1711 s->except_ready = false;
1712 return s;
1715 select_record *
1716 fhandler_base::select_read (select_stuff *ss)
1718 select_record *s = ss->start.next;
1719 if (!s->startup)
1721 s->startup = no_startup;
1722 s->verify = verify_ok;
1724 s->h = get_handle ();
1725 s->read_selected = true;
1726 s->read_ready = true;
1727 return s;
1730 select_record *
1731 fhandler_base::select_write (select_stuff *ss)
1733 select_record *s = ss->start.next;
1734 if (!s->startup)
1736 s->startup = no_startup;
1737 s->verify = verify_ok;
1739 s->h = get_output_handle ();
1740 s->write_selected = true;
1741 s->write_ready = true;
1742 return s;
1745 select_record *
1746 fhandler_base::select_except (select_stuff *ss)
1748 select_record *s = ss->start.next;
1749 if (!s->startup)
1751 s->startup = no_startup;
1752 s->verify = verify_ok;
1754 s->h = NULL;
1755 s->except_selected = true;
1756 s->except_ready = false;
1757 return s;
1760 static int
1761 peek_socket (select_record *me, bool)
1763 fhandler_socket_wsock *fh = (fhandler_socket_wsock *) me->fh;
1764 long events;
1765 /* Don't play with the settings again, unless having taken a deep look into
1766 Richard W. Stevens Network Programming book and how these flags are
1767 defined in Winsock. Thank you. */
1768 long evt_mask = (me->read_selected ? (FD_READ | FD_ACCEPT | FD_CLOSE) : 0)
1769 | (me->write_selected ? (FD_WRITE | FD_CONNECT | FD_CLOSE) : 0)
1770 | (me->except_selected ? FD_OOB : 0);
1771 int ret = fh->evaluate_events (evt_mask, events, false);
1772 if (me->read_selected)
1773 me->read_ready |= ret || !!(events & (FD_READ | FD_ACCEPT | FD_CLOSE));
1774 if (me->write_selected)
1775 /* Don't check for FD_CLOSE here. Only an error case (ret == -1)
1776 will set ready for writing. */
1777 me->write_ready |= ret || !!(events & (FD_WRITE | FD_CONNECT));
1778 if (me->except_selected)
1779 me->except_ready |= !!(events & FD_OOB);
1781 select_printf ("read_ready: %d, write_ready: %d, except_ready: %d",
1782 me->read_ready, me->write_ready, me->except_ready);
1783 return me->read_ready || me->write_ready || me->except_ready;
1786 static int start_thread_socket (select_record *, select_stuff *);
1788 static DWORD
1789 thread_socket (void *arg)
1791 select_socket_info *si = (select_socket_info *) arg;
1792 DWORD timeout = (si->num_w4 <= MAXIMUM_WAIT_OBJECTS)
1793 ? INFINITE
1794 : (64 / (roundup2 (si->num_w4, MAXIMUM_WAIT_OBJECTS)
1795 / MAXIMUM_WAIT_OBJECTS));
1796 bool event = false;
1798 select_printf ("stuff_start %p, timeout %u", si->start, timeout);
1799 while (!event)
1801 for (select_record *s = si->start; (s = s->next); )
1802 if (s->startup == start_thread_socket)
1803 if (peek_socket (s, false))
1804 event = true;
1805 if (!event)
1806 for (int i = 0; i < si->num_w4; i += MAXIMUM_WAIT_OBJECTS)
1807 switch (WaitForMultipleObjects (MIN (si->num_w4 - i,
1808 MAXIMUM_WAIT_OBJECTS),
1809 si->w4 + i, FALSE, timeout))
1811 case WAIT_FAILED:
1812 goto out;
1813 case WAIT_TIMEOUT:
1814 continue;
1815 case WAIT_OBJECT_0:
1816 if (!i) /* Socket event set. */
1817 goto out;
1818 fallthrough;
1819 default:
1820 break;
1823 out:
1824 select_printf ("leaving thread_socket");
1825 return 0;
1828 static inline bool init_tls_select_info () __attribute__ ((always_inline));
1829 static inline bool
1830 init_tls_select_info ()
1832 if (!_my_tls.locals.select.sockevt)
1834 _my_tls.locals.select.sockevt = CreateEvent (&sec_none_nih, TRUE, FALSE,
1835 NULL);
1836 if (!_my_tls.locals.select.sockevt)
1837 return false;
1839 if (!_my_tls.locals.select.ser_num)
1841 _my_tls.locals.select.ser_num
1842 = (LONG *) malloc (MAXIMUM_WAIT_OBJECTS * sizeof (LONG));
1843 if (!_my_tls.locals.select.ser_num)
1844 return false;
1845 _my_tls.locals.select.w4
1846 = (HANDLE *) malloc (MAXIMUM_WAIT_OBJECTS * sizeof (HANDLE));
1847 if (!_my_tls.locals.select.w4)
1849 free (_my_tls.locals.select.ser_num);
1850 _my_tls.locals.select.ser_num = NULL;
1851 return false;
1853 _my_tls.locals.select.max_w4 = MAXIMUM_WAIT_OBJECTS;
1855 return true;
1858 static int
1859 start_thread_socket (select_record *me, select_stuff *stuff)
1861 select_socket_info *si;
1863 if ((si = (select_socket_info *) stuff->device_specific_socket))
1865 me->h = *si->thread;
1866 return 1;
1869 si = new select_socket_info;
1871 if (!init_tls_select_info ())
1873 delete si;
1874 return 0;
1877 si->ser_num = _my_tls.locals.select.ser_num;
1878 si->w4 = _my_tls.locals.select.w4;
1880 si->w4[0] = _my_tls.locals.select.sockevt;
1881 si->num_w4 = 1;
1883 select_record *s = &stuff->start;
1884 while ((s = s->next))
1885 if (s->startup == start_thread_socket)
1887 /* No event/socket should show up multiple times. Every socket
1888 is uniquely identified by its serial number in the global
1889 wsock_events record. */
1890 const LONG ser_num = ((fhandler_socket_wsock *) s->fh)->serial_number ();
1891 for (int i = 1; i < si->num_w4; ++i)
1892 if (si->ser_num[i] == ser_num)
1893 goto continue_outer_loop;
1894 if (si->num_w4 >= _my_tls.locals.select.max_w4)
1896 LONG *nser = (LONG *) realloc (si->ser_num,
1897 (_my_tls.locals.select.max_w4
1898 + MAXIMUM_WAIT_OBJECTS)
1899 * sizeof (LONG));
1900 if (!nser)
1902 delete si;
1903 return 0;
1905 _my_tls.locals.select.ser_num = si->ser_num = nser;
1906 HANDLE *nw4 = (HANDLE *) realloc (si->w4,
1907 (_my_tls.locals.select.max_w4
1908 + MAXIMUM_WAIT_OBJECTS)
1909 * sizeof (HANDLE));
1910 if (!nw4)
1912 delete si;
1913 return 0;
1915 _my_tls.locals.select.w4 = si->w4 = nw4;
1916 _my_tls.locals.select.max_w4 += MAXIMUM_WAIT_OBJECTS;
1918 si->ser_num[si->num_w4] = ser_num;
1919 si->w4[si->num_w4++] = ((fhandler_socket_wsock *) s->fh)->wsock_event ();
1920 continue_outer_loop:
1923 stuff->device_specific_socket = si;
1924 si->start = &stuff->start;
1925 select_printf ("stuff_start %p", &stuff->start);
1926 si->thread = new cygthread (thread_socket, si, "socksel");
1927 me->h = *si->thread;
1928 return 1;
1931 void
1932 socket_cleanup (select_record *, select_stuff *stuff)
1934 select_socket_info *si = (select_socket_info *) stuff->device_specific_socket;
1935 select_printf ("si %p si->thread %p", si, si ? si->thread : NULL);
1936 if (!si)
1937 return;
1938 if (si->thread)
1940 SetEvent (si->w4[0]);
1941 /* Wait for thread to go away */
1942 si->thread->detach ();
1943 ResetEvent (si->w4[0]);
1945 delete si;
1946 stuff->device_specific_socket = NULL;
1947 select_printf ("returning");
1950 select_record *
1951 fhandler_socket_wsock::select_read (select_stuff *ss)
1953 select_record *s = ss->start.next;
1954 if (!s->startup)
1956 s->startup = start_thread_socket;
1957 s->verify = verify_true;
1958 s->cleanup = socket_cleanup;
1960 s->peek = peek_socket;
1961 s->read_ready = saw_shutdown_read ();
1962 s->read_selected = true;
1963 return s;
1966 select_record *
1967 fhandler_socket_wsock::select_write (select_stuff *ss)
1969 select_record *s = ss->start.next;
1970 if (!s->startup)
1972 s->startup = start_thread_socket;
1973 s->verify = verify_true;
1974 s->cleanup = socket_cleanup;
1976 s->peek = peek_socket;
1977 s->write_ready = saw_shutdown_write () || connect_state () == unconnected;
1978 s->write_selected = true;
1979 if (connect_state () != unconnected)
1980 s->except_on_write = true;
1981 return s;
1984 select_record *
1985 fhandler_socket_wsock::select_except (select_stuff *ss)
1987 select_record *s = ss->start.next;
1988 if (!s->startup)
1990 s->startup = start_thread_socket;
1991 s->verify = verify_true;
1992 s->cleanup = socket_cleanup;
1994 s->peek = peek_socket;
1995 s->except_selected = true;
1996 return s;
1999 #ifdef __WITH_AF_UNIX
2001 select_record *
2002 fhandler_socket_unix::select_read (select_stuff *ss)
2004 select_record *s = ss->start.next;
2005 if (!s->startup)
2007 s->startup = no_startup;
2008 s->verify = verify_ok;
2010 s->h = get_handle ();
2011 s->read_selected = true;
2012 s->read_ready = true;
2013 return s;
2016 select_record *
2017 fhandler_socket_unix::select_write (select_stuff *ss)
2019 select_record *s = ss->start.next;
2020 if (!s->startup)
2022 s->startup = no_startup;
2023 s->verify = verify_ok;
2025 s->h = get_handle ();
2026 s->write_selected = true;
2027 s->write_ready = true;
2028 return s;
2031 select_record *
2032 fhandler_socket_unix::select_except (select_stuff *ss)
2034 select_record *s = ss->start.next;
2035 if (!s->startup)
2037 s->startup = no_startup;
2038 s->verify = verify_ok;
2040 s->h = NULL;
2041 s->except_selected = true;
2042 s->except_ready = false;
2043 return s;
2046 #endif /* __WITH_AF_UNIX */
2048 static int
2049 peek_windows (select_record *me, bool)
2051 MSG m;
2052 HANDLE h;
2053 set_handle_or_return_if_not_open (h, me);
2054 /* We need the hWnd value, not the io_handle. */
2055 h = ((fhandler_windows *) me->fh)->get_hwnd ();
2057 if (me->read_selected && me->read_ready)
2058 return 1;
2060 if (PeekMessageW (&m, (HWND) h, 0, 0, PM_NOREMOVE))
2062 me->read_ready = true;
2063 select_printf ("window %d(%p) ready", me->fd, h);
2064 return 1;
2067 select_printf ("window %d(%p) not ready", me->fd, h);
2068 return me->write_ready;
2071 static int
2072 verify_windows (select_record *me, fd_set *rfds, fd_set *wfds,
2073 fd_set *efds)
2075 return peek_windows (me, true);
2078 select_record *
2079 fhandler_windows::select_read (select_stuff *ss)
2081 select_record *s = ss->start.next;
2082 if (!s->startup)
2084 s->startup = no_startup;
2086 s->verify = verify_windows;
2087 s->peek = peek_windows;
2088 s->read_selected = true;
2089 s->read_ready = false;
2090 s->windows_handle = true;
2091 return s;
2094 select_record *
2095 fhandler_windows::select_write (select_stuff *ss)
2097 select_record *s = ss->start.next;
2098 if (!s->startup)
2100 s->startup = no_startup;
2101 s->verify = verify_ok;
2103 s->peek = peek_windows;
2104 s->write_selected = true;
2105 s->write_ready = true;
2106 s->windows_handle = true;
2107 return s;
2110 select_record *
2111 fhandler_windows::select_except (select_stuff *ss)
2113 select_record *s = ss->start.next;
2114 if (!s->startup)
2116 s->startup = no_startup;
2117 s->verify = verify_ok;
2119 s->peek = peek_windows;
2120 s->except_selected = true;
2121 s->except_ready = false;
2122 s->windows_handle = true;
2123 return s;
2126 static int
2127 peek_signalfd (select_record *me, bool)
2129 if (((fhandler_signalfd *) me->fh)->poll () == 0)
2131 select_printf ("signalfd %d ready", me->fd);
2132 me->read_ready = true;
2133 return 1;
2135 select_printf ("signalfd %d not ready", me->fd);
2136 return 0;
2139 static int
2140 verify_signalfd (select_record *me, fd_set *rfds, fd_set *wfds, fd_set *efds)
2142 return peek_signalfd (me, true);
2145 extern HANDLE my_pendingsigs_evt;
2147 select_record *
2148 fhandler_signalfd::select_read (select_stuff *stuff)
2150 select_record *s = stuff->start.next;
2151 if (!s->startup)
2153 s->startup = no_startup;
2154 s->verify = verify_signalfd;
2156 s->peek = peek_signalfd;
2157 s->h = my_pendingsigs_evt; /* wait_sig sets this if signal are pending */
2158 s->read_selected = true;
2159 s->read_ready = false;
2160 return s;
2163 select_record *
2164 fhandler_signalfd::select_write (select_stuff *stuff)
2166 select_record *s = stuff->start.next;
2167 if (!s->startup)
2169 s->startup = no_startup;
2170 s->verify = no_verify;
2172 s->peek = NULL;
2173 s->write_selected = false;
2174 s->write_ready = false;
2175 return s;
2178 select_record *
2179 fhandler_signalfd::select_except (select_stuff *stuff)
2181 select_record *s = stuff->start.next;
2182 if (!s->startup)
2184 s->startup = no_startup;
2185 s->verify = no_verify;
2187 s->peek = NULL;
2188 s->except_selected = false;
2189 s->except_ready = false;
2190 return s;
2193 static int
2194 peek_timerfd (select_record *me, bool)
2196 if (WaitForSingleObject (me->h, 0) == WAIT_OBJECT_0)
2198 select_printf ("timerfd %d ready", me->fd);
2199 me->read_ready = true;
2200 return 1;
2202 select_printf ("timerfd %d not ready", me->fd);
2203 return 0;
2206 static int
2207 verify_timerfd (select_record *me, fd_set *rfds, fd_set *wfds,
2208 fd_set *efds)
2210 return peek_timerfd (me, true);
2213 select_record *
2214 fhandler_timerfd::select_read (select_stuff *stuff)
2216 select_record *s = stuff->start.next;
2217 if (!s->startup)
2219 s->startup = no_startup;
2220 s->verify = verify_timerfd;
2222 s->h = get_timerfd_handle ();
2223 s->peek = peek_timerfd;
2224 s->read_selected = true;
2225 s->read_ready = false;
2226 return s;
2229 select_record *
2230 fhandler_timerfd::select_write (select_stuff *stuff)
2232 select_record *s = stuff->start.next;
2233 if (!s->startup)
2235 s->startup = no_startup;
2236 s->verify = no_verify;
2238 s->peek = NULL;
2239 s->write_selected = false;
2240 s->write_ready = false;
2241 return s;
2244 select_record *
2245 fhandler_timerfd::select_except (select_stuff *stuff)
2247 select_record *s = stuff->start.next;
2248 if (!s->startup)
2250 s->startup = no_startup;
2251 s->verify = no_verify;
2253 s->peek = NULL;
2254 s->except_selected = false;
2255 s->except_ready = false;
2256 return s;
2259 static int
2260 peek_dsp (select_record *s, bool from_select)
2262 int gotone = 0;
2263 fhandler_dev_dsp *fh = (fhandler_dev_dsp *)(fhandler_base *) s->fh;
2265 if (s->read_selected)
2266 if (s->read_ready || fh->read_ready ())
2267 gotone += s->read_ready = true;
2268 if (s->write_selected)
2269 if (s->write_ready || fh->write_ready ())
2270 gotone += s->write_ready = true;
2271 if (s->except_selected)
2272 if (s->except_ready || fh->is_closed ())
2273 gotone += s->except_ready = true;
2274 return gotone;
2277 static int start_thread_dsp (select_record *me, select_stuff *stuff);
2279 static DWORD
2280 thread_dsp (void *arg)
2282 select_dsp_info *di = (select_dsp_info *) arg;
2283 DWORD sleep_time = 0;
2284 bool looping = true;
2286 while (looping)
2288 for (select_record *s = di->start; (s = s->next); )
2289 if (s->startup == start_thread_dsp)
2291 if (peek_dsp (s, true))
2292 looping = false;
2293 if (di->stop_thread)
2295 select_printf ("stopping");
2296 looping = false;
2297 break;
2300 if (!looping)
2301 break;
2302 cygwait (di->bye, sleep_time >> 3);
2303 if (sleep_time < 80)
2304 ++sleep_time;
2305 if (di->stop_thread)
2306 break;
2308 return 0;
2311 static int
2312 start_thread_dsp (select_record *me, select_stuff *stuff)
2314 select_dsp_info *di = stuff->device_specific_dsp;
2315 if (di->start)
2316 me->h = *((select_dsp_info *) stuff->device_specific_dsp)->thread;
2317 else
2319 di->bye = me->fh->get_select_sem ();
2320 if (di->bye)
2321 DuplicateHandle (GetCurrentProcess (), di->bye,
2322 GetCurrentProcess (), &di->bye,
2323 0, 0, DUPLICATE_SAME_ACCESS);
2324 else
2325 di->bye = CreateSemaphore (&sec_none_nih, 0, INT32_MAX, NULL);
2326 di->start = &stuff->start;
2327 di->stop_thread = false;
2328 di->thread = new cygthread (thread_dsp, di, "dspsel");
2329 me->h = *di->thread;
2330 if (!me->h)
2331 return 0;
2333 return 1;
2336 static void
2337 dsp_cleanup (select_record *, select_stuff *stuff)
2339 select_dsp_info *di = (select_dsp_info *) stuff->device_specific_dsp;
2340 if (!di)
2341 return;
2342 if (di->thread)
2344 di->stop_thread = true;
2345 ReleaseSemaphore (di->bye, get_obj_handle_count (di->bye), NULL);
2346 di->thread->detach ();
2347 CloseHandle (di->bye);
2349 delete di;
2350 stuff->device_specific_dsp = NULL;
2353 select_record *
2354 fhandler_dev_dsp::select_read (select_stuff *stuff)
2356 if (!stuff->device_specific_dsp
2357 && (stuff->device_specific_dsp = new select_dsp_info) == NULL)
2358 return NULL;
2359 select_record *s = stuff->start.next;
2360 s->startup = start_thread_dsp;
2361 s->peek = peek_dsp;
2362 s->verify = verify_ok;
2363 s->cleanup = dsp_cleanup;
2364 s->read_selected = true;
2365 s->read_ready = false;
2366 return s;
2369 select_record *
2370 fhandler_dev_dsp::select_write (select_stuff *stuff)
2372 if (!stuff->device_specific_dsp
2373 && (stuff->device_specific_dsp = new select_dsp_info) == NULL)
2374 return NULL;
2375 select_record *s = stuff->start.next;
2376 s->startup = start_thread_dsp;
2377 s->peek = peek_dsp;
2378 s->verify = verify_ok;
2379 s->cleanup = dsp_cleanup;
2380 s->write_selected = true;
2381 s->write_ready = false;
2382 return s;
2385 select_record *
2386 fhandler_dev_dsp::select_except (select_stuff *stuff)
2388 if (!stuff->device_specific_dsp
2389 && (stuff->device_specific_dsp = new select_dsp_info) == NULL)
2390 return NULL;
2391 select_record *s = stuff->start.next;
2392 s->startup = start_thread_dsp;
2393 s->peek = peek_dsp;
2394 s->verify = verify_ok;
2395 s->cleanup = dsp_cleanup;
2396 s->except_selected = true;
2397 s->except_ready = false;
2398 return s;