OSDN Git Service

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