OSDN Git Service

* sigproc.cc (remove_proc): Don't terminate the currently executing thread.
authorcgf <cgf>
Tue, 29 Nov 2011 15:34:47 +0000 (15:34 +0000)
committercgf <cgf>
Tue, 29 Nov 2011 15:34:47 +0000 (15:34 +0000)
winsup/cygwin/ChangeLog
winsup/cygwin/cygheap.cc
winsup/cygwin/cygheap_malloc.h
winsup/cygwin/fhandler.cc
winsup/cygwin/fhandler.h
winsup/cygwin/select.cc
winsup/cygwin/sigproc.cc
winsup/cygwin/syscalls.cc
winsup/cygwin/tty.h

index b2a66fd..5cb4a38 100644 (file)
@@ -1,3 +1,8 @@
+2011-11-29  Christopher Faylor  <me.cygwin2011@cgf.cx>
+
+       * sigproc.cc (remove_proc): Don't terminate the currently executing
+       thread.
+
 2011-11-28  Christopher Faylor  <me.cygwin2011@cgf.cx>
 
        * cygheap.cc (cygheap_fixup_in_child): Accommodate new HEAP_3*
index 5543759..fabb680 100644 (file)
@@ -70,18 +70,22 @@ cygheap_fixup_in_child (bool execed)
     {
       cygheap->hooks.next = NULL;
       cygheap->user_heap.base = NULL;          /* We can allocate the heap anywhere */
-      /* Walk the allocated memory chain looking for orphaned memory from
-        previous execs */
-      for (_cmalloc_entry *rvc = cygheap->chain; rvc; rvc = rvc->prev)
-       {
-         cygheap_entry *ce = (cygheap_entry *) rvc->data;
-         if (!rvc->ptr || rvc->b >= NBUCKETS || ce->type <= HEAP_1_START)
-           continue;
-         else if (ce->type < HEAP_1_MAX)
-           ce->type += HEAP_1_MAX;     /* Mark for freeing after next exec */
-         else
-           _cfree (ce);                /* Marked by parent for freeing in child */
-       }
+    }
+  /* Walk the allocated memory chain looking for orphaned memory from
+     previous execs or forks */
+  for (_cmalloc_entry *rvc = cygheap->chain; rvc; rvc = rvc->prev)
+    {
+      cygheap_entry *ce = (cygheap_entry *) rvc->data;
+      if (!rvc->ptr || rvc->b >= NBUCKETS || ce->type <= HEAP_1_START)
+       continue;
+      else if (ce->type > HEAP_2_MAX)
+       _cfree (ce);            /* Marked for freeing in any child */
+      else if (!execed)
+       continue;
+      else if (ce->type > HEAP_1_MAX)
+       _cfree (ce);            /* Marked for freeing in execed child */
+      else
+       ce->type += HEAP_1_MAX; /* Mark for freeing after next exec */
     }
 }
 
index 12ed4bd..ef260ec 100644 (file)
@@ -33,7 +33,9 @@ enum cygheap_types
   HEAP_1_MAX = 100,
   HEAP_2_STR,
   HEAP_2_DLL,
