OSDN Git Service

1cd18e72075eb4677cfd604db66f3fafd474a1a2
[pf3gnuchains/pf3gnuchains3x.git] / winsup / cygwin / select.cc
1 /* select.cc
2
3    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4    2005, 2006, 2007, 2008, 2009 Red Hat, Inc.
5
6 This file is part of Cygwin.
7
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
10 details. */
11
12 /* The following line means that the BSD socket definitions for
13    fd_set, FD_ISSET etc. are used in this file.  */
14
15 #define  __INSIDE_CYGWIN_NET__
16
17 #include "winsup.h"
18 #include <stdlib.h>
19 #include <sys/param.h>
20 #include "ntdll.h"
21
22 #include <wingdi.h>
23 #include <winuser.h>
24 #include <netdb.h>
25 #define USE_SYS_TYPES_FD_SET
26 #include <winsock.h>
27 #include "cygerrno.h"
28 #include "security.h"
29 #include "path.h"
30 #include "fhandler.h"
31 #include "select.h"
32 #include "dtable.h"
33 #include "cygheap.h"
34 #include "pinfo.h"
35 #include "sigproc.h"
36 #include "cygtls.h"
37
38 /*
39  * All these defines below should be in sys/types.h
40  * but because of the includes above, they may not have
41  * been included. We create special UNIX_xxxx versions here.
42  */
43
44 #ifndef NBBY
45 #define NBBY 8    /* number of bits in a byte */
46 #endif /* NBBY */
47
48 /*
49  * Select uses bit masks of file descriptors in longs.
50  * These macros manipulate such bit fields (the filesystem macros use chars).
51  * FD_SETSIZE may be defined by the user, but the default here
52  * should be >= NOFILE (param.h).
53  */
54
55 typedef long fd_mask;
56 #define UNIX_NFDBITS (sizeof (fd_mask) * NBBY)       /* bits per mask */
57 #ifndef unix_howmany
58 #define unix_howmany(x,y) (((x)+((y)-1))/(y))
59 #endif
60
61 #define unix_fd_set fd_set
62
63 #define NULL_fd_set ((fd_set *) NULL)
64 #define sizeof_fd_set(n) \
65   ((unsigned) (NULL_fd_set->fds_bits + unix_howmany ((n), UNIX_NFDBITS)))
66 #define UNIX_FD_SET(n, p) \
67   ((p)->fds_bits[(n)/UNIX_NFDBITS] |= (1L << ((n) % UNIX_NFDBITS)))
68 #define UNIX_FD_CLR(n, p) \
69   ((p)->fds_bits[(n)/UNIX_NFDBITS] &= ~(1L << ((n) % UNIX_NFDBITS)))
70 #define UNIX_FD_ISSET(n, p) \
71   ((p)->fds_bits[(n)/UNIX_NFDBITS] & (1L << ((n) % UNIX_NFDBITS)))
72 #define UNIX_FD_ZERO(p, n) \
73   memset ((caddr_t) (p), 0, sizeof_fd_set ((n)))
74
75 #define allocfd_set(n) ((fd_set *) memset (alloca (sizeof_fd_set (n)), 0, sizeof_fd_set (n)))
76 #define copyfd_set(to, from, n) memcpy (to, from, sizeof_fd_set (n));
77
78 #define set_handle_or_return_if_not_open(h, s) \
79   h = (s)->fh->get_handle (); \
80   if (cygheap->fdtab.not_open ((s)->fd)) \
81     { \
82       (s)->thread_errno =  EBADF; \
83       return -1; \
84     } \
85
86 /* The main select code.
87  */
88 extern "C" int
89 cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
90                struct timeval *to)
91 {
92   select_stuff sel;
93   fd_set *dummy_readfds = allocfd_set (maxfds);
94   fd_set *dummy_writefds = allocfd_set (maxfds);
95   fd_set *dummy_exceptfds = allocfd_set (maxfds);
96
97   select_printf ("%d, %p, %p, %p, %p", maxfds, readfds, writefds, exceptfds, to);
98
99   if (!readfds)
100     readfds = dummy_readfds;
101   if (!writefds)
102     writefds = dummy_writefds;
103   if (!exceptfds)
104     exceptfds = dummy_exceptfds;
105
106   for (int i = 0; i < maxfds; i++)
107     if (!sel.test_and_set (i, readfds, writefds, exceptfds))
108       {
109         select_printf ("aborting due to test_and_set error");
110         return -1;      /* Invalid fd, maybe? */
111       }
112
113   /* Convert to milliseconds or INFINITE if to == NULL */
114   DWORD ms = to ? (to->tv_sec * 1000) + (to->tv_usec / 1000) : INFINITE;
115   if (ms == 0 && to->tv_usec)
116     ms = 1;                     /* At least 1 ms granularity */
117
118   if (to)
119     select_printf ("to->tv_sec %d, to->tv_usec %d, ms %d", to->tv_sec, to->tv_usec, ms);
120   else
121     select_printf ("to NULL, ms %x", ms);
122
123   select_printf ("sel.always_ready %d", sel.always_ready);
124
125   int timeout = 0;
126   /* Allocate some fd_set structures using the number of fds as a guide. */
127   fd_set *r = allocfd_set (maxfds);
128   fd_set *w = allocfd_set (maxfds);
129   fd_set *e = allocfd_set (maxfds);
130
131   /* Degenerate case.  No fds to wait for.  Just wait. */
132   if (sel.start.next == NULL)
133     {
134       if (WaitForSingleObject (signal_arrived, ms) == WAIT_OBJECT_0)
135         {
136           select_printf ("signal received");
137           set_sig_errno (EINTR);
138           return -1;
139         }
140       timeout = 1;
141     }
142   else if (sel.always_ready || ms == 0)
143     /* Don't bother waiting. */;
144   else if ((timeout = sel.wait (r, w, e, ms) < 0))
145     return -1;  /* some kind of error */
146
147   sel.cleanup ();
148   copyfd_set (readfds, r, maxfds);
149   copyfd_set (writefds, w, maxfds);
150   copyfd_set (exceptfds, e, maxfds);
151   return timeout ? 0 : sel.poll (readfds, writefds, exceptfds);
152 }
153
154 extern "C" int
155 pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
156         const struct timespec *ts, const sigset_t *set)
157 {
158   struct timeval tv;
159   sigset_t oldset = _my_tls.sigmask;
160
161   myfault efault;
162   if (efault.faulted (EFAULT))
163     return -1;
164   if (ts)
165     {
166       tv.tv_sec = ts->tv_sec;
167       tv.tv_usec = ts->tv_nsec / 1000;
168     }
169   if (set)
170     set_signal_mask (*set, _my_tls.sigmask);
171   int ret = cygwin_select (maxfds, readfds, writefds, exceptfds,
172                            ts ? &tv : NULL);
173   if (set)
174     set_signal_mask (oldset, _my_tls.sigmask);
175   return ret;
176 }
177
178 /* Call cleanup functions for all inspected fds.  Gets rid of any
179    executing threads. */
180 void
181 select_stuff::cleanup ()
182 {
183   select_record *s = &start;
184
185   select_printf ("calling cleanup routines");
186   while ((s = s->next))
187     if (s->cleanup)
188       {
189         s->cleanup (s, this);
190         s->cleanup = NULL;
191       }
192 }
193
194 /* Destroy all storage associated with select stuff. */
195 select_stuff::~select_stuff ()
196 {
197   cleanup ();
198   select_record *s = &start;
199   select_record *snext = start.next;
200
201   select_printf ("deleting select records");
202   while ((s = snext))
203     {
204       snext = s->next;
205       delete s;
206     }
207 }
208
209 /* Add a record to the select chain */
210 bool
211 select_stuff::test_and_set (int i, fd_set *readfds, fd_set *writefds,
212                             fd_set *exceptfds)
213 {
214   if (!UNIX_FD_ISSET (i, readfds) && !UNIX_FD_ISSET (i, writefds)
215       && ! UNIX_FD_ISSET (i, exceptfds))
216     return true;
217
218   select_record *s = new select_record;
219   if (!s)
220     return false;
221
222   s->next = start.next;
223   start.next = s;
224
225   if (UNIX_FD_ISSET (i, readfds) && !cygheap->fdtab.select_read (i, this))
226     goto err;
227   if (UNIX_FD_ISSET (i, writefds) && !cygheap->fdtab.select_write (i, this))
228     goto err;
229   if (UNIX_FD_ISSET (i, exceptfds) && !cygheap->fdtab.select_except (i, this))
230     goto err; /* error */
231
232   if (s->read_ready || s->write_ready || s->except_ready)
233     always_ready = true;
234
235   if (s->windows_handle)
236     windows_used = true;
237
238   return true;
239
240 err:
241   start.next = s->next;
242   delete s;
243   return false;
244 }
245
246 /* The heart of select.  Waits for an fd to do something interesting. */
247 int
248 select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
249                     DWORD ms)
250 {
251   int wait_ret;
252   HANDLE w4[MAXIMUM_WAIT_OBJECTS];
253   select_record *s = &start;
254   int m = 0;
255   int res = 0;
256
257   w4[m++] = signal_arrived;  /* Always wait for the arrival of a signal. */
258   /* Loop through the select chain, starting up anything appropriate and
259      counting the number of active fds. */
260   while ((s = s->next))
261     {
262       if (m >= MAXIMUM_WAIT_OBJECTS)
263         {
264           set_sig_errno (EINVAL);
265           return -1;
266         }
267       if (!s->startup (s, this))
268         {
269           s->set_select_errno ();
270           return -1;
271         }
272       if (s->h == NULL)
273         continue;
274       for (int i = 1; i < m; i++)
275         if (w4[i] == s->h)
276           goto next_while;
277       w4[m++] = s->h;
278   next_while:
279       continue;
280     }
281
282   LONGLONG start_time = gtod.msecs ();  /* Record the current time for later use. */
283
284   debug_printf ("m %d, ms %u", m, ms);
285   for (;;)
286     {
287       if (!windows_used)
288         wait_ret = WaitForMultipleObjects (m, w4, FALSE, ms);
289       else
290         wait_ret = MsgWaitForMultipleObjects (m, w4, FALSE, ms, QS_ALLINPUT);
291
292       switch (wait_ret)
293       {
294         case WAIT_OBJECT_0:
295           select_printf ("signal received");
296           set_sig_errno (EINTR);
297           return -1;
298         case WAIT_FAILED:
299           select_printf ("WaitForMultipleObjects failed");
300           s->set_select_errno ();
301           return -1;
302         case WAIT_TIMEOUT:
303           select_printf ("timed out");
304           res = 1;
305           goto out;
306       }
307
308       select_printf ("woke up.  wait_ret %d.  verifying", wait_ret);
309       s = &start;
310       bool gotone = false;
311       /* Some types of objects (e.g., consoles) wake up on "inappropriate" events
312          like mouse movements.  The verify function will detect these situations.
313          If it returns false, then this wakeup was a false alarm and we should go
314          back to waiting. */
315       while ((s = s->next))
316         if (s->saw_error ())
317           {
318             set_errno (s->saw_error ());
319             return -1;          /* Somebody detected an error */
320           }
321         else if ((((wait_ret >= m && s->windows_handle) || s->h == w4[wait_ret])) &&
322             s->verify (s, readfds, writefds, exceptfds))
323           gotone = true;
324
325       select_printf ("gotone %d", gotone);
326       if (gotone)
327         goto out;
328
329       if (ms == INFINITE)
330         {
331           select_printf ("looping");
332           continue;
333         }
334       select_printf ("recalculating ms");
335
336       LONGLONG now = gtod.msecs ();
337       if (now > (start_time + ms))
338         {
339           select_printf ("timed out after verification");
340           goto out;
341         }
342       ms -= (now - start_time);
343       start_time = now;
344       select_printf ("ms now %u", ms);
345     }
346
347 out:
348   select_printf ("returning %d", res);
349   return res;
350 }
351
352 static int
353 set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
354           fd_set *exceptfds)
355 {
356   int ready = 0;
357   fhandler_socket *sock;
358   select_printf ("me %p, testing fd %d (%s)", me, me->fd, me->fh->get_name ());
359   if (me->read_selected && me->read_ready)
360     {
361       UNIX_FD_SET (me->fd, readfds);
362       ready++;
363     }
364   if (me->write_selected && me->write_ready)
365     {
366       UNIX_FD_SET (me->fd, writefds);
367       if (me->except_on_write && (sock = me->fh->is_socket ()))
368         {
369           /* Special AF_LOCAL handling. */
370           if (!me->read_ready && sock->connect_state () == connect_pending
371               && sock->af_local_connect ())
372             {
373               if (me->read_selected)
374                 UNIX_FD_SET (me->fd, readfds);
375               sock->connect_state (connect_failed);
376             }
377           else
378             sock->connect_state (connected);
379         }
380       ready++;
381     }
382   if (me->except_selected && me->except_ready)
383     {
384       UNIX_FD_SET (me->fd, exceptfds);
385       ready++;
386     }
387   select_printf ("ready %d", ready);
388   return ready;
389 }
390
391 /* Poll every fd in the select chain.  Set appropriate fd in mask. */
392 int
393 select_stuff::poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
394 {
395   int n = 0;
396   select_record *s = &start;
397   while ((s = s->next))
398     n += (!s->peek || s->peek (s, true)) ?
399          set_bits (s, readfds, writefds, exceptfds) : 0;
400   select_printf ("returning %d", n);
401   return n;
402 }
403
404 static int
405 verify_true (select_record *, fd_set *, fd_set *, fd_set *)
406 {
407   return 1;
408 }
409
410 static int
411 verify_ok (select_record *me, fd_set *readfds, fd_set *writefds,
412            fd_set *exceptfds)
413 {
414   return set_bits (me, readfds, writefds, exceptfds);
415 }
416
417 static int
418 no_startup (select_record *, select_stuff *)
419 {
420   return 1;
421 }
422
423 static int
424 no_verify (select_record *, fd_set *, fd_set *, fd_set *)
425 {
426   return 0;
427 }
428
429 static int
430 peek_pipe (select_record *s, bool from_select)
431 {
432   int n = 0;
433   int gotone = 0;
434   fhandler_base *fh = s->fh;
435
436   HANDLE h;
437   set_handle_or_return_if_not_open (h, s);
438
439   /* Don't perform complicated tests if we don't need to. */
440   if (!s->read_selected && !s->except_selected)
441     goto out;
442
443   if (s->read_selected)
444     {
445       if (s->read_ready)
446         {
447           select_printf ("%s, already ready for read", fh->get_name ());
448           gotone = 1;
449           goto out;
450         }
451
452       switch (fh->get_major ())
453         {
454         case DEV_TTYM_MAJOR:
455           if (((fhandler_pty_master *) fh)->need_nl)
456             {
457               gotone = s->read_ready = true;
458               goto out;
459             }
460           break;
461         default:
462           if (fh->get_readahead_valid ())
463             {
464               select_printf ("readahead");
465               gotone = s->read_ready = true;
466               goto out;
467             }
468         }
469
470       if (fh->bg_check (SIGTTIN) <= bg_eof)
471         {
472           gotone = s->read_ready = true;
473           goto out;
474         }
475     }
476
477   if (fh->get_device () == FH_PIPEW)
478     select_printf ("%s, select for read/except on write end of pipe",
479                    fh->get_name ());
480   else if (!PeekNamedPipe (h, NULL, 0, NULL, (DWORD *) &n, NULL))
481     switch (GetLastError ())
482       {
483       case ERROR_BAD_PIPE:
484       case ERROR_PIPE_BUSY:
485       case ERROR_NO_DATA:
486       case ERROR_PIPE_NOT_CONNECTED:
487         n = 0;
488         break;
489       default:
490         select_printf ("%s, PeekNamedPipe failed, %E", fh->get_name ());
491         n = -1;
492         break;
493       }
494
495   if (n < 0)
496     {
497       select_printf ("%s, n %d", fh->get_name (), n);
498       if (s->except_selected)
499         gotone += s->except_ready = true;
500       if (s->read_selected)
501         gotone += s->read_ready = true;
502     }
503   if (n > 0 && s->read_selected)
504     {
505       select_printf ("%s, ready for read: avail %d", fh->get_name (), n);
506       gotone += s->read_ready = true;
507     }
508   if (!gotone && s->fh->hit_eof ())
509     {
510       select_printf ("%s, saw EOF", fh->get_name ());
511       if (s->except_selected)
512         gotone += s->except_ready = true;
513       if (s->read_selected)
514         gotone += s->read_ready = true;
515     }
516
517 out:
518   if (s->write_selected)
519     {
520       if (s->write_ready)
521         {
522           select_printf ("%s, already ready for write", fh->get_name ());
523           gotone++;
524         }
525       /* Do we need to do anything about SIGTTOU here? */
526       else if (fh->get_device () == FH_PIPER)
527         select_printf ("%s, select for write on read end of pipe",
528                        fh->get_name ());
529       else if (fh->has_ongoing_io (true))
530         s->write_ready = false;
531       else
532         {
533           IO_STATUS_BLOCK iosb = {0};
534           FILE_PIPE_LOCAL_INFORMATION fpli = {0};
535
536           if (NtQueryInformationFile (h,
537                                       &iosb,
538                                       &fpli,
539                                       sizeof (fpli),
540                                       FilePipeLocalInformation))
541             {
542               /* If NtQueryInformationFile fails, optimistically assume the
543                  pipe is writable.  This could happen if we somehow
544                  inherit a pipe that doesn't permit FILE_READ_ATTRIBUTES
545                  access on the write end.  */
546               select_printf ("%s, NtQueryInformationFile failed",
547                              fh->get_name ());
548               gotone += s->write_ready = true;
549             }
550           /* If there is anything available in the pipe buffer then signal
551              that.  This means that a pipe could still block since you could
552              be trying to write more to the pipe than is available in the
553              buffer but that is the hazard of select().  */
554           else if ((fpli.WriteQuotaAvailable = (fpli.OutboundQuota - fpli.ReadDataAvailable)))
555             {
556               select_printf ("%s, ready for write: size %lu, avail %lu",
557                              fh->get_name (),
558                              fpli.OutboundQuota,
559                              fpli.WriteQuotaAvailable);
560               gotone += s->write_ready = true;
561             }
562           /* If we somehow inherit a tiny pipe (size < PIPE_BUF), then consider
563              the pipe writable only if it is completely empty, to minimize the
564              probability that a subsequent write will block.  */
565           else if (fpli.OutboundQuota < PIPE_BUF &&
566                    fpli.WriteQuotaAvailable == fpli.OutboundQuota)
567             {
568               select_printf ("%s, tiny pipe: size %lu, avail %lu",
569                              fh->get_name (),
570                              fpli.OutboundQuota,
571                              fpli.WriteQuotaAvailable);
572               gotone += s->write_ready = true;
573             }
574         }
575     }
576
577   return gotone;
578 }
579
580 static int start_thread_pipe (select_record *me, select_stuff *stuff);
581
582 select_pipe_info::select_pipe_info ()
583 {
584   n = 1;
585   w4[0] = CreateEvent (&sec_none_nih, true, false, NULL);
586 }
587
588 select_pipe_info::~select_pipe_info ()
589 {
590   if (thread)
591     {
592       SetEvent (w4[0]);
593       stop_thread = true;
594       thread->detach ();
595     }
596   ForceCloseHandle (w4[0]);
597 }
598
599 void
600 select_pipe_info::add_watch_handle (fhandler_pipe *fh)
601 {
602   if (fh->get_overlapped () && fh->get_overlapped ()->hEvent)
603     w4[n++] = fh->get_overlapped ()->hEvent;
604 }
605
606 static DWORD WINAPI
607 thread_pipe (void *arg)
608 {
609   select_pipe_info *pi = (select_pipe_info *) arg;
610   bool gotone = false;
611   DWORD sleep_time = 0;
612
613   for (;;)
614     {
615       select_record *s = pi->start;
616       if (pi->n > 1)
617         switch (WaitForMultipleObjects (pi->n, pi->w4, false, INFINITE))
618           {
619           case WAIT_OBJECT_0:
620             goto out;
621           default:
622             break;
623           }
624       while ((s = s->next))
625         if (s->startup == start_thread_pipe)
626           {
627             if (peek_pipe (s, true))
628               gotone = true;
629             if (pi->stop_thread)
630               {
631                 select_printf ("stopping");
632                 goto out;
633               }
634           }
635       /* Paranoid check */
636       if (pi->stop_thread)
637         {
638           select_printf ("stopping from outer loop");
639           break;
640         }
641       if (gotone)
642         break;
643       Sleep (sleep_time >> 3);
644       if (sleep_time < 80)
645         ++sleep_time;
646     }
647 out:
648   return 0;
649 }
650
651 static int
652 start_thread_pipe (select_record *me, select_stuff *stuff)
653 {
654   select_pipe_info *pi = stuff->device_specific_pipe;
655   if (pi->start)
656     me->h = *((select_pipe_info *) stuff->device_specific_pipe)->thread;
657   else
658     {
659       pi->start = &stuff->start;
660       pi->stop_thread = false;
661       pi->thread = new cygthread (thread_pipe, 0, pi, "select_pipe");
662       me->h = *pi->thread;
663       if (!me->h)
664         return 0;
665     }
666   return 1;
667 }
668
669 static void
670 pipe_cleanup (select_record *, select_stuff *stuff)
671 {
672   if (stuff->device_specific_pipe)
673     {
674       delete stuff->device_specific_pipe;
675       stuff->device_specific_pipe = NULL;
676     }
677 }
678
679 int
680 fhandler_pipe::ready_for_read (int fd, DWORD howlong)
681 {
682   int res;
683   if (!howlong)
684     res = fhandler_base::ready_for_read (fd, howlong);
685   else
686     res = 1;
687   return res;
688 }
689
690 select_record *
691 fhandler_pipe::select_read (select_stuff *ss)
692 {
693   if (!ss->device_specific_pipe
694       && (ss->device_specific_pipe = new select_pipe_info) == NULL)
695     return NULL;
696   ss->device_specific_pipe->add_watch_handle (this);
697
698   select_record *s = ss->start.next;
699   s->startup = start_thread_pipe;
700   s->peek = peek_pipe;
701   s->verify = verify_ok;
702   s->cleanup = pipe_cleanup;
703   s->read_selected = true;
704   s->read_ready = false;
705   return s;
706 }
707
708 select_record *
709 fhandler_pipe::select_write (select_stuff *ss)
710 {
711   if (!ss->device_specific_pipe
712       && (ss->device_specific_pipe = new select_pipe_info) == NULL)
713     return NULL;
714   ss->device_specific_pipe->add_watch_handle (this);
715   select_record *s = ss->start.next;
716   s->startup = start_thread_pipe;
717   s->peek = peek_pipe;
718   s->verify = verify_ok;
719   s->cleanup = pipe_cleanup;
720   s->write_selected = true;
721   s->write_ready = false;
722   return s;
723 }
724
725 select_record *
726 fhandler_pipe::select_except (select_stuff *ss)
727 {
728   if (!ss->device_specific_pipe
729       && (ss->device_specific_pipe = new select_pipe_info) == NULL)
730     return NULL;
731   ss->device_specific_pipe->add_watch_handle (this);
732   select_record *s = ss->start.next;
733   s->startup = start_thread_pipe;
734   s->peek = peek_pipe;
735   s->verify = verify_ok;
736   s->cleanup = pipe_cleanup;
737   s->except_selected = true;
738   s->except_ready = false;
739   return s;
740 }
741
742 select_record *
743 fhandler_fifo::select_read (select_stuff *ss)
744 {
745   select_record *s = ss->start.next;
746   s->startup = start_thread_pipe;
747   s->peek = peek_pipe;
748   s->verify = verify_ok;
749   s->cleanup = pipe_cleanup;
750   s->read_selected = true;
751   s->read_ready = false;
752   return s;
753 }
754
755 select_record *
756 fhandler_fifo::select_write (select_stuff *ss)
757 {
758   select_record *s = ss->start.next;
759   s->startup = start_thread_pipe;
760   s->peek = peek_pipe;
761   s->verify = verify_ok;
762   s->cleanup = pipe_cleanup;
763   s->write_selected = true;
764   s->write_ready = false;
765   return s;
766 }
767
768 select_record *
769 fhandler_fifo::select_except (select_stuff *ss)
770 {
771   select_record *s = ss->start.next;
772   s->startup = start_thread_pipe;
773   s->peek = peek_pipe;
774   s->verify = verify_ok;
775   s->cleanup = pipe_cleanup;
776   s->except_selected = true;
777   s->except_ready = false;
778   return s;
779 }
780
781 static int
782 peek_console (select_record *me, bool)
783 {
784   extern const char * get_nonascii_key (INPUT_RECORD& input_rec, char *);
785   fhandler_console *fh = (fhandler_console *) me->fh;
786
787   if (!me->read_selected)
788     return me->write_ready;
789
790   if (fh->get_readahead_valid ())
791     {
792       select_printf ("readahead");
793       return me->read_ready = true;
794     }
795
796   if (me->read_ready)
797     {
798       select_printf ("already ready");
799       return 1;
800     }
801
802   INPUT_RECORD irec;
803   DWORD events_read;
804   HANDLE h;
805   char tmpbuf[17];
806   set_handle_or_return_if_not_open (h, me);
807
808   for (;;)
809     if (fh->bg_check (SIGTTIN) <= bg_eof)
810       return me->read_ready = true;
811     else if (!PeekConsoleInput (h, &irec, 1, &events_read) || !events_read)
812       break;
813     else
814       {
815         fh->send_winch_maybe ();
816         if (irec.EventType == KEY_EVENT)
817           {
818             if (irec.Event.KeyEvent.bKeyDown
819                 && (irec.Event.KeyEvent.uChar.AsciiChar
820                     || get_nonascii_key (irec, tmpbuf)))
821               return me->read_ready = true;
822           }
823         else
824           {
825             if (irec.EventType == MOUSE_EVENT
826                 && fh->mouse_aware (irec.Event.MouseEvent))
827                 return me->read_ready = true;
828             if (irec.EventType == FOCUS_EVENT && fh->focus_aware ())
829                 return me->read_ready = true;
830           }
831
832         /* Read and discard the event */
833         ReadConsoleInput (h, &irec, 1, &events_read);
834       }
835
836   return me->write_ready;
837 }
838
839 static int
840 verify_console (select_record *me, fd_set *rfds, fd_set *wfds,
841               fd_set *efds)
842 {
843   return peek_console (me, true);
844 }
845
846
847 select_record *
848 fhandler_console::select_read (select_stuff *ss)
849 {
850   select_record *s = ss->start.next;
851   if (!s->startup)
852     {
853       s->startup = no_startup;
854       s->verify = verify_console;
855       set_cursor_maybe ();
856     }
857
858   s->peek = peek_console;
859   s->h = get_handle ();
860   s->read_selected = true;
861   s->read_ready = false;
862   return s;
863 }
864
865 select_record *
866 fhandler_console::select_write (select_stuff *ss)
867 {
868   select_record *s = ss->start.next;
869   if (!s->startup)
870     {
871       s->startup = no_startup;
872       s->verify = no_verify;
873       set_cursor_maybe ();
874     }
875
876   s->peek = peek_console;
877   s->write_selected = true;
878   s->write_ready = true;
879   return s;
880 }
881
882 select_record *
883 fhandler_console::select_except (select_stuff *ss)
884 {
885   select_record *s = ss->start.next;
886   if (!s->startup)
887     {
888       s->startup = no_startup;
889       s->verify = no_verify;
890       set_cursor_maybe ();
891     }
892
893   s->peek = peek_console;
894   s->except_selected = true;
895   s->except_ready = false;
896   return s;
897 }
898
899 select_record *
900 fhandler_tty_common::select_read (select_stuff *ss)
901 {
902   return ((fhandler_pipe *) this)->fhandler_pipe::select_read (ss);
903 }
904
905 select_record *
906 fhandler_tty_common::select_write (select_stuff *ss)
907 {
908   return ((fhandler_pipe *) this)->fhandler_pipe::select_write (ss);
909 }
910
911 select_record *
912 fhandler_tty_common::select_except (select_stuff *ss)
913 {
914   return ((fhandler_pipe *) this)->fhandler_pipe::select_except (ss);
915 }
916
917 static int
918 verify_tty_slave (select_record *me, fd_set *readfds, fd_set *writefds,
919            fd_set *exceptfds)
920 {
921   if (WaitForSingleObject (me->h, 0) == WAIT_OBJECT_0)
922     me->read_ready = true;
923   return set_bits (me, readfds, writefds, exceptfds);
924 }
925
926 select_record *
927 fhandler_tty_slave::select_read (select_stuff *ss)
928 {
929   select_record *s = ss->start.next;
930   s->h = input_available_event;
931   s->startup = no_startup;
932   s->peek = peek_pipe;
933   s->verify = verify_tty_slave;
934   s->read_selected = true;
935   s->read_ready = false;
936   s->cleanup = NULL;
937   return s;
938 }
939
940 select_record *
941 fhandler_dev_null::select_read (select_stuff *ss)
942 {
943   select_record *s = ss->start.next;
944   if (!s->startup)
945     {
946       s->startup = no_startup;
947       s->verify = no_verify;
948     }
949   s->h = get_handle ();
950   s->read_selected = true;
951   s->read_ready = true;
952   return s;
953 }
954
955 select_record *
956 fhandler_dev_null::select_write (select_stuff *ss)
957 {
958   select_record *s = ss->start.next;
959   if (!s->startup)
960     {
961       s->startup = no_startup;
962       s->verify = no_verify;
963     }
964   s->h = get_handle ();
965   s->write_selected = true;
966   s->write_ready = true;
967   return s;
968 }
969
970 select_record *
971 fhandler_dev_null::select_except (select_stuff *ss)
972 {
973   select_record *s = ss->start.next;
974   if (!s->startup)
975     {
976       s->startup = no_startup;
977       s->verify = no_verify;
978     }
979   s->h = get_handle ();
980   s->except_selected = true;
981   s->except_ready = false;
982   return s;
983 }
984
985 static int start_thread_serial (select_record *me, select_stuff *stuff);
986
987 static int
988 peek_serial (select_record *s, bool)
989 {
990   COMSTAT st;
991
992   fhandler_serial *fh = (fhandler_serial *) s->fh;
993
994   if (fh->get_readahead_valid () || fh->overlapped_armed < 0)
995     return s->read_ready = true;
996
997   select_printf ("fh->overlapped_armed %d", fh->overlapped_armed);
998
999   HANDLE h;
1000   set_handle_or_return_if_not_open (h, s);
1001   int ready = 0;
1002
1003   if ((s->read_selected && s->read_ready) || (s->write_selected && s->write_ready))
1004     {
1005       select_printf ("already ready");
1006       ready = 1;
1007       goto out;
1008     }
1009
1010   /* This is apparently necessary for the com0com driver.
1011      See: http://cygwin.com/ml/cygwin/2009-01/msg00667.html */
1012   SetCommMask (h, 0);
1013
1014   SetCommMask (h, EV_RXCHAR);
1015
1016   if (!fh->overlapped_armed)
1017     {
1018       COMSTAT st;
1019
1020       ResetEvent (fh->io_status.hEvent);
1021
1022       if (!ClearCommError (h, &fh->ev, &st))
1023         {
1024           debug_printf ("ClearCommError");
1025           goto err;
1026         }
1027       else if (st.cbInQue)
1028         return s->read_ready = true;
1029       else if (WaitCommEvent (h, &fh->ev, &fh->io_status))
1030         return s->read_ready = true;
1031       else if (GetLastError () == ERROR_IO_PENDING)
1032         fh->overlapped_armed = 1;
1033       else
1034         {
1035           debug_printf ("WaitCommEvent");
1036           goto err;
1037         }
1038     }
1039
1040   HANDLE w4[2];
1041   DWORD to;
1042
1043   w4[0] = fh->io_status.hEvent;
1044   w4[1] = signal_arrived;
1045   to = 10;
1046
1047   switch (WaitForMultipleObjects (2, w4, FALSE, to))
1048     {
1049     case WAIT_OBJECT_0:
1050       if (!ClearCommError (h, &fh->ev, &st))
1051         {
1052           debug_printf ("ClearCommError");
1053           goto err;
1054         }
1055       else if (!st.cbInQue)
1056         Sleep (to);
1057       else
1058         {
1059           return s->read_ready = true;
1060           select_printf ("got something");
1061         }
1062       break;
1063     case WAIT_OBJECT_0 + 1:
1064       select_printf ("interrupt");
1065       set_sig_errno (EINTR);
1066       ready = -1;
1067       break;
1068     case WAIT_TIMEOUT:
1069       break;
1070     default:
1071       debug_printf ("WaitForMultipleObjects");
1072       goto err;
1073     }
1074
1075 out:
1076   return ready;
1077
1078 err:
1079   if (GetLastError () == ERROR_OPERATION_ABORTED)
1080     {
1081       select_printf ("operation aborted");
1082       return ready;
1083     }
1084
1085   s->set_select_errno ();
1086   select_printf ("error %E");
1087   return -1;
1088 }
1089
1090 static DWORD WINAPI
1091 thread_serial (void *arg)
1092 {
1093   select_serial_info *si = (select_serial_info *) arg;
1094   bool gotone = false;
1095
1096   for (;;)
1097     {
1098       select_record *s = si->start;
1099       while ((s = s->next))
1100         if (s->startup == start_thread_serial)
1101           {
1102             if (peek_serial (s, true))
1103               gotone = true;
1104           }
1105       if (si->stop_thread)
1106         {
1107           select_printf ("stopping");
1108           break;
1109         }
1110       if (gotone)
1111         break;
1112     }
1113
1114   select_printf ("exiting");
1115   return 0;
1116 }
1117
1118 static int
1119 start_thread_serial (select_record *me, select_stuff *stuff)
1120 {
1121   if (stuff->device_specific_serial)
1122     me->h = *((select_serial_info *) stuff->device_specific_serial)->thread;
1123   else
1124     {
1125       select_serial_info *si = new select_serial_info;
1126       si->start = &stuff->start;
1127       si->stop_thread = false;
1128       si->thread = new cygthread (thread_serial, 0,  si, "select_serial");
1129       me->h = *si->thread;
1130       stuff->device_specific_serial = si;
1131     }
1132   return 1;
1133 }
1134
1135 static void
1136 serial_cleanup (select_record *, select_stuff *stuff)
1137 {
1138   select_serial_info *si = (select_serial_info *) stuff->device_specific_serial;
1139   if (si && si->thread)
1140     {
1141       si->stop_thread = true;
1142       si->thread->detach ();
1143       delete si;
1144       stuff->device_specific_serial = NULL;
1145     }
1146 }
1147
1148 select_record *
1149 fhandler_serial::select_read (select_stuff *ss)
1150 {
1151   select_record *s = ss->start.next;
1152   if (!s->startup)
1153     {
1154       s->startup = start_thread_serial;
1155       s->verify = verify_ok;
1156       s->cleanup = serial_cleanup;
1157     }
1158   s->peek = peek_serial;
1159   s->read_selected = true;
1160   s->read_ready = false;
1161   return s;
1162 }
1163
1164 select_record *
1165 fhandler_serial::select_write (select_stuff *ss)
1166 {
1167   select_record *s = ss->start.next;
1168   if (!s->startup)
1169     {
1170       s->startup = no_startup;
1171       s->verify = verify_ok;
1172     }
1173   s->peek = peek_serial;
1174   s->h = get_handle ();
1175   s->write_selected = true;
1176   s->write_ready = true;
1177   return s;
1178 }
1179
1180 select_record *
1181 fhandler_serial::select_except (select_stuff *ss)
1182 {
1183   select_record *s = ss->start.next;
1184   if (!s->startup)
1185     {
1186       s->startup = no_startup;
1187       s->verify = verify_ok;
1188     }
1189   s->h = NULL;
1190   s->peek = peek_serial;
1191   s->except_selected = false;   // Can't do this
1192   s->except_ready = false;
1193   return s;
1194 }
1195
1196 int
1197 fhandler_base::ready_for_read (int fd, DWORD howlong)
1198 {
1199   bool avail = false;
1200
1201   select_stuff sel;
1202   fd_set *thisfd = allocfd_set (fd + 1);
1203   fd_set *dummy_writefds = allocfd_set (fd + 1);
1204   fd_set *dummy_exceptfds = allocfd_set (fd + 1);
1205   UNIX_FD_SET(fd, thisfd);
1206
1207   if (!sel.test_and_set (fd, thisfd, dummy_writefds, dummy_exceptfds))
1208     select_printf ("aborting due to test_and_set error");
1209   else
1210     {
1211       select_record *me = sel.start.next;
1212       while (!avail)
1213         {
1214           avail = me->read_ready ?: me->peek (me, false);
1215
1216           if (fd >= 0 && cygheap->fdtab.not_open (fd))
1217             {
1218               set_sig_errno (EBADF);
1219               avail = false;
1220               break;
1221             }
1222
1223           if (howlong != INFINITE)
1224             {
1225               if (!avail)
1226                 set_sig_errno (EAGAIN);
1227               break;
1228             }
1229
1230           if (WaitForSingleObject (signal_arrived, avail ? 0 : 10) == WAIT_OBJECT_0)
1231             {
1232               debug_printf ("interrupted");
1233               set_sig_errno (EINTR);
1234               avail = false;
1235               break;
1236             }
1237         }
1238     }
1239
1240   select_printf ("read_ready %d, avail %d", sel.start.next->read_ready, avail);
1241   sel.cleanup ();
1242   return avail;
1243 }
1244
1245 select_record *
1246 fhandler_base::select_read (select_stuff *ss)
1247 {
1248   select_record *s = ss->start.next;
1249   if (!s->startup)
1250     {
1251       s->startup = no_startup;
1252       s->verify = verify_ok;
1253     }
1254   s->h = get_handle ();
1255   s->read_selected = true;
1256   s->read_ready = true;
1257   return s;
1258 }
1259
1260 select_record *
1261 fhandler_base::select_write (select_stuff *ss)
1262 {
1263   select_record *s = ss->start.next;
1264   if (!s->startup)
1265     {
1266       s->startup = no_startup;
1267       s->verify = verify_ok;
1268     }
1269   s->h = get_handle ();
1270   s->write_selected = true;
1271   s->write_ready = true;
1272   return s;
1273 }
1274
1275 select_record *
1276 fhandler_base::select_except (select_stuff *ss)
1277 {
1278   select_record *s = ss->start.next;
1279   if (!s->startup)
1280     {
1281       s->startup = no_startup;
1282       s->verify = verify_ok;
1283     }
1284   s->h = NULL;
1285   s->except_selected = true;
1286   s->except_ready = false;
1287   return s;
1288 }
1289
1290 static int
1291 peek_socket (select_record *me, bool)
1292 {
1293   fhandler_socket *fh = (fhandler_socket *) me->fh;
1294   long events;
1295   /* Don't play with the settings again, unless having taken a deep look into
1296      Richard W. Stevens Network Programming book.  Thank you. */
1297   long evt_mask = (me->read_selected ? (FD_READ | FD_ACCEPT | FD_CLOSE) : 0)
1298                 | (me->write_selected ? (FD_WRITE | FD_CONNECT | FD_CLOSE) : 0)
1299                 | (me->except_selected ? FD_OOB : 0);
1300   int ret = fh->evaluate_events (evt_mask, events, false);
1301   if (me->read_selected)
1302     me->read_ready |= ret || !!(events & (FD_READ | FD_ACCEPT | FD_CLOSE));
1303   if (me->write_selected)
1304     me->write_ready |= ret || !!(events & (FD_WRITE | FD_CONNECT | FD_CLOSE));
1305   if (me->except_selected)
1306     me->except_ready |= !!(events & FD_OOB);
1307
1308   select_printf ("read_ready: %d, write_ready: %d, except_ready: %d",
1309                  me->read_ready, me->write_ready, me->except_ready);
1310   return me->read_ready || me->write_ready || me->except_ready;
1311 }
1312
1313 static int start_thread_socket (select_record *, select_stuff *);
1314
1315 static DWORD WINAPI
1316 thread_socket (void *arg)
1317 {
1318   select_socket_info *si = (select_socket_info *) arg;
1319   DWORD timeout = (si->num_w4 <= MAXIMUM_WAIT_OBJECTS)
1320                   ? INFINITE
1321                   : (64 / (roundup2 (si->num_w4, MAXIMUM_WAIT_OBJECTS)
1322                            / MAXIMUM_WAIT_OBJECTS));
1323   bool event = false;
1324
1325   select_printf ("stuff_start %p", si->start);
1326   while (!event)
1327     {
1328       for (select_record *s = si->start; (s = s->next); )
1329         if (s->startup == start_thread_socket)
1330           if (peek_socket (s, false))
1331             event = true;
1332       if (!event)
1333         for (int i = 0; i < si->num_w4; i += MAXIMUM_WAIT_OBJECTS)
1334           switch (WaitForMultipleObjects (min (si->num_w4 - i,
1335                                                MAXIMUM_WAIT_OBJECTS),
1336                                           si->w4 + i, FALSE, timeout))
1337             {
1338             case WAIT_FAILED:
1339               goto out;
1340             case WAIT_TIMEOUT:
1341               continue;
1342             case WAIT_OBJECT_0:
1343               if (!i)   /* Socket event set. */
1344                 goto out;
1345               /*FALLTHRU*/
1346             default:
1347               break;
1348             }
1349     }
1350 out:
1351   select_printf ("leaving thread_socket");
1352   return 0;
1353 }
1354
1355 static inline bool init_tls_select_info () __attribute__ ((always_inline));
1356 static inline bool
1357 init_tls_select_info ()
1358 {
1359   if (!_my_tls.locals.select.sockevt)
1360     {
1361       _my_tls.locals.select.sockevt = CreateEvent (&sec_none_nih, TRUE, FALSE,
1362                                                    NULL);
1363       if (!_my_tls.locals.select.sockevt)
1364         return false;
1365     }
1366   if (!_my_tls.locals.select.ser_num)
1367     {
1368       _my_tls.locals.select.ser_num
1369               = (LONG *) malloc (MAXIMUM_WAIT_OBJECTS * sizeof (LONG));
1370       if (!_my_tls.locals.select.ser_num)
1371         return false;
1372       _my_tls.locals.select.w4
1373               = (HANDLE *) malloc (MAXIMUM_WAIT_OBJECTS * sizeof (HANDLE));
1374       if (!_my_tls.locals.select.w4)
1375         {
1376           free (_my_tls.locals.select.ser_num);
1377           _my_tls.locals.select.ser_num = NULL;
1378           return false;
1379         }
1380       _my_tls.locals.select.max_w4 = MAXIMUM_WAIT_OBJECTS;
1381     }
1382   return true;
1383 }
1384
1385 static int
1386 start_thread_socket (select_record *me, select_stuff *stuff)
1387 {
1388   select_socket_info *si;
1389
1390   if ((si = (select_socket_info *) stuff->device_specific_socket))
1391     {
1392       me->h = *si->thread;
1393       return 1;
1394     }
1395
1396   si = new select_socket_info;
1397
1398   if (!init_tls_select_info ())
1399     return 0;
1400
1401   si->ser_num = _my_tls.locals.select.ser_num;
1402   si->w4 = _my_tls.locals.select.w4;
1403
1404   si->w4[0] = _my_tls.locals.select.sockevt;
1405   si->num_w4 = 1;
1406
1407   select_record *s = &stuff->start;
1408   while ((s = s->next))
1409     if (s->startup == start_thread_socket)
1410       {
1411         /* No event/socket should show up multiple times.  Every socket
1412            is uniquely identified by its serial number in the global
1413            wsock_events record. */
1414         const LONG ser_num = ((fhandler_socket *) s->fh)->serial_number ();
1415         for (int i = 1; i < si->num_w4; ++i)
1416           if (si->ser_num[i] == ser_num)
1417             goto continue_outer_loop;
1418         if (si->num_w4 >= _my_tls.locals.select.max_w4)
1419           {
1420             LONG *nser = (LONG *) realloc (si->ser_num,
1421                                            (_my_tls.locals.select.max_w4
1422                                             + MAXIMUM_WAIT_OBJECTS)
1423                                            * sizeof (LONG));
1424             if (!nser)
1425               return 0;
1426             _my_tls.locals.select.ser_num = si->ser_num = nser;
1427             HANDLE *nw4 = (HANDLE *) realloc (si->w4,
1428                                            (_my_tls.locals.select.max_w4
1429                                             + MAXIMUM_WAIT_OBJECTS)
1430                                            * sizeof (HANDLE));
1431             if (!nw4)
1432               return 0;
1433             _my_tls.locals.select.w4 = si->w4 = nw4;
1434             _my_tls.locals.select.max_w4 += MAXIMUM_WAIT_OBJECTS;
1435           }
1436         si->ser_num[si->num_w4] = ser_num;
1437         si->w4[si->num_w4++] = ((fhandler_socket *) s->fh)->wsock_event ();
1438       continue_outer_loop:
1439         ;
1440       }
1441   stuff->device_specific_socket = si;
1442   si->start = &stuff->start;
1443   select_printf ("stuff_start %p", &stuff->start);
1444   si->thread = new cygthread (thread_socket, 0,  si, "select_socket");
1445   me->h = *si->thread;
1446   return 1;
1447 }
1448
1449 void
1450 socket_cleanup (select_record *, select_stuff *stuff)
1451 {
1452   select_socket_info *si = (select_socket_info *) stuff->device_specific_socket;
1453   select_printf ("si %p si->thread %p", si, si ? si->thread : NULL);
1454   if (si && si->thread)
1455     {
1456       SetEvent (si->w4[0]);
1457       /* Wait for thread to go away */
1458       si->thread->detach ();
1459       ResetEvent (si->w4[0]);
1460       stuff->device_specific_socket = NULL;
1461       delete si;
1462     }
1463   select_printf ("returning");
1464 }
1465
1466 select_record *
1467 fhandler_socket::select_read (select_stuff *ss)
1468 {
1469   select_record *s = ss->start.next;
1470   if (!s->startup)
1471     {
1472       s->startup = start_thread_socket;
1473       s->verify = verify_true;
1474       s->cleanup = socket_cleanup;
1475     }
1476   s->peek = peek_socket;
1477   s->read_ready = saw_shutdown_read ();
1478   s->read_selected = true;
1479   return s;
1480 }
1481
1482 select_record *
1483 fhandler_socket::select_write (select_stuff *ss)
1484 {
1485   select_record *s = ss->start.next;
1486   if (!s->startup)
1487     {
1488       s->startup = start_thread_socket;
1489       s->verify = verify_true;
1490       s->cleanup = socket_cleanup;
1491     }
1492   s->peek = peek_socket;
1493   s->write_ready = saw_shutdown_write () || connect_state () == unconnected;
1494   s->write_selected = true;
1495   if (connect_state () != unconnected)
1496     {
1497       s->except_ready = saw_shutdown_write () || saw_shutdown_read ();
1498       s->except_on_write = true;
1499     }
1500   return s;
1501 }
1502
1503 select_record *
1504 fhandler_socket::select_except (select_stuff *ss)
1505 {
1506   select_record *s = ss->start.next;
1507   if (!s->startup)
1508     {
1509       s->startup = start_thread_socket;
1510       s->verify = verify_true;
1511       s->cleanup = socket_cleanup;
1512     }
1513   s->peek = peek_socket;
1514   /* FIXME: Is this right?  Should these be used as criteria for except? */
1515   s->except_ready = saw_shutdown_write () || saw_shutdown_read ();
1516   s->except_selected = true;
1517   return s;
1518 }
1519
1520 static int
1521 peek_windows (select_record *me, bool)
1522 {
1523   MSG m;
1524   HANDLE h;
1525   set_handle_or_return_if_not_open (h, me);
1526
1527   if (me->read_selected && me->read_ready)
1528     return 1;
1529
1530   if (PeekMessage (&m, (HWND) h, 0, 0, PM_NOREMOVE))
1531     {
1532       me->read_ready = true;
1533       select_printf ("window %d(%p) ready", me->fd, me->fh->get_handle ());
1534       return 1;
1535     }
1536
1537   select_printf ("window %d(%p) not ready", me->fd, me->fh->get_handle ());
1538   return me->write_ready;
1539 }
1540
1541 static int
1542 verify_windows (select_record *me, fd_set *rfds, fd_set *wfds,
1543                 fd_set *efds)
1544 {
1545   return peek_windows (me, true);
1546 }
1547
1548 select_record *
1549 fhandler_windows::select_read (select_stuff *ss)
1550 {
1551   select_record *s = ss->start.next;
1552   if (!s->startup)
1553     {
1554       s->startup = no_startup;
1555     }
1556   s->verify = verify_windows;
1557   s->peek = peek_windows;
1558   s->read_selected = true;
1559   s->read_ready = false;
1560   s->h = get_handle ();
1561   s->windows_handle = true;
1562   return s;
1563 }
1564
1565 select_record *
1566 fhandler_windows::select_write (select_stuff *ss)
1567 {
1568   select_record *s = ss->start.next;
1569   if (!s->startup)
1570     {
1571       s->startup = no_startup;
1572       s->verify = verify_ok;
1573     }
1574   s->peek = peek_windows;
1575   s->h = get_handle ();
1576   s->write_selected = true;
1577   s->write_ready = true;
1578   s->windows_handle = true;
1579   return s;
1580 }
1581
1582 select_record *
1583 fhandler_windows::select_except (select_stuff *ss)
1584 {
1585   select_record *s = ss->start.next;
1586   if (!s->startup)
1587     {
1588       s->startup = no_startup;
1589       s->verify = verify_ok;
1590     }
1591   s->peek = peek_windows;
1592   s->h = get_handle ();
1593   s->except_selected = true;
1594   s->except_ready = false;
1595   s->windows_handle = true;
1596   return s;
1597 }
1598
1599 static int
1600 peek_mailslot (select_record *me, bool)
1601 {
1602   HANDLE h;
1603   set_handle_or_return_if_not_open (h, me);
1604
1605   if (me->read_selected && me->read_ready)
1606     return 1;
1607   DWORD msgcnt = 0;
1608   if (!GetMailslotInfo (h, NULL, NULL, &msgcnt, NULL))
1609     {
1610       select_printf ("mailslot %d(%p) error %E", me->fd, h);
1611       return 1;
1612     }
1613   if (msgcnt > 0)
1614     {
1615       me->read_ready = true;
1616       select_printf ("mailslot %d(%p) ready", me->fd, h);
1617       return 1;
1618     }
1619   select_printf ("mailslot %d(%p) not ready", me->fd, h);
1620   return 0;
1621 }
1622
1623 static int
1624 verify_mailslot (select_record *me, fd_set *rfds, fd_set *wfds,
1625                  fd_set *efds)
1626 {
1627   return peek_mailslot (me, true);
1628 }
1629
1630 static int start_thread_mailslot (select_record *me, select_stuff *stuff);
1631
1632 static DWORD WINAPI
1633 thread_mailslot (void *arg)
1634 {
1635   select_mailslot_info *mi = (select_mailslot_info *) arg;
1636   bool gotone = false;
1637   DWORD sleep_time = 0;
1638
1639   for (;;)
1640     {
1641       select_record *s = mi->start;
1642       while ((s = s->next))
1643         if (s->startup == start_thread_mailslot)
1644           {
1645             if (peek_mailslot (s, true))
1646               gotone = true;
1647             if (mi->stop_thread)
1648               {
1649                 select_printf ("stopping");
1650                 goto out;
1651               }
1652           }
1653       /* Paranoid check */
1654       if (mi->stop_thread)
1655         {
1656           select_printf ("stopping from outer loop");
1657           break;
1658         }
1659       if (gotone)
1660         break;
1661       Sleep (sleep_time >> 3);
1662       if (sleep_time < 80)
1663         ++sleep_time;
1664     }
1665 out:
1666   return 0;
1667 }
1668
1669 static int
1670 start_thread_mailslot (select_record *me, select_stuff *stuff)
1671 {
1672   if (stuff->device_specific_mailslot)
1673     {
1674       me->h = *((select_mailslot_info *) stuff->device_specific_mailslot)->thread;
1675       return 1;
1676     }
1677   select_mailslot_info *mi = new select_mailslot_info;
1678   mi->start = &stuff->start;
1679   mi->stop_thread = false;
1680   mi->thread = new cygthread (thread_mailslot, 0,  mi, "select_mailslot");
1681   me->h = *mi->thread;
1682   if (!me->h)
1683     return 0;
1684   stuff->device_specific_mailslot = mi;
1685   return 1;
1686 }
1687
1688 static void
1689 mailslot_cleanup (select_record *, select_stuff *stuff)
1690 {
1691   select_mailslot_info *mi = (select_mailslot_info *) stuff->device_specific_mailslot;
1692   if (mi && mi->thread)
1693     {
1694       mi->stop_thread = true;
1695       mi->thread->detach ();
1696       delete mi;
1697       stuff->device_specific_mailslot = NULL;
1698     }
1699 }
1700
1701 select_record *
1702 fhandler_mailslot::select_read (select_stuff *ss)
1703 {
1704   select_record *s = ss->start.next;
1705   s->startup = start_thread_mailslot;
1706   s->peek = peek_mailslot;
1707   s->verify = verify_mailslot;
1708   s->cleanup = mailslot_cleanup;
1709   s->read_selected = true;
1710   s->read_ready = false;
1711   return s;
1712 }