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
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__
16 #include <sys/param.h>
19 #define USE_SYS_TYPES_FD_SET
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.
40 #define NBBY 8 /* number of bits in a byte */
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 */
52 #define unix_howmany(x,y) (((x)+((y)-1))/(y))
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); \
76 #define set_handle_or_return_if_not_open(h, s) \
77 h = (s)->fh->get_io_handle_cyg (); \
78 if (cygheap->fdtab.not_open ((s)->fd)) \
80 (s)->thread_errno = EBADF; \
84 static int select (int, fd_set
*, fd_set
*, fd_set
*, LONGLONG
);
86 /* The main select code. */
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
;
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 ();
109 /* Convert to microseconds or -1 if to == NULL */
110 LONGLONG us
= to
? to
->tv_sec
* 1000000LL + (to
->tv_nsec
+ 999) / 1000 : -1LL;
113 select_printf ("to->tv_sec %ld, to->tv_nsec %ld, us %D", to
->tv_sec
, to
->tv_nsec
, us
);
115 select_printf ("to NULL, us %D", us
);
117 res
= select (maxfds
, readfds
?: allocfd_set (maxfds
),
118 writefds
?: allocfd_set (maxfds
),
119 exceptfds
?: allocfd_set (maxfds
), us
);
121 syscall_printf ("%R = select (%d, %p, %p, %p, %p)", res
, maxfds
, readfds
,
122 writefds
, exceptfds
, to
);
125 set_signal_mask (_my_tls
.sigmask
, oldset
);
133 /* select () is just a wrapper on pselect (). */
135 cygwin_select (int maxfds
, fd_set
*readfds
, fd_set
*writefds
, fd_set
*exceptfds
,
141 ts
.tv_sec
= to
->tv_sec
;
142 ts
.tv_nsec
= to
->tv_usec
* 1000;
144 return pselect (maxfds
, readfds
, writefds
, exceptfds
,
145 to
? &ts
: NULL
, NULL
);
148 /* This function is arbitrarily split out from cygwin_select to avoid odd
149 gcc issues with the use of allocfd_set and improper constructor handling
150 for the sel variable. */
152 select (int maxfds
, fd_set
*readfds
, fd_set
*writefds
, fd_set
*exceptfds
,
155 select_stuff::wait_states wait_state
= select_stuff::select_set_zero
;
158 /* Record the current time for later use. */
159 LONGLONG start_time
= gtod
.usecs ();
162 sel
.return_on_signal
= 0;
164 /* Allocate some fd_set structures using the number of fds as a guide. */
165 fd_set
*r
= allocfd_set (maxfds
);
166 fd_set
*w
= allocfd_set (maxfds
);
167 fd_set
*e
= allocfd_set (maxfds
);
171 /* Build the select record per fd linked list and set state as
173 for (int i
= 0; i
< maxfds
; i
++)
174 if (!sel
.test_and_set (i
, readfds
, writefds
, exceptfds
))
176 select_printf ("aborting due to test_and_set error");
177 return -1; /* Invalid fd, maybe? */
179 select_printf ("sel.always_ready %d", sel
.always_ready
);
181 if (sel
.always_ready
|| us
== 0)
182 /* Catch any active fds via sel.poll () below */
183 wait_state
= select_stuff::select_ok
;
185 /* wait for an fd to become active or time out */
186 wait_state
= sel
.wait (r
, w
, e
, us
);
188 select_printf ("sel.wait returns %d", wait_state
);
190 if (wait_state
== select_stuff::select_ok
)
192 UNIX_FD_ZERO (readfds
, maxfds
);
193 UNIX_FD_ZERO (writefds
, maxfds
);
194 UNIX_FD_ZERO (exceptfds
, maxfds
);
195 /* Set bit mask from sel records. This also sets ret to the
196 right value >= 0, matching the number of bits set in the
197 fds records. if ret is 0, continue to loop. */
198 ret
= sel
.poll (readfds
, writefds
, exceptfds
);
200 wait_state
= select_stuff::select_set_zero
;
202 /* Always clean up everything here. If we're looping then build it
206 /* Check and recalculate timeout. */
207 if (us
!= -1LL && wait_state
== select_stuff::select_set_zero
)
209 select_printf ("recalculating us");
210 LONGLONG now
= gtod
.usecs ();
211 if (now
>= (start_time
+ us
))
213 select_printf ("timed out after verification");
214 /* Set descriptor bits to zero per POSIX. */
215 UNIX_FD_ZERO (readfds
, maxfds
);
216 UNIX_FD_ZERO (writefds
, maxfds
);
217 UNIX_FD_ZERO (exceptfds
, maxfds
);
218 wait_state
= select_stuff::select_ok
;
223 us
-= (now
- start_time
);
225 select_printf ("us now %D", us
);
229 while (wait_state
== select_stuff::select_set_zero
);
231 if (wait_state
< select_stuff::select_ok
)
236 /* Call cleanup functions for all inspected fds. Gets rid of any
237 executing threads. */
239 select_stuff::cleanup ()
241 select_record
*s
= &start
;
243 select_printf ("calling cleanup routines");
244 while ((s
= s
->next
))
247 s
->cleanup (s
, this);
252 /* Destroy all storage associated with select stuff. */
254 select_stuff::destroy ()
257 select_record
*snext
= start
.next
;
259 select_printf ("deleting select records");
268 select_stuff::~select_stuff ()
276 select_record::dump_select_record ()
278 select_printf ("fd %d, h %p, fh %p, thread_errno %d, windows_handle %p",
279 fd
, h
, fh
, thread_errno
, windows_handle
);
280 select_printf ("read_ready %d, write_ready %d, except_ready %d",
281 read_ready
, write_ready
, except_ready
);
282 select_printf ("read_selected %d, write_selected %d, except_selected %d, except_on_write %d",
283 read_selected
, write_selected
, except_selected
, except_on_write
);
285 select_printf ("startup %p, peek %p, verify %p cleanup %p, next %p",
286 startup
, peek
, verify
, cleanup
, next
);
290 /* Add a record to the select chain */
292 select_stuff::test_and_set (int i
, fd_set
*readfds
, fd_set
*writefds
,
295 if (!UNIX_FD_ISSET (i
, readfds
) && !UNIX_FD_ISSET (i
, writefds
)
296 && ! UNIX_FD_ISSET (i
, exceptfds
))
299 select_record
*s
= new select_record
;
303 s
->next
= start
.next
;
306 if (UNIX_FD_ISSET (i
, readfds
) && !cygheap
->fdtab
.select_read (i
, this))
308 if (UNIX_FD_ISSET (i
, writefds
) && !cygheap
->fdtab
.select_write (i
, this))
310 if (UNIX_FD_ISSET (i
, exceptfds
) && !cygheap
->fdtab
.select_except (i
, this))
311 goto err
; /* error */
313 if (s
->read_ready
|| s
->write_ready
|| s
->except_ready
)
316 if (s
->windows_handle
)
320 s
->dump_select_record ();
325 start
.next
= s
->next
;
330 /* The heart of select. Waits for an fd to do something interesting. */
331 select_stuff::wait_states
332 select_stuff::wait (fd_set
*readfds
, fd_set
*writefds
, fd_set
*exceptfds
,
335 HANDLE w4
[MAXIMUM_WAIT_OBJECTS
];
336 select_record
*s
= &start
;
337 DWORD m
= 0, timer_idx
= 0, cancel_idx
= 0;
339 /* Always wait for signals. */
340 wait_signal_arrived
here (w4
[m
++]);
342 /* Set a timeout, or not, for WMFO. */
343 DWORD wmfo_timeout
= us
? INFINITE
: 0;
345 /* Optionally wait for pthread cancellation. */
346 if ((w4
[m
] = pthread::get_cancel_event ()) != NULL
)
349 /* Loop through the select chain, starting up anything appropriate and
350 counting the number of active fds. */
352 while ((s
= s
->next
))
354 /* Make sure to leave space for the timer, if we have a finite timeout. */
355 if (m
>= MAXIMUM_WAIT_OBJECTS
- (us
> 0LL ? 1 : 0))
357 set_sig_errno (EINVAL
);
360 if (!s
->startup (s
, this))
362 s
->set_select_errno ();
367 for (DWORD i
= startfds
; i
< m
; i
++)
375 /* Optionally create and set a waitable timer if a finite timeout has
376 been requested. Recycle cw_timer in the cygtls area so we only have
377 to create the timer once per thread. Since WFMO checks the handles
378 in order, we append the timer as last object, otherwise it's preferred
379 over actual events on the descriptors. */
380 HANDLE
&wait_timer
= _my_tls
.locals
.cw_timer
;
386 status
= NtCreateTimer (&wait_timer
, TIMER_ALL_ACCESS
, NULL
,
388 if (!NT_SUCCESS (status
))
390 select_printf ("%y = NtCreateTimer ()\n", status
);
394 LARGE_INTEGER ms_clock_ticks
= { .QuadPart
= -us
* 10 };
395 status
= NtSetTimer (wait_timer
, &ms_clock_ticks
, NULL
, NULL
, FALSE
,
397 if (!NT_SUCCESS (status
))
399 select_printf ("%y = NtSetTimer (%D)\n",
400 status
, ms_clock_ticks
.QuadPart
);
407 debug_printf ("m %d, us %U, wmfo_timeout %d", m
, us
, wmfo_timeout
);
411 wait_ret
= WaitForMultipleObjects (m
, w4
, FALSE
, wmfo_timeout
);
413 /* Using MWMO_INPUTAVAILABLE is the officially supported solution for
414 the problem that the call to PeekMessage disarms the queue state
415 so that a subsequent MWFMO hangs, even if there are still messages
417 wait_ret
= MsgWaitForMultipleObjectsEx (m
, w4
, wmfo_timeout
,
418 QS_ALLINPUT
| QS_ALLPOSTMESSAGE
,
419 MWMO_INPUTAVAILABLE
);
420 select_printf ("wait_ret %d, m = %d. verifying", wait_ret
, m
);
424 BOOLEAN current_state
;
425 NtCancelTimer (wait_timer
, ¤t_state
);
432 select_printf ("signal received");
433 /* Need to get rid of everything when a signal occurs since we can't
434 be assured that a signal handler won't jump out of select entirely. */
437 /* select() is always interrupted by a signal so set EINTR,
438 unconditionally, ignoring any SA_RESTART detection by
439 call_signal_handler(). */
440 _my_tls
.call_signal_handler ();
441 set_sig_errno (EINTR
);
442 res
= select_signalled
; /* Cause loop exit in cygwin_select */
445 system_printf ("WaitForMultipleObjects failed, %E");
447 s
->set_select_errno ();
452 select_printf ("timed out");
453 res
= select_set_zero
;
455 case WAIT_OBJECT_0
+ 1:
457 if (wait_ret
== cancel_idx
)
461 pthread::static_cancel_self ();
467 if (wait_ret
== timer_idx
)
471 res
= select_set_zero
;
472 /* Some types of objects (e.g., consoles) wake up on "inappropriate"
473 events like mouse movements. The verify function will detect these
474 situations. If it returns false, then this wakeup was a false alarm
475 and we should go back to waiting. */
476 while ((s
= s
->next
))
479 set_errno (s
->saw_error ());
480 res
= select_error
; /* Somebody detected an error */
483 else if ((((wait_ret
>= m
&& s
->windows_handle
)
484 || s
->h
== w4
[wait_ret
]))
485 && s
->verify (s
, readfds
, writefds
, exceptfds
))
488 select_printf ("res after verify %d", res
);
492 select_printf ("returning %d", res
);
497 set_bits (select_record
*me
, fd_set
*readfds
, fd_set
*writefds
,
501 fhandler_socket
*sock
;
502 select_printf ("me %p, testing fd %d (%s)", me
, me
->fd
, me
->fh
->get_name ());
503 if (me
->read_selected
&& me
->read_ready
)
505 UNIX_FD_SET (me
->fd
, readfds
);
508 if (me
->write_selected
&& me
->write_ready
)
510 UNIX_FD_SET (me
->fd
, writefds
);
511 if (me
->except_on_write
&& (sock
= me
->fh
->is_socket ()))
513 /* Set readfds entry in case of a failed connect. */
514 if (!me
->read_ready
&& me
->read_selected
515 && sock
->connect_state () == connect_failed
)
516 UNIX_FD_SET (me
->fd
, readfds
);
520 if (me
->except_selected
&& me
->except_ready
)
522 UNIX_FD_SET (me
->fd
, exceptfds
);
525 select_printf ("ready %d", ready
);
529 /* Poll every fd in the select chain. Set appropriate fd in mask. */
531 select_stuff::poll (fd_set
*readfds
, fd_set
*writefds
, fd_set
*exceptfds
)
534 select_record
*s
= &start
;
535 while ((s
= s
->next
))
536 n
+= (!s
->peek
|| s
->peek (s
, true)) ?
537 set_bits (s
, readfds
, writefds
, exceptfds
) : 0;
542 verify_true (select_record
*, fd_set
*, fd_set
*, fd_set
*)
548 verify_ok (select_record
*me
, fd_set
*readfds
, fd_set
*writefds
,
551 return set_bits (me
, readfds
, writefds
, exceptfds
);
555 no_startup (select_record
*, select_stuff
*)
561 no_verify (select_record
*, fd_set
*, fd_set
*, fd_set
*)
567 pipe_data_available (int fd
, fhandler_base
*fh
, HANDLE h
, bool writing
)
569 IO_STATUS_BLOCK iosb
= {{0}, 0};
570 FILE_PIPE_LOCAL_INFORMATION fpli
= {0};
573 if (fh
->has_ongoing_io ())
576 status
= NtQueryInformationFile (h
, &iosb
, &fpli
, sizeof (fpli
),
577 FilePipeLocalInformation
);
578 if (!NT_SUCCESS (status
))
580 /* If NtQueryInformationFile fails, optimistically assume the
581 pipe is writable. This could happen if we somehow
582 inherit a pipe that doesn't permit FILE_READ_ATTRIBUTES
583 access on the write end. */
584 select_printf ("fd %d, %s, NtQueryInformationFile failed, status %y",
585 fd
, fh
->get_name (), status
);
586 return writing
? 1 : -1;
590 /* If there is anything available in the pipe buffer then signal
591 that. This means that a pipe could still block since you could
592 be trying to write more to the pipe than is available in the
593 buffer but that is the hazard of select(). */
594 fpli
.WriteQuotaAvailable
= fpli
.OutboundQuota
- fpli
.ReadDataAvailable
;
595 if (fpli
.WriteQuotaAvailable
> 0)
597 paranoid_printf ("fd %d, %s, write: size %u, avail %u", fd
,
598 fh
->get_name (), fpli
.OutboundQuota
,
599 fpli
.WriteQuotaAvailable
);
602 /* If we somehow inherit a tiny pipe (size < PIPE_BUF), then consider
603 the pipe writable only if it is completely empty, to minimize the
604 probability that a subsequent write will block. */
605 if (fpli
.OutboundQuota
< PIPE_BUF
606 && fpli
.WriteQuotaAvailable
== fpli
.OutboundQuota
)
608 select_printf ("fd, %s, write tiny pipe: size %u, avail %u",
609 fd
, fh
->get_name (), fpli
.OutboundQuota
,
610 fpli
.WriteQuotaAvailable
);
614 else if (fpli
.ReadDataAvailable
)
616 paranoid_printf ("fd %d, %s, read avail %u", fd
, fh
->get_name (),
617 fpli
.ReadDataAvailable
);
620 if (fpli
.NamedPipeState
& FILE_PIPE_CLOSING_STATE
)
626 peek_pipe (select_record
*s
, bool from_select
)
629 set_handle_or_return_if_not_open (h
, s
);
632 fhandler_base
*fh
= (fhandler_base
*) s
->fh
;
634 DWORD dev
= fh
->get_device ();
635 if (s
->read_selected
&& dev
!= FH_PIPEW
)
639 select_printf ("%s, already ready for read", fh
->get_name ());
644 switch (fh
->get_major ())
648 fhandler_pty_master
*fhm
= (fhandler_pty_master
*) fh
;
649 fhm
->flush_to_slave ();
653 if (fh
->get_readahead_valid ())
655 select_printf ("readahead");
656 gotone
= s
->read_ready
= true;
661 if (fh
->bg_check (SIGTTIN
, true) <= bg_eof
)
663 gotone
= s
->read_ready
= true;
666 int n
= pipe_data_available (s
->fd
, fh
, h
, false);
667 /* On PTY masters, check if input from the echo pipe is available. */
668 if (n
== 0 && fh
->get_echo_handle ())
669 n
= pipe_data_available (s
->fd
, fh
, fh
->get_echo_handle (), false);
673 select_printf ("read: %s, n %d", fh
->get_name (), n
);
674 if (s
->except_selected
)
675 gotone
+= s
->except_ready
= true;
676 if (s
->read_selected
)
677 gotone
+= s
->read_ready
= true;
681 select_printf ("read: %s, ready for read: avail %d", fh
->get_name (), n
);
682 gotone
+= s
->read_ready
= true;
684 if (!gotone
&& s
->fh
->hit_eof ())
686 select_printf ("read: %s, saw EOF", fh
->get_name ());
687 if (s
->except_selected
)
688 gotone
+= s
->except_ready
= true;
689 if (s
->read_selected
)
690 gotone
+= s
->read_ready
= true;
695 if (s
->write_selected
&& dev
!= FH_PIPER
)
697 gotone
+= s
->write_ready
= pipe_data_available (s
->fd
, fh
, h
, true);
698 select_printf ("write: %s, gotone %d", fh
->get_name (), gotone
);
703 static int start_thread_pipe (select_record
*me
, select_stuff
*stuff
);
706 thread_pipe (void *arg
)
708 select_pipe_info
*pi
= (select_pipe_info
*) arg
;
709 DWORD sleep_time
= 0;
714 for (select_record
*s
= pi
->start
; (s
= s
->next
); )
715 if (s
->startup
== start_thread_pipe
)
717 if (peek_pipe (s
, true))
721 select_printf ("stopping");
728 Sleep (sleep_time
>> 3);
738 start_thread_pipe (select_record
*me
, select_stuff
*stuff
)
740 select_pipe_info
*pi
= stuff
->device_specific_pipe
;
742 me
->h
= *((select_pipe_info
*) stuff
->device_specific_pipe
)->thread
;
745 pi
->start
= &stuff
->start
;
746 pi
->stop_thread
= false;
747 pi
->thread
= new cygthread (thread_pipe
, pi
, "pipesel");
756 pipe_cleanup (select_record
*, select_stuff
*stuff
)
758 select_pipe_info
*pi
= (select_pipe_info
*) stuff
->device_specific_pipe
;
763 pi
->stop_thread
= true;
764 pi
->thread
->detach ();
767 stuff
->device_specific_pipe
= NULL
;
771 fhandler_pipe::select_read (select_stuff
*ss
)
773 if (!ss
->device_specific_pipe
774 && (ss
->device_specific_pipe
= new select_pipe_info
) == NULL
)
777 select_record
*s
= ss
->start
.next
;
778 s
->startup
= start_thread_pipe
;
780 s
->verify
= verify_ok
;
781 s
->cleanup
= pipe_cleanup
;
782 s
->read_selected
= true;
783 s
->read_ready
= false;
788 fhandler_pipe::select_write (select_stuff
*ss
)
790 if (!ss
->device_specific_pipe
791 && (ss
->device_specific_pipe
= new select_pipe_info
) == NULL
)
793 select_record
*s
= ss
->start
.next
;
794 s
->startup
= start_thread_pipe
;
796 s
->verify
= verify_ok
;
797 s
->cleanup
= pipe_cleanup
;
798 s
->write_selected
= true;
799 s
->write_ready
= false;
804 fhandler_pipe::select_except (select_stuff
*ss
)
806 if (!ss
->device_specific_pipe
807 && (ss
->device_specific_pipe
= new select_pipe_info
) == NULL
)
809 select_record
*s
= ss
->start
.next
;
810 s
->startup
= start_thread_pipe
;
812 s
->verify
= verify_ok
;
813 s
->cleanup
= pipe_cleanup
;
814 s
->except_selected
= true;
815 s
->except_ready
= false;
820 fhandler_fifo::select_read (select_stuff
*ss
)
822 if (!ss
->device_specific_pipe
823 && (ss
->device_specific_pipe
= new select_pipe_info
) == NULL
)
825 select_record
*s
= ss
->start
.next
;
826 s
->startup
= start_thread_pipe
;
828 s
->verify
= verify_ok
;
829 s
->cleanup
= pipe_cleanup
;
830 s
->read_selected
= true;
831 s
->read_ready
= false;
836 fhandler_fifo::select_write (select_stuff
*ss
)
838 if (!ss
->device_specific_pipe
839 && (ss
->device_specific_pipe
= new select_pipe_info
) == NULL
)
841 select_record
*s
= ss
->start
.next
;
842 s
->startup
= start_thread_pipe
;
844 s
->verify
= verify_ok
;
845 s
->cleanup
= pipe_cleanup
;
846 s
->write_selected
= true;
847 s
->write_ready
= false;
852 fhandler_fifo::select_except (select_stuff
*ss
)
854 if (!ss
->device_specific_pipe
855 && (ss
->device_specific_pipe
= new select_pipe_info
) == NULL
)
857 select_record
*s
= ss
->start
.next
;
858 s
->startup
= start_thread_pipe
;
860 s
->verify
= verify_ok
;
861 s
->cleanup
= pipe_cleanup
;
862 s
->except_selected
= true;
863 s
->except_ready
= false;
868 peek_console (select_record
*me
, bool)
870 fhandler_console
*fh
= (fhandler_console
*) me
->fh
;
872 if (!me
->read_selected
)
873 return me
->write_ready
;
875 if (fh
->get_cons_readahead_valid ())
877 select_printf ("cons_readahead");
878 return me
->read_ready
= true;
881 if (fh
->get_readahead_valid ())
883 select_printf ("readahead");
884 return me
->read_ready
= true;
889 select_printf ("already ready");
897 set_handle_or_return_if_not_open (h
, me
);
900 if (fh
->bg_check (SIGTTIN
, true) <= bg_eof
)
901 return me
->read_ready
= true;
902 else if (!PeekConsoleInputW (h
, &irec
, 1, &events_read
) || !events_read
)
906 fh
->send_winch_maybe ();
907 if (irec
.EventType
== KEY_EVENT
)
909 if (irec
.Event
.KeyEvent
.bKeyDown
)
911 /* Ignore Alt+Numpad keys. They are eventually handled in the
912 key-up case below. */
913 if (is_alt_numpad_key (&irec
))
915 /* Handle normal input. */
916 else if (irec
.Event
.KeyEvent
.uChar
.UnicodeChar
917 || fhandler_console::get_nonascii_key (irec
, tmpbuf
))
918 return me
->read_ready
= true;
920 /* Ignore key up events, except for Alt+Numpad events. */
921 else if (is_alt_numpad_event (&irec
))
922 return me
->read_ready
= true;
926 if (irec
.EventType
== MOUSE_EVENT
927 && fh
->mouse_aware (irec
.Event
.MouseEvent
))
928 return me
->read_ready
= true;
929 if (irec
.EventType
== FOCUS_EVENT
&& fh
->focus_aware ())
930 return me
->read_ready
= true;
933 /* Read and discard the event */
934 ReadConsoleInputW (h
, &irec
, 1, &events_read
);
937 return me
->write_ready
;
941 verify_console (select_record
*me
, fd_set
*rfds
, fd_set
*wfds
,
944 return peek_console (me
, true);
949 fhandler_console::select_read (select_stuff
*ss
)
951 select_record
*s
= ss
->start
.next
;
954 s
->startup
= no_startup
;
955 s
->verify
= verify_console
;
959 s
->peek
= peek_console
;
960 s
->h
= get_handle ();
961 s
->read_selected
= true;
962 s
->read_ready
= get_readahead_valid ();
967 fhandler_console::select_write (select_stuff
*ss
)
969 select_record
*s
= ss
->start
.next
;
972 s
->startup
= no_startup
;
973 s
->verify
= no_verify
;
977 s
->peek
= peek_console
;
978 s
->write_selected
= true;
979 s
->write_ready
= true;
984 fhandler_console::select_except (select_stuff
*ss
)
986 select_record
*s
= ss
->start
.next
;
989 s
->startup
= no_startup
;
990 s
->verify
= no_verify
;
994 s
->peek
= peek_console
;
995 s
->except_selected
= true;
996 s
->except_ready
= false;
1001 fhandler_pty_common::select_read (select_stuff
*ss
)
1003 if (!ss
->device_specific_pipe
1004 && (ss
->device_specific_pipe
= new select_pipe_info
) == NULL
)
1007 select_record
*s
= ss
->start
.next
;
1008 s
->startup
= start_thread_pipe
;
1009 s
->peek
= peek_pipe
;
1010 s
->verify
= verify_ok
;
1011 s
->cleanup
= pipe_cleanup
;
1012 s
->read_selected
= true;
1013 s
->read_ready
= false;
1018 fhandler_pty_common::select_write (select_stuff
*ss
)
1020 if (!ss
->device_specific_pipe
1021 && (ss
->device_specific_pipe
= new select_pipe_info
) == NULL
)
1023 select_record
*s
= ss
->start
.next
;
1024 s
->startup
= start_thread_pipe
;
1025 s
->peek
= peek_pipe
;
1026 s
->verify
= verify_ok
;
1027 s
->cleanup
= pipe_cleanup
;
1028 s
->write_selected
= true;
1029 s
->write_ready
= false;
1034 fhandler_pty_common::select_except (select_stuff
*ss
)
1036 if (!ss
->device_specific_pipe
1037 && (ss
->device_specific_pipe
= new select_pipe_info
) == NULL
)
1039 select_record
*s
= ss
->start
.next
;
1040 s
->startup
= start_thread_pipe
;
1041 s
->peek
= peek_pipe
;
1042 s
->verify
= verify_ok
;
1043 s
->cleanup
= pipe_cleanup
;
1044 s
->except_selected
= true;
1045 s
->except_ready
= false;
1050 verify_tty_slave (select_record
*me
, fd_set
*readfds
, fd_set
*writefds
,
1053 if (IsEventSignalled (me
->h
))
1054 me
->read_ready
= true;
1055 return set_bits (me
, readfds
, writefds
, exceptfds
);
1059 fhandler_pty_slave::select_read (select_stuff
*ss
)
1061 select_record
*s
= ss
->start
.next
;
1062 s
->h
= input_available_event
;
1063 s
->startup
= no_startup
;
1064 s
->peek
= peek_pipe
;
1065 s
->verify
= verify_tty_slave
;
1066 s
->read_selected
= true;
1067 s
->read_ready
= false;
1073 fhandler_dev_null::select_read (select_stuff
*ss
)
1075 select_record
*s
= ss
->start
.next
;
1078 s
->startup
= no_startup
;
1079 s
->verify
= no_verify
;
1081 s
->h
= get_handle ();
1082 s
->read_selected
= true;
1083 s
->read_ready
= true;
1088 fhandler_dev_null::select_write (select_stuff
*ss
)
1090 select_record
*s
= ss
->start
.next
;
1093 s
->startup
= no_startup
;
1094 s
->verify
= no_verify
;
1096 s
->h
= get_handle ();
1097 s
->write_selected
= true;
1098 s
->write_ready
= true;
1103 fhandler_dev_null::select_except (select_stuff
*ss
)
1105 select_record
*s
= ss
->start
.next
;
1108 s
->startup
= no_startup
;
1109 s
->verify
= no_verify
;
1111 s
->h
= get_handle ();
1112 s
->except_selected
= true;
1113 s
->except_ready
= false;
1117 static int start_thread_serial (select_record
*me
, select_stuff
*stuff
);
1120 peek_serial (select_record
*s
, bool)
1124 fhandler_serial
*fh
= (fhandler_serial
*) s
->fh
;
1126 if (fh
->get_readahead_valid () || fh
->overlapped_armed
< 0)
1127 return s
->read_ready
= true;
1129 select_printf ("fh->overlapped_armed %d", fh
->overlapped_armed
);
1132 set_handle_or_return_if_not_open (h
, s
);
1135 if ((s
->read_selected
&& s
->read_ready
) || (s
->write_selected
&& s
->write_ready
))
1137 select_printf ("already ready");
1142 /* This is apparently necessary for the com0com driver.
1143 See: http://cygwin.com/ml/cygwin/2009-01/msg00667.html */
1146 SetCommMask (h
, EV_RXCHAR
);
1148 if (!fh
->overlapped_armed
)
1152 ResetEvent (fh
->io_status
.hEvent
);
1154 if (!ClearCommError (h
, &fh
->ev
, &st
))
1156 debug_printf ("ClearCommError");
1159 else if (st
.cbInQue
)
1160 return s
->read_ready
= true;
1161 else if (WaitCommEvent (h
, &fh
->ev
, &fh
->io_status
))
1162 return s
->read_ready
= true;
1163 else if (GetLastError () == ERROR_IO_PENDING
)
1164 fh
->overlapped_armed
= 1;
1167 debug_printf ("WaitCommEvent");
1172 switch (WaitForSingleObject (fh
->io_status
.hEvent
, 10L))
1175 if (!ClearCommError (h
, &fh
->ev
, &st
))
1177 debug_printf ("ClearCommError");
1180 else if (!st
.cbInQue
)
1184 return s
->read_ready
= true;
1185 select_printf ("got something");
1191 debug_printf ("WaitForMultipleObjects");
1199 if (GetLastError () == ERROR_OPERATION_ABORTED
)
1201 select_printf ("operation aborted");
1205 s
->set_select_errno ();
1206 select_printf ("error %E");
1211 thread_serial (void *arg
)
1213 select_serial_info
*si
= (select_serial_info
*) arg
;
1214 bool looping
= true;
1217 for (select_record
*s
= si
->start
; (s
= s
->next
); )
1218 if (s
->startup
!= start_thread_serial
)
1222 if (peek_serial (s
, true))
1224 if (si
->stop_thread
)
1226 select_printf ("stopping");
1232 select_printf ("exiting");
1237 start_thread_serial (select_record
*me
, select_stuff
*stuff
)
1239 if (stuff
->device_specific_serial
)
1240 me
->h
= *((select_serial_info
*) stuff
->device_specific_serial
)->thread
;
1243 select_serial_info
*si
= new select_serial_info
;
1244 si
->start
= &stuff
->start
;
1245 si
->stop_thread
= false;
1246 si
->thread
= new cygthread (thread_serial
, si
, "sersel");
1247 me
->h
= *si
->thread
;
1248 stuff
->device_specific_serial
= si
;
1254 serial_cleanup (select_record
*, select_stuff
*stuff
)
1256 select_serial_info
*si
= (select_serial_info
*) stuff
->device_specific_serial
;
1261 si
->stop_thread
= true;
1262 si
->thread
->detach ();
1265 stuff
->device_specific_serial
= NULL
;
1269 fhandler_serial::select_read (select_stuff
*ss
)
1271 select_record
*s
= ss
->start
.next
;
1274 s
->startup
= start_thread_serial
;
1275 s
->verify
= verify_ok
;
1276 s
->cleanup
= serial_cleanup
;
1278 s
->peek
= peek_serial
;
1279 s
->read_selected
= true;
1280 s
->read_ready
= false;
1285 fhandler_serial::select_write (select_stuff
*ss
)
1287 select_record
*s
= ss
->start
.next
;
1290 s
->startup
= no_startup
;
1291 s
->verify
= verify_ok
;
1293 s
->peek
= peek_serial
;
1294 s
->h
= get_handle ();
1295 s
->write_selected
= true;
1296 s
->write_ready
= true;
1301 fhandler_serial::select_except (select_stuff
*ss
)
1303 select_record
*s
= ss
->start
.next
;
1306 s
->startup
= no_startup
;
1307 s
->verify
= verify_ok
;
1310 s
->peek
= peek_serial
;
1311 s
->except_selected
= false; // Can't do this
1312 s
->except_ready
= false;
1317 fhandler_base::select_read (select_stuff
*ss
)
1319 select_record
*s
= ss
->start
.next
;
1322 s
->startup
= no_startup
;
1323 s
->verify
= verify_ok
;
1325 s
->h
= get_io_handle_cyg ();
1326 s
->read_selected
= true;
1327 s
->read_ready
= true;
1332 fhandler_base::select_write (select_stuff
*ss
)
1334 select_record
*s
= ss
->start
.next
;
1337 s
->startup
= no_startup
;
1338 s
->verify
= verify_ok
;
1340 s
->h
= get_handle ();
1341 s
->write_selected
= true;
1342 s
->write_ready
= true;
1347 fhandler_base::select_except (select_stuff
*ss
)
1349 select_record
*s
= ss
->start
.next
;
1352 s
->startup
= no_startup
;
1353 s
->verify
= verify_ok
;
1356 s
->except_selected
= true;
1357 s
->except_ready
= false;
1362 peek_socket (select_record
*me
, bool)
1364 fhandler_socket
*fh
= (fhandler_socket
*) me
->fh
;
1366 /* Don't play with the settings again, unless having taken a deep look into
1367 Richard W. Stevens Network Programming book. Thank you. */
1368 long evt_mask
= (me
->read_selected
? (FD_READ
| FD_ACCEPT
| FD_CLOSE
) : 0)
1369 | (me
->write_selected
? (FD_WRITE
| FD_CONNECT
| FD_CLOSE
) : 0)
1370 | (me
->except_selected
? FD_OOB
: 0);
1371 int ret
= fh
->evaluate_events (evt_mask
, events
, false);
1372 if (me
->read_selected
)
1373 me
->read_ready
|= ret
|| !!(events
& (FD_READ
| FD_ACCEPT
| FD_CLOSE
));
1374 if (me
->write_selected
)
1375 me
->write_ready
|= ret
|| !!(events
& (FD_WRITE
| FD_CONNECT
| FD_CLOSE
));
1376 if (me
->except_selected
)
1377 me
->except_ready
|= !!(events
& FD_OOB
);
1379 select_printf ("read_ready: %d, write_ready: %d, except_ready: %d",
1380 me
->read_ready
, me
->write_ready
, me
->except_ready
);
1381 return me
->read_ready
|| me
->write_ready
|| me
->except_ready
;
1384 static int start_thread_socket (select_record
*, select_stuff
*);
1387 thread_socket (void *arg
)
1389 select_socket_info
*si
= (select_socket_info
*) arg
;
1390 DWORD timeout
= (si
->num_w4
<= MAXIMUM_WAIT_OBJECTS
)
1392 : (64 / (roundup2 (si
->num_w4
, MAXIMUM_WAIT_OBJECTS
)
1393 / MAXIMUM_WAIT_OBJECTS
));
1396 select_printf ("stuff_start %p, timeout %u", si
->start
, timeout
);
1399 for (select_record
*s
= si
->start
; (s
= s
->next
); )
1400 if (s
->startup
== start_thread_socket
)
1401 if (peek_socket (s
, false))
1404 for (int i
= 0; i
< si
->num_w4
; i
+= MAXIMUM_WAIT_OBJECTS
)
1405 switch (WaitForMultipleObjects (MIN (si
->num_w4
- i
,
1406 MAXIMUM_WAIT_OBJECTS
),
1407 si
->w4
+ i
, FALSE
, timeout
))
1414 if (!i
) /* Socket event set. */
1422 select_printf ("leaving thread_socket");
1426 static inline bool init_tls_select_info () __attribute__ ((always_inline
));
1428 init_tls_select_info ()
1430 if (!_my_tls
.locals
.select
.sockevt
)
1432 _my_tls
.locals
.select
.sockevt
= CreateEvent (&sec_none_nih
, TRUE
, FALSE
,
1434 if (!_my_tls
.locals
.select
.sockevt
)
1437 if (!_my_tls
.locals
.select
.ser_num
)
1439 _my_tls
.locals
.select
.ser_num
1440 = (LONG
*) malloc (MAXIMUM_WAIT_OBJECTS
* sizeof (LONG
));
1441 if (!_my_tls
.locals
.select
.ser_num
)
1443 _my_tls
.locals
.select
.w4
1444 = (HANDLE
*) malloc (MAXIMUM_WAIT_OBJECTS
* sizeof (HANDLE
));
1445 if (!_my_tls
.locals
.select
.w4
)
1447 free (_my_tls
.locals
.select
.ser_num
);
1448 _my_tls
.locals
.select
.ser_num
= NULL
;
1451 _my_tls
.locals
.select
.max_w4
= MAXIMUM_WAIT_OBJECTS
;
1457 start_thread_socket (select_record
*me
, select_stuff
*stuff
)
1459 select_socket_info
*si
;
1461 if ((si
= (select_socket_info
*) stuff
->device_specific_socket
))
1463 me
->h
= *si
->thread
;
1467 si
= new select_socket_info
;
1469 if (!init_tls_select_info ())
1475 si
->ser_num
= _my_tls
.locals
.select
.ser_num
;
1476 si
->w4
= _my_tls
.locals
.select
.w4
;
1478 si
->w4
[0] = _my_tls
.locals
.select
.sockevt
;
1481 select_record
*s
= &stuff
->start
;
1482 while ((s
= s
->next
))
1483 if (s
->startup
== start_thread_socket
)
1485 /* No event/socket should show up multiple times. Every socket
1486 is uniquely identified by its serial number in the global
1487 wsock_events record. */
1488 const LONG ser_num
= ((fhandler_socket
*) s
->fh
)->serial_number ();
1489 for (int i
= 1; i
< si
->num_w4
; ++i
)
1490 if (si
->ser_num
[i
] == ser_num
)
1491 goto continue_outer_loop
;
1492 if (si
->num_w4
>= _my_tls
.locals
.select
.max_w4
)
1494 LONG
*nser
= (LONG
*) realloc (si
->ser_num
,
1495 (_my_tls
.locals
.select
.max_w4
1496 + MAXIMUM_WAIT_OBJECTS
)
1503 _my_tls
.locals
.select
.ser_num
= si
->ser_num
= nser
;
1504 HANDLE
*nw4
= (HANDLE
*) realloc (si
->w4
,
1505 (_my_tls
.locals
.select
.max_w4
1506 + MAXIMUM_WAIT_OBJECTS
)
1513 _my_tls
.locals
.select
.w4
= si
->w4
= nw4
;
1514 _my_tls
.locals
.select
.max_w4
+= MAXIMUM_WAIT_OBJECTS
;
1516 si
->ser_num
[si
->num_w4
] = ser_num
;
1517 si
->w4
[si
->num_w4
++] = ((fhandler_socket
*) s
->fh
)->wsock_event ();
1518 continue_outer_loop
:
1521 stuff
->device_specific_socket
= si
;
1522 si
->start
= &stuff
->start
;
1523 select_printf ("stuff_start %p", &stuff
->start
);
1524 si
->thread
= new cygthread (thread_socket
, si
, "socksel");
1525 me
->h
= *si
->thread
;
1530 socket_cleanup (select_record
*, select_stuff
*stuff
)
1532 select_socket_info
*si
= (select_socket_info
*) stuff
->device_specific_socket
;
1533 select_printf ("si %p si->thread %p", si
, si
? si
->thread
: NULL
);
1538 SetEvent (si
->w4
[0]);
1539 /* Wait for thread to go away */
1540 si
->thread
->detach ();
1541 ResetEvent (si
->w4
[0]);
1544 stuff
->device_specific_socket
= NULL
;
1545 select_printf ("returning");
1549 fhandler_socket::select_read (select_stuff
*ss
)
1551 select_record
*s
= ss
->start
.next
;
1554 s
->startup
= start_thread_socket
;
1555 s
->verify
= verify_true
;
1556 s
->cleanup
= socket_cleanup
;
1558 s
->peek
= peek_socket
;
1559 s
->read_ready
= saw_shutdown_read ();
1560 s
->read_selected
= true;
1565 fhandler_socket::select_write (select_stuff
*ss
)
1567 select_record
*s
= ss
->start
.next
;
1570 s
->startup
= start_thread_socket
;
1571 s
->verify
= verify_true
;
1572 s
->cleanup
= socket_cleanup
;
1574 s
->peek
= peek_socket
;
1575 s
->write_ready
= saw_shutdown_write () || connect_state () == unconnected
;
1576 s
->write_selected
= true;
1577 if (connect_state () != unconnected
)
1579 s
->except_ready
= saw_shutdown_write () || saw_shutdown_read ();
1580 s
->except_on_write
= true;
1586 fhandler_socket::select_except (select_stuff
*ss
)
1588 select_record
*s
= ss
->start
.next
;
1591 s
->startup
= start_thread_socket
;
1592 s
->verify
= verify_true
;
1593 s
->cleanup
= socket_cleanup
;
1595 s
->peek
= peek_socket
;
1596 /* FIXME: Is this right? Should these be used as criteria for except? */
1597 s
->except_ready
= saw_shutdown_write () || saw_shutdown_read ();
1598 s
->except_selected
= true;
1603 peek_windows (select_record
*me
, bool)
1607 set_handle_or_return_if_not_open (h
, me
);
1608 /* We need the hWnd value, not the io_handle. */
1609 h
= ((fhandler_windows
*) me
->fh
)->get_hwnd ();
1611 if (me
->read_selected
&& me
->read_ready
)
1614 if (PeekMessageW (&m
, (HWND
) h
, 0, 0, PM_NOREMOVE
))
1616 me
->read_ready
= true;
1617 select_printf ("window %d(%p) ready", me
->fd
, h
);
1621 select_printf ("window %d(%p) not ready", me
->fd
, h
);
1622 return me
->write_ready
;
1626 verify_windows (select_record
*me
, fd_set
*rfds
, fd_set
*wfds
,
1629 return peek_windows (me
, true);
1633 fhandler_windows::select_read (select_stuff
*ss
)
1635 select_record
*s
= ss
->start
.next
;
1638 s
->startup
= no_startup
;
1640 s
->verify
= verify_windows
;
1641 s
->peek
= peek_windows
;
1642 s
->read_selected
= true;
1643 s
->read_ready
= false;
1644 s
->windows_handle
= true;
1649 fhandler_windows::select_write (select_stuff
*ss
)
1651 select_record
*s
= ss
->start
.next
;
1654 s
->startup
= no_startup
;
1655 s
->verify
= verify_ok
;
1657 s
->peek
= peek_windows
;
1658 s
->write_selected
= true;
1659 s
->write_ready
= true;
1660 s
->windows_handle
= true;
1665 fhandler_windows::select_except (select_stuff
*ss
)
1667 select_record
*s
= ss
->start
.next
;
1670 s
->startup
= no_startup
;
1671 s
->verify
= verify_ok
;
1673 s
->peek
= peek_windows
;
1674 s
->except_selected
= true;
1675 s
->except_ready
= false;
1676 s
->windows_handle
= true;
1681 peek_mailslot (select_record
*me
, bool)
1684 set_handle_or_return_if_not_open (h
, me
);
1686 if (me
->read_selected
&& me
->read_ready
)
1689 if (!GetMailslotInfo (h
, NULL
, NULL
, &msgcnt
, NULL
))
1691 me
->except_ready
= true;
1692 select_printf ("mailslot %d(%p) error %E", me
->fd
, h
);
1697 me
->read_ready
= true;
1698 select_printf ("mailslot %d(%p) ready", me
->fd
, h
);
1701 select_printf ("mailslot %d(%p) not ready", me
->fd
, h
);
1706 verify_mailslot (select_record
*me
, fd_set
*rfds
, fd_set
*wfds
,
1709 return peek_mailslot (me
, true);
1712 static int start_thread_mailslot (select_record
*me
, select_stuff
*stuff
);
1715 thread_mailslot (void *arg
)
1717 select_mailslot_info
*mi
= (select_mailslot_info
*) arg
;
1718 bool gotone
= false;
1719 DWORD sleep_time
= 0;
1723 select_record
*s
= mi
->start
;
1724 while ((s
= s
->next
))
1725 if (s
->startup
== start_thread_mailslot
)
1727 if (peek_mailslot (s
, true))
1729 if (mi
->stop_thread
)
1731 select_printf ("stopping");
1735 /* Paranoid check */
1736 if (mi
->stop_thread
)
1738 select_printf ("stopping from outer loop");
1743 Sleep (sleep_time
>> 3);
1744 if (sleep_time
< 80)
1752 start_thread_mailslot (select_record
*me
, select_stuff
*stuff
)
1754 if (stuff
->device_specific_mailslot
)
1756 me
->h
= *((select_mailslot_info
*) stuff
->device_specific_mailslot
)->thread
;
1759 select_mailslot_info
*mi
= new select_mailslot_info
;
1760 mi
->start
= &stuff
->start
;
1761 mi
->stop_thread
= false;
1762 mi
->thread
= new cygthread (thread_mailslot
, mi
, "mailsel");
1763 me
->h
= *mi
->thread
;
1766 stuff
->device_specific_mailslot
= mi
;
1771 mailslot_cleanup (select_record
*, select_stuff
*stuff
)
1773 select_mailslot_info
*mi
= (select_mailslot_info
*) stuff
->device_specific_mailslot
;
1778 mi
->stop_thread
= true;
1779 mi
->thread
->detach ();
1782 stuff
->device_specific_mailslot
= NULL
;
1786 fhandler_mailslot::select_read (select_stuff
*ss
)
1788 select_record
*s
= ss
->start
.next
;
1789 s
->startup
= start_thread_mailslot
;
1790 s
->peek
= peek_mailslot
;
1791 s
->verify
= verify_mailslot
;
1792 s
->cleanup
= mailslot_cleanup
;
1793 s
->read_selected
= true;
1794 s
->read_ready
= false;