-  HEAP_MMAP = 200
+  HEAP_MMAP,
+  HEAP_2_MAX = 200,
+  HEAP_3_FHANDLER
 };
 
 extern "C" {
index 98c6bb9..08f404c 100644 (file)
@@ -28,6 +28,7 @@ details. */
 #include "ntdll.h"
 #include "cygtls.h"
 #include "sigproc.h"
+#include "shared_info.h"
 #include <asm/socket.h>
 
 #define MAX_OVERLAPPED_WRITE_LEN (64 * 1024 * 1024)
@@ -37,6 +38,9 @@ static const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
 
 struct __cygwin_perfile *perfile_table;
 
+HANDLE NO_COPY fhandler_base_overlapped::asio_done;
+LONG NO_COPY fhandler_base_overlapped::asio_close_counter;
+
 void
 fhandler_base::reset (const fhandler_base *from)
 {
@@ -1152,17 +1156,77 @@ fhandler_base::close ()
   return res;
 }
 
+DWORD WINAPI
+flush_async_io (void *arg)
+{
+  fhandler_base_overlapped *fh = (fhandler_base_overlapped *) arg;
+  debug_only_printf ("waiting for %s I/O for %s",
+                    (fh->get_access () & GENERIC_WRITE) ? "write" : "read",
+                    fh->get_name ());
+  SetEvent (fh->get_overlapped ()->hEvent); /* force has_ongoing_io to block */
+  bool res = fh->has_ongoing_io ();
+  debug_printf ("finished waiting for I/O from %s, res %d", fh->get_name (),
+               res);
+  fh->close ();
+  delete fh;
+
+  InterlockedDecrement (&fhandler_base_overlapped::asio_close_counter);
+  SetEvent (fhandler_base_overlapped::asio_done);
+
+  _my_tls._ctinfo->auto_release ();
+  return 0;
+}
+
+void
+fhandler_base_overlapped::flush_all_async_io ()
+{
+  while (asio_close_counter > 0)
+    if (WaitForSingleObject (asio_done, INFINITE) != WAIT_OBJECT_0)
+      {
+       system_printf ("WaitForSingleObject failed, possible data loss in pipe, %E");
+       break;
+      }
+  asio_close_counter = 0;
+  if (asio_done)
+    CloseHandle (asio_done);
+}
+
+/* Start a thread to handle closing of overlapped asynchronous I/O since
+   Windows amazingly does not seem to always flush I/O on close.  */
+void
+fhandler_base_overlapped::check_later ()
+{
+  set_close_on_exec (true);
+  char buf[MAX_PATH];
+  if (!asio_done
+      && !(asio_done = CreateEvent (&sec_none_nih, false, false,
+                                   shared_name (buf, "asio",
+                                                GetCurrentProcessId ()))))
+    api_fatal ("CreateEvent failed, %E");
+
+  InterlockedIncrement (&asio_close_counter);
+  if (!new cygthread(flush_async_io, this, "flasio"))
+    api_fatal ("couldn't create a thread to track async I/O, %E");
+  debug_printf ("started thread to handle asynchronous closing for %s", get_name ());
+}
 
 int
 fhandler_base_overlapped::close ()
 {
-  if (is_nonblocking () && io_pending)
+  int res;
+  /* Need to treat non-blocking I/O specially because Windows appears to
+     be brain-dead  */
+  if (is_nonblocking () && has_ongoing_io ())
     {
-      DWORD bytes;
-      wait_overlapped (1, !!(get_access () & GENERIC_WRITE), &bytes, false);
+      clone (HEAP_3_FHANDLER)->check_later ();
+      res = 0;
     }
-  destroy_overlapped ();
-  return fhandler_base::close ();
+  else
+    {
+      destroy_overlapped ();
+      res = fhandler_base::close ();
+    }
+  return res;
 }
 
 int
@@ -1414,12 +1478,6 @@ fhandler_base::ptsname_r (char *, size_t)
   return ENOTTY;
 }
 
-void
-fhandler_base::operator delete (void *p)
-{
-  cfree (p);
-}
-
 /* Normal I/O constructor */
 fhandler_base::fhandler_base () :
   status (),
@@ -1836,13 +1894,10 @@ fhandler_base_overlapped::has_ongoing_io ()
     return false;
 
   if (!IsEventSignalled (get_overlapped ()->hEvent))
-    {
-      set_errno (EAGAIN);
-      return true;
-    }
+    return true;
   io_pending = false;
   DWORD nbytes;
-  GetOverlappedResult (get_output_handle (), get_overlapped (), &nbytes, 0);
+  GetOverlappedResult (get_output_handle (), get_overlapped (), &nbytes, true);
   return false;
 }
 
@@ -1930,7 +1985,7 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte
     }
   else
     {
-      debug_printf ("res %u, err %u", (unsigned) res, err);
+      debug_printf ("res %u, Win32 Error %u", (unsigned) res, err);
       *bytes = (DWORD) -1;
       __seterrno_from_win_error (err);
       if (writing && err == ERROR_NO_DATA)
@@ -1970,7 +2025,10 @@ fhandler_base_overlapped::raw_write (const void *ptr, size_t len)
 {
   size_t nbytes;
   if (has_ongoing_io ())
-    nbytes = (DWORD) -1;
+    {
+      set_errno (EAGAIN);
+      nbytes = (DWORD) -1;
+    }
   else
     {
       size_t chunk;
index e94a8bf..a6e1834 100644 (file)
@@ -409,7 +409,7 @@ public:
     raixput = raixget = ralen = rabuflen = 0;
     rabuf = NULL;
   }
-  void operator delete (void *);
+  void operator delete (void *p) {cfree (p);}
   virtual void set_eof () {}
   virtual int mkdir (mode_t mode);
   virtual int rmdir ();
@@ -435,9 +435,9 @@ public:
     x->reset (this);
   }
 
-  virtual fhandler_base *clone ()
+  virtual fhandler_base *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_base));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_base));
     fhandler_base *fh = new (ptr) fhandler_base (ptr);
     copyto (fh);
     return fh;
