From 9a8597c13affb2f0e2a18cc808f9edf4d9b03d8c Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Tue, 23 Dec 2008 18:22:33 +0000 Subject: [PATCH] * fhandler.h (fhandler_base_setup_overlapped): Add new argument. (fhandler_base::get_overlapped_buffer): Declare new function. (fhandler_base::set_overlapped): Ditto. (fhandler_pipe::overlapped): New variable. (fhandler_pipe::get_overlapped): Rework to return contents of overlapped variable. (fhandler_pipe::set_overlapped): Set overlapped variable based on argument. (fhandler_fifo::get_overlapped_buffer): Return pointer to io_status. * fhandler.cc (handler_base::setup_overlapped): Set to overlapped pointer to NULL if new doit parameter is false. Otherwise set up overlapped event as usual. (fhandler_base::wait_overlapped): Return inres if this isn't an overlapped operation. (fhandler_base::read_overlapped): Remove inappropriate asserts. * pipe.cc (fhandler_pipe::fhandler_pipe): Zero overlapped element. (struct pipesync): Delete. (getov_result): Ditto. (pipe_handler): Ditto. (pipesync::pipesync): Ditto. (fhandler_pipe::init): Don't set up pipesync thread. Just pass opened_properly flag along to overlapped setup. --- winsup/cygwin/ChangeLog | 27 +++++++- winsup/cygwin/fhandler.cc | 24 +++++-- winsup/cygwin/fhandler.h | 12 +++- winsup/cygwin/pipe.cc | 135 +------------------------------------- 4 files changed, 55 insertions(+), 143 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index e40be0aab..8068c0735 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,28 @@ +2008-12-23 Christopher Faylor + + * fhandler.h (fhandler_base_setup_overlapped): Add new argument. + (fhandler_base::get_overlapped_buffer): Declare new function. + (fhandler_base::set_overlapped): Ditto. + (fhandler_pipe::overlapped): New variable. + (fhandler_pipe::get_overlapped): Rework to return contents of + overlapped variable. + (fhandler_pipe::set_overlapped): Set overlapped variable based on + argument. + (fhandler_fifo::get_overlapped_buffer): Return pointer to io_status. + * fhandler.cc (handler_base::setup_overlapped): Set to overlapped + pointer to NULL if new doit parameter is false. Otherwise set up + overlapped event as usual. + (fhandler_base::wait_overlapped): Return inres if this isn't an + overlapped operation. + (fhandler_base::read_overlapped): Remove inappropriate asserts. + * pipe.cc (fhandler_pipe::fhandler_pipe): Zero overlapped element. + (struct pipesync): Delete. + (getov_result): Ditto. + (pipe_handler): Ditto. + (pipesync::pipesync): Ditto. + (fhandler_pipe::init): Don't set up pipesync thread. Just pass + opened_properly flag along to overlapped setup. + 2008-12-22 Christopher Faylor * pipe.cc (getov_result): Minor cleanup. @@ -66,7 +91,7 @@ 2008-12-18 Corinna Vinschen * fhandler_disk_file.cc: Set 4th parameter of NtQueryDirectoryFile to - NULL throughout. + NULL throughout. (fhandler_disk_file::facl): Fix a condition so that fstat_by_handle is actually used. (fhandler_disk_file::readdir): Don't print debug message on a simple diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index b573e4eca..cb2877dd8 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1661,11 +1661,22 @@ fhandler_base::fpathconf (int v) /* Overlapped I/O */ bool -fhandler_base::setup_overlapped () +fhandler_base::setup_overlapped (bool doit) { - OVERLAPPED *ov = get_overlapped (); + OVERLAPPED *ov = get_overlapped_buffer (); memset (ov, 0, sizeof (*ov)); - return (ov->hEvent = CreateEvent (&sec_none_nih, true, false, NULL)); + bool res; + if (doit) + { + set_overlapped (ov); + res = !!(ov->hEvent = CreateEvent (&sec_none_nih, true, false, NULL)); + } + else + { + set_overlapped (NULL); + res = false; + } + return res; } void @@ -1682,6 +1693,9 @@ fhandler_base::destroy_overlapped () int fhandler_base::wait_overlapped (bool inres, bool writing, DWORD *bytes) { + if (!get_overlapped ()) + return inres; + int res = 0; *bytes = (DWORD) -1; DWORD err; @@ -1753,10 +1767,6 @@ fhandler_base::wait_overlapped (bool inres, bool writing, DWORD *bytes) void fhandler_base::read_overlapped (void *ptr, size_t& len) { -#ifdef DEBUGGING - assert (get_overlapped ()); - assert (get_overlapped ()->hEvent); -#endif while (1) { bool res = ReadFile (get_handle (), ptr, len, (DWORD *) &len, diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index fdaf7d577..c98a7d533 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -144,7 +144,7 @@ class fhandler_base HANDLE read_state; int wait_overlapped (bool, bool, DWORD *) __attribute__ ((regparm (3))); - bool setup_overlapped () __attribute__ ((regparm (1))); + bool setup_overlapped (bool doit = true) __attribute__ ((regparm (2))); void destroy_overlapped () __attribute__ ((regparm (1))); public: @@ -344,6 +344,8 @@ class fhandler_base virtual void raw_read (void *ptr, size_t& ulen); virtual int raw_write (const void *ptr, size_t ulen); virtual OVERLAPPED *get_overlapped () {return NULL;} + virtual OVERLAPPED *get_overlapped_buffer () {return NULL;} + virtual void set_overlapped (OVERLAPPED *) {} /* Virtual accessor functions to hide the fact that some fd's have two handles. */ @@ -532,9 +534,14 @@ class fhandler_pipe: public fhandler_base private: pid_t popen_pid; OVERLAPPED io_status; + OVERLAPPED *overlapped; public: fhandler_pipe (); - OVERLAPPED *get_overlapped () {return &io_status;} + + OVERLAPPED *get_overlapped () {return overlapped;} + OVERLAPPED *get_overlapped_buffer () {return &io_status;} + void set_overlapped (OVERLAPPED *ov) {overlapped = ov;} + void set_popen_pid (pid_t pid) {popen_pid = pid;} pid_t get_popen_pid () const {return popen_pid;} _off64_t lseek (_off64_t offset, int whence); @@ -577,6 +584,7 @@ public: bool isfifo () { return true; } int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2))); OVERLAPPED *get_overlapped () {return &io_status;} + OVERLAPPED *get_overlapped_buffer () {return &io_status;} }; class fhandler_dev_raw: public fhandler_base diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc index cfc3f0410..43b34b6f4 100644 --- a/winsup/cygwin/pipe.cc +++ b/winsup/cygwin/pipe.cc @@ -23,136 +23,11 @@ details. */ #include "pinfo.h" fhandler_pipe::fhandler_pipe () - : fhandler_base (), popen_pid (0) + : fhandler_base (), popen_pid (0), overlapped (NULL) { - get_overlapped ()->hEvent = NULL; need_fork_fixup (true); } -struct pipesync -{ - bool reader; - HANDLE ev, non_cygwin_h, ret_handle; - pipesync(HANDLE, DWORD); - int operator == (int x) const {return !!ev;} - static DWORD WINAPI handler (LPVOID *); -}; - -inline bool -getov_result (BOOL res, bool reading, HANDLE h, DWORD& nbytes, LPOVERLAPPED ov) -{ - DWORD err = GetLastError (); - if (res || (reading && ov && err == ERROR_HANDLE_EOF)) - /* not an error */; - else if (!ov || (err != ERROR_IO_PENDING) - || (!GetOverlappedResult (h, ov, &nbytes, true) - && (!reading || (GetLastError () != ERROR_HANDLE_EOF)))) - { - __seterrno (); - return false; - } - return true; -} - -static DWORD WINAPI -pipe_handler (LPVOID in_ps) -{ - pipesync ps = *(pipesync *) in_ps; - HANDLE h, in, out; - DWORD err = fhandler_pipe::create_selectable (&sec_none_nih, in, out, 0); - if (err) - { - SetLastError (err); - system_printf ("couldn't create a shadow pipe for non-cygwin pipe I/O, %E"); - return 0; - } - h = ((pipesync *) in_ps)->ret_handle = ps.reader ? in : out; - SetHandleInformation (h, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); - SetEvent (ps.ev); - - DWORD read_bytes, write_bytes; - HANDLE hread, hwrite, hclose; - OVERLAPPED ov, *rov, *wov; - memset (&ov, 0, sizeof (ov)); - ov.hEvent = CreateEvent (&sec_none_nih, true, false, NULL); - if (ps.reader) - { - hread = ps.non_cygwin_h; - hclose = hwrite = out; - wov = &ov; - rov = NULL; - } - else - { - hclose = hread = in; - hwrite = ps.non_cygwin_h; - rov = &ov; - wov = NULL; - } - - char buf[4096]; - while (1) - { - ResetEvent (ov.hEvent); - BOOL res = ReadFile (hread, buf, 4096, &read_bytes, rov); - if (!getov_result (res, true, hread, read_bytes, rov)) - break; - if (!read_bytes) - break; - - res = WriteFile (hwrite, buf, read_bytes, &write_bytes, wov); - if (!getov_result (res, false, hwrite, write_bytes, wov)) - break; - if (write_bytes != read_bytes) - break; - } - - err = GetLastError (); - CloseHandle (ov.hEvent); - CloseHandle (hclose); - CloseHandle (ps.non_cygwin_h); - SetLastError (err); - return 0; -} - -pipesync::pipesync (HANDLE f, DWORD is_reader): - reader (false), ret_handle (NULL) -{ - ev = CreateEvent (&sec_none_nih, true, false, NULL); - if (!ev) - system_printf ("couldn't create synchronization event for non-cygwin pipe, %E"); - else - { - debug_printf ("created thread synchronization event %p", ev); - non_cygwin_h = f; - reader = !!is_reader; - ret_handle = NULL; - - DWORD tid; - HANDLE ht = CreateThread (&sec_none_nih, 0, pipe_handler, this, 0, &tid); - - if (!ht) - goto out; - CloseHandle (ht); - - switch (WaitForSingleObject (ev, INFINITE)) - { - case WAIT_OBJECT_0: - break; - default: - system_printf ("WFSO failed waiting for synchronization event for non-cygwin pipe, %E"); - break; - } - } - -out: - if (ev) - { - CloseHandle (ev); - ev = NULL; - } -} - void fhandler_pipe::init (HANDLE f, DWORD a, mode_t mode) { @@ -173,16 +48,10 @@ fhandler_pipe::init (HANDLE f, DWORD a, mode_t mode) bool opened_properly = a & FILE_CREATE_PIPE_INSTANCE; a &= ~FILE_CREATE_PIPE_INSTANCE; - if (!opened_properly) - { - pipesync ps (f, a & GENERIC_READ); - f = ps.ret_handle; - } - fhandler_base::init (f, a, mode); if (mode & O_NOINHERIT) close_on_exec (true); - setup_overlapped (); + setup_overlapped (opened_properly); } extern "C" int sscanf (const char *, const char *, ...);