diff options
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/ChangeLog | 5 | ||||
-rw-r--r-- | winsup/cygwin/cygheap.cc | 28 | ||||
-rw-r--r-- | winsup/cygwin/cygheap_malloc.h | 4 | ||||
-rw-r--r-- | winsup/cygwin/fhandler.cc | 94 | ||||
-rw-r--r-- | winsup/cygwin/fhandler.h | 137 | ||||
-rw-r--r-- | winsup/cygwin/select.cc | 79 | ||||
-rw-r--r-- | winsup/cygwin/sigproc.cc | 5 | ||||
-rw-r--r-- | winsup/cygwin/syscalls.cc | 1 | ||||
-rw-r--r-- | winsup/cygwin/tty.h | 2 |
9 files changed, 219 insertions, 136 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index b2a66fddc..5cb4a38ca 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -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* diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index 554375943..fabb68072 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -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 */ } } diff --git a/winsup/cygwin/cygheap_malloc.h b/winsup/cygwin/cygheap_malloc.h index 12ed4bd76..ef260ecce 100644 --- a/winsup/cygwin/cygheap_malloc.h +++ b/winsup/cygwin/cygheap_malloc.h @@ -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" { diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 98c6bb954..08f404cb8 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -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; diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index e94a8bf2f..a6e183456 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -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; diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index c3d3c950d..d92642b21 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -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); diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index fac5088a6..d5c96168a 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -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; diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 35c4b3fd7..8ca0b0e1b 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -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 (); diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h index deb8e207b..38e57caba 100644 --- a/winsup/cygwin/tty.h +++ b/winsup/cygwin/tty.h @@ -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 */ |