@@ -602,9 +602,9 @@ class fhandler_socket: public fhandler_base
     x->reset (this);
   }
 
-  fhandler_socket *clone ()
+  fhandler_socket *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_socket));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_socket));
     fhandler_socket *fh = new (ptr) fhandler_socket (ptr);
     copyto (fh);
     return fh;
@@ -613,6 +613,8 @@ class fhandler_socket: public fhandler_base
 
 class fhandler_base_overlapped: public fhandler_base
 {
+  static HANDLE asio_done;
+  static LONG asio_close_counter;
 protected:
   enum wait_return
   {
@@ -647,6 +649,9 @@ public:
   int close ();
   int dup (fhandler_base *child, int);
 
+  void check_later ();
+  static void flush_all_async_io () __attribute__ ((regparm (1)));;
+
   fhandler_base_overlapped (void *) {}
 
   virtual void copyto (fhandler_base *x)
@@ -656,13 +661,15 @@ public:
     x->reset (this);
   }
 
-  virtual fhandler_base_overlapped *clone ()
+  virtual fhandler_base_overlapped *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_base_overlapped));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_base_overlapped));
     fhandler_base_overlapped *fh = new (ptr) fhandler_base_overlapped (ptr);
     copyto (fh);
     return fh;
   }
+
+  friend DWORD WINAPI flush_async_io (void *);
 };
 
 class fhandler_pipe: public fhandler_base_overlapped
@@ -701,9 +708,9 @@ public:
     x->reset (this);
   }
 
-  fhandler_pipe *clone ()
+  fhandler_pipe *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_pipe));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_pipe));
     fhandler_pipe *fh = new (ptr) fhandler_pipe (ptr);
     copyto (fh);
     return fh;
@@ -739,9 +746,9 @@ public:
     x->reset (this);
   }
 
-  fhandler_fifo *clone ()
+  fhandler_fifo *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_fifo));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_fifo));
     fhandler_fifo *fh = new (ptr) fhandler_fifo (ptr);
     copyto (fh);
     return fh;
@@ -768,9 +775,9 @@ class fhandler_mailslot : public fhandler_base_overlapped
     x->reset (this);
   }
 
-  fhandler_mailslot *clone ()
+  fhandler_mailslot *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_mailslot));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_mailslot));
     fhandler_mailslot *fh = new (ptr) fhandler_mailslot (ptr);
     copyto (fh);
     return fh;
@@ -817,9 +824,9 @@ class fhandler_dev_raw: public fhandler_base
     x->reset (this);
   }
 
-  fhandler_dev_raw *clone ()
+  fhandler_dev_raw *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_dev_raw));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_raw));
     fhandler_dev_raw *fh = new (ptr) fhandler_dev_raw (ptr);
     copyto (fh);
     return fh;
@@ -877,9 +884,9 @@ class fhandler_dev_floppy: public fhandler_dev_raw
     x->reset (this);
   }
 
-  fhandler_dev_floppy *clone ()
+  fhandler_dev_floppy *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_dev_floppy));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_floppy));
     fhandler_dev_floppy *fh = new (ptr) fhandler_dev_floppy (ptr);
     copyto (fh);
     return fh;
@@ -925,9 +932,9 @@ class fhandler_dev_tape: public fhandler_dev_raw
     x->reset (this);
   }
 
-  fhandler_dev_tape *clone ()
+  fhandler_dev_tape *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_dev_tape));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_tape));
     fhandler_dev_tape *fh = new (ptr) fhandler_dev_tape (ptr);
     copyto (fh);
     return fh;
@@ -991,9 +998,9 @@ class fhandler_disk_file: public fhandler_base
     x->reset (this);
   }
 
-  fhandler_disk_file *clone ()
+  fhandler_disk_file *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_disk_file));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_disk_file));
     fhandler_disk_file *fh = new (ptr) fhandler_disk_file (ptr);
     copyto (fh);
     return fh;
@@ -1029,9 +1036,9 @@ class fhandler_cygdrive: public fhandler_disk_file
     x->reset (this);
   }
 
-  fhandler_cygdrive *clone ()
+  fhandler_cygdrive *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_cygdrive));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_cygdrive));
     fhandler_cygdrive *fh = new (ptr) fhandler_cygdrive (ptr);
     copyto (fh);
     return fh;
