OSDN Git Service

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