@@ -1093,9 +1100,9 @@ class fhandler_serial: public fhandler_base
     x->reset (this);
   }
 
-  fhandler_serial *clone ()
+  fhandler_serial *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_serial));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_serial));
     fhandler_serial *fh = new (ptr) fhandler_serial (ptr);
     copyto (fh);
     return fh;
@@ -1151,9 +1158,9 @@ class fhandler_termios: public fhandler_base
     x->reset (this);
   }
 
-  virtual fhandler_termios *clone ()
+  virtual fhandler_termios *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_termios));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_termios));
     fhandler_termios *fh = new (ptr) fhandler_termios (ptr);
     copyto (fh);
     return fh;
@@ -1350,9 +1357,9 @@ private:
     x->reset (this);
   }
 
-  fhandler_console *clone ()
+  fhandler_console *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_console));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_console));
     fhandler_console *fh = new (ptr) fhandler_console (ptr);
     copyto (fh);
     return fh;
@@ -1394,9 +1401,9 @@ class fhandler_pty_common: public fhandler_termios
     x->reset (this);
   }
 
-  virtual fhandler_pty_common *clone ()
+  virtual fhandler_pty_common *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_pty_common));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_pty_common));
     fhandler_pty_common *fh = new (ptr) fhandler_pty_common (ptr);
     copyto (fh);
     return fh;
@@ -1448,9 +1455,9 @@ class fhandler_pty_slave: public fhandler_pty_common
     x->reset (this);
   }
 
-  fhandler_pty_slave *clone ()
+  fhandler_pty_slave *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_pty_slave));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_pty_slave));
     fhandler_pty_slave *fh = new (ptr) fhandler_pty_slave (ptr);
     copyto (fh);
     return fh;
@@ -1507,9 +1514,9 @@ public:
     x->reset (this);
   }
 
-  fhandler_pty_master *clone ()
+  fhandler_pty_master *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_pty_master));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_pty_master));
     fhandler_pty_master *fh = new (ptr) fhandler_pty_master (ptr);
     copyto (fh);
     return fh;
@@ -1534,9 +1541,9 @@ class fhandler_dev_null: public fhandler_base
     x->reset (this);
   }
 
-  fhandler_dev_null *clone ()
+  fhandler_dev_null *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_dev_null));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_null));
     fhandler_dev_null *fh = new (ptr) fhandler_dev_null (ptr);
     copyto (fh);
     return fh;
@@ -1569,9 +1576,9 @@ class fhandler_dev_zero: public fhandler_base
     x->reset (this);
   }
 
-  fhandler_dev_zero *clone ()
+  fhandler_dev_zero *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_dev_zero));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_zero));
     fhandler_dev_zero *fh = new (ptr) fhandler_dev_zero (ptr);
     copyto (fh);
     return fh;
@@ -1607,9 +1614,9 @@ class fhandler_dev_random: public fhandler_base
     x->reset (this);
   }
 
-  fhandler_dev_random *clone ()
+  fhandler_dev_random *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_dev_random));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_random));
     fhandler_dev_random *fh = new (ptr) fhandler_dev_random (ptr);
     copyto (fh);
     return fh;
@@ -1647,9 +1654,9 @@ class fhandler_dev_mem: public fhandler_base
     x->reset (this);
   }
 
-  fhandler_dev_mem *clone ()
+  fhandler_dev_mem *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_dev_mem));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_mem));
     fhandler_dev_mem *fh = new (ptr) fhandler_dev_mem (ptr);
     copyto (fh);
     return fh;
@@ -1683,9 +1690,9 @@ class fhandler_dev_clipboard: public fhandler_base
     x->reset (this);
   }
 
-  fhandler_dev_clipboard *clone ()
+  fhandler_dev_clipboard *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_dev_clipboard));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_clipboard));
     fhandler_dev_clipboard *fh = new (ptr) fhandler_dev_clipboard (ptr);
     copyto (fh);
     return fh;
@@ -1722,9 +1729,9 @@ class fhandler_windows: public fhandler_base
     x->reset (this);
   }
 
-  fhandler_windows *clone ()
+  fhandler_windows *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_windows));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_windows));
     fhandler_windows *fh = new (ptr) fhandler_windows (ptr);
     copyto (fh);
     return fh;
@@ -1769,9 +1776,9 @@ class fhandler_dev_dsp: public fhandler_base
     x->reset (this);
   }
 
-  fhandler_dev_dsp *clone ()
+  fhandler_dev_dsp *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_dev_dsp));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_dsp));
     fhandler_dev_dsp *fh = new (ptr) fhandler_dev_dsp (ptr);
     copyto (fh);
     return fh;
@@ -1820,9 +1827,9 @@ class fhandler_virtual : public fhandler_base
     x->reset (this);
   }
 
-  virtual fhandler_virtual *clone ()
+  virtual fhandler_virtual *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_virtual));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_virtual));
     fhandler_virtual *fh = new (ptr) fhandler_virtual (ptr);
     copyto (fh);
     return fh;
@@ -1852,9 +1859,9 @@ class fhandler_proc: public fhandler_virtual
     x->reset (this);
   }
 
-  virtual fhandler_proc *clone ()
+  virtual fhandler_proc *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_proc));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_proc));
     fhandler_proc *fh = new (ptr) fhandler_proc (ptr);
     copyto (fh);
     return fh;
@@ -1888,9 +1895,9 @@ class fhandler_procsys: public fhandler_virtual
     x->reset (this);
   }
 
-  fhandler_procsys *clone ()
+  fhandler_procsys *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_procsys));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_procsys));
     fhandler_procsys *fh = new (ptr) fhandler_procsys (ptr);
     copyto (fh);
     return fh;
@@ -1917,9 +1924,9 @@ class fhandler_procsysvipc: public fhandler_proc
     x->reset (this);
   }
 
-  fhandler_procsysvipc *clone ()
+  fhandler_procsysvipc *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_procsysvipc));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_procsysvipc));
     fhandler_procsysvipc *fh = new (ptr) fhandler_procsysvipc (ptr);
     copyto (fh);
     return fh;
@@ -1947,9 +1954,9 @@ class fhandler_netdrive: public fhandler_virtual
     x->reset (this);
   }
 
-  fhandler_netdrive *clone ()
+  fhandler_netdrive *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_netdrive));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_netdrive));
     fhandler_netdrive *fh = new (ptr) fhandler_netdrive (ptr);
     copyto (fh);
     return fh;
@@ -1987,9 +1994,9 @@ class fhandler_registry: public fhandler_proc
     x->reset (this);
   }
 
-  fhandler_registry *clone ()
+  fhandler_registry *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_registry));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_registry));
     fhandler_registry *fh = new (ptr) fhandler_registry (ptr);
     copyto (fh);
     return fh;
@@ -2019,9 +2026,9 @@ class fhandler_process: public fhandler_proc
     x->reset (this);
   }
 
-  fhandler_process *clone ()
+  fhandler_process *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_process));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_process));
     fhandler_process *fh = new (ptr) fhandler_process (ptr);
     copyto (fh);
     return fh;
@@ -2048,9 +2055,9 @@ class fhandler_procnet: public fhandler_proc
     x->reset (this);
   }
 
-  fhandler_procnet *clone ()
+  fhandler_procnet *clone (cygheap_types malloc_type = HEAP_FHANDLER)
   {
-    void *ptr = (void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_procnet));
+    void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_procnet));
     fhandler_procnet *fh = new (ptr) fhandler_procnet (ptr);
     copyto (fh);
     return fh;
index c3d3c95..d92642b 100644 (file)
@@ -484,48 +484,51 @@ pipe_data_available (int fd, fhandler_base *fh, HANDLE h, bool writing)
   FILE_PIPE_LOCAL_INFORMATION fpli = {0};
 
   bool res = false;
-  if (NtQueryInformationFile (h,
-                             &iosb,
-                             &fpli,
-                             sizeof (fpli),
-                             FilePipeLocalInformation))
+  if (!fh->has_ongoing_io ())
     {
-      /* If NtQueryInformationFile fails, optimistically assume the
-        pipe is writable.  This could happen if we somehow
-        inherit a pipe that doesn't permit FILE_READ_ATTRIBUTES
-        access on the write end.  */
-      select_printf ("fd %d, %s, NtQueryInformationFile failed",
-                    fd, fh->get_name ());
-      res = writing ? true : -1;
-    }
-  else if (!writing)
-    {
-      res = !!fpli.ReadDataAvailable;
-      paranoid_printf ("fd %d, %s, read avail %u", fd, fh->get_name (), fpli.ReadDataAvailable);
-    }
-  else
-    {
-      /* If there is anything available in the pipe buffer then signal
-        that.  This means that a pipe could still block since you could
-        be trying to write more to the pipe than is available in the
-        buffer but that is the hazard of select().  */
-      if ((fpli.WriteQuotaAvailable = (fpli.OutboundQuota - fpli.ReadDataAvailable)))
+      if (NtQueryInformationFile (h,
+                                 &iosb,
+                                 &fpli,
+                                 sizeof (fpli),
+                                 FilePipeLocalInformation))
+       {
+         /* If NtQueryInformationFile fails, optimistically assume the
+            pipe is writable.  This could happen if we somehow
+            inherit a pipe that doesn't permit FILE_READ_ATTRIBUTES
+            access on the write end.  */
+         select_printf ("fd %d, %s, NtQueryInformationFile failed",
+                        fd, fh->get_name ());
+         res = writing ? true : -1;
+       }
+      else if (!writing)
        {
-         paranoid_printf ("fd %d, %s, write: size %lu, avail %lu", fd,
-                        fh->get_name (), fpli.OutboundQuota,
-                        fpli.WriteQuotaAvailable);
-         res = true;
+         res = !!fpli.ReadDataAvailable;
+         paranoid_printf ("fd %d, %s, read avail %u", fd, fh->get_name (), fpli.ReadDataAvailable);
        }
-      /* If we somehow inherit a tiny pipe (size < PIPE_BUF), then consider
-        the pipe writable only if it is completely empty, to minimize the
-        probability that a subsequent write will block.  */
-      else if (fpli.OutboundQuota < PIPE_BUF &&
-              fpli.WriteQuotaAvailable == fpli.OutboundQuota)
+      else
        {
-         select_printf ("fd, %s, write tiny pipe: size %lu, avail %lu",
-                        fd, fh->get_name (), fpli.OutboundQuota,
-                        fpli.WriteQuotaAvailable);
-         res = true;
+         /* If there is anything available in the pipe buffer then signal
+            that.  This means that a pipe could still block since you could
+            be trying to write more to the pipe than is available in the
+            buffer but that is the hazard of select().  */
+         if ((fpli.WriteQuotaAvailable = (fpli.OutboundQuota - fpli.ReadDataAvailable)))
+           {
+             paranoid_printf ("fd %d, %s, write: size %lu, avail %lu", fd,
+                            fh->get_name (), fpli.OutboundQuota,
+                            fpli.WriteQuotaAvailable);
+             res = true;
+           }
+         /* If we somehow inherit a tiny pipe (size < PIPE_BUF), then consider
+            the pipe writable only if it is completely empty, to minimize the
+            probability that a subsequent write will block.  */
+         else if (fpli.OutboundQuota < PIPE_BUF &&
+                  fpli.WriteQuotaAvailable == fpli.OutboundQuota)
+           {
+             select_printf ("fd, %s, write tiny pipe: size %lu, avail %lu",
+                            fd, fh->get_name (), fpli.OutboundQuota,
+                            fpli.WriteQuotaAvailable);
+             res = true;
+           }
        }
     }
   return res ?: -!!(fpli.NamedPipeState & FILE_PIPE_CLOSING_STATE);
index fac5088..d5c9616 100644 (file)
@@ -1135,7 +1135,10 @@ static bool __stdcall
 remove_proc (int ci)
 {
   if (have_execed)
-    procs[ci].wait_thread->terminate_thread ();
+    {
+      if (_my_tls._ctinfo != procs[ci].wait_thread)
+       procs[ci].wait_thread->terminate_thread ();
+    }
   else if (procs[ci]->exists ())
     return true;
 
index 35c4b3f..8ca0b0e 100644 (file)
@@ -111,6 +111,7 @@ close_all_files (bool norelease)
   if (!have_execed && cygheap->ctty)
     cygheap->close_ctty ();
 
+  fhandler_base_overlapped::flush_all_async_io ();
   if (h)
     SetStdHandle (STD_ERROR_HANDLE, h);
   cygheap->fdtab.unlock ();
index deb8e20..38e57ca 100644 (file)
@@ -15,7 +15,7 @@ details. */
 #define INP_BUFFER_SIZE 256
 #define OUT_BUFFER_SIZE 256
 #define NTTYS          64
-#define real_tty_attached(p)   ((p)->ctty >= 0 && !iscons_dev ((p)->ctty))
+#define real_tty_attached(p)   ((p)->ctty > 0 && !iscons_dev ((p)->ctty))
 
 /* Input/Output/ioctl events */