* 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.
This commit is contained in:
parent
a432f50100
commit
9a8597c13a
@ -1,3 +1,28 @@
|
|||||||
|
2008-12-23 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
|
* 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 <me+cygwin@cgf.cx>
|
2008-12-22 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
* pipe.cc (getov_result): Minor cleanup.
|
* pipe.cc (getov_result): Minor cleanup.
|
||||||
|
@ -1661,11 +1661,22 @@ fhandler_base::fpathconf (int v)
|
|||||||
/* Overlapped I/O */
|
/* Overlapped I/O */
|
||||||
|
|
||||||
bool
|
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));
|
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
|
void
|
||||||
@ -1682,6 +1693,9 @@ fhandler_base::destroy_overlapped ()
|
|||||||
int
|
int
|
||||||
fhandler_base::wait_overlapped (bool inres, bool writing, DWORD *bytes)
|
fhandler_base::wait_overlapped (bool inres, bool writing, DWORD *bytes)
|
||||||
{
|
{
|
||||||
|
if (!get_overlapped ())
|
||||||
|
return inres;
|
||||||
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
*bytes = (DWORD) -1;
|
*bytes = (DWORD) -1;
|
||||||
DWORD err;
|
DWORD err;
|
||||||
@ -1753,10 +1767,6 @@ fhandler_base::wait_overlapped (bool inres, bool writing, DWORD *bytes)
|
|||||||
void
|
void
|
||||||
fhandler_base::read_overlapped (void *ptr, size_t& len)
|
fhandler_base::read_overlapped (void *ptr, size_t& len)
|
||||||
{
|
{
|
||||||
#ifdef DEBUGGING
|
|
||||||
assert (get_overlapped ());
|
|
||||||
assert (get_overlapped ()->hEvent);
|
|
||||||
#endif
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
bool res = ReadFile (get_handle (), ptr, len, (DWORD *) &len,
|
bool res = ReadFile (get_handle (), ptr, len, (DWORD *) &len,
|
||||||
|
@ -144,7 +144,7 @@ class fhandler_base
|
|||||||
|
|
||||||
HANDLE read_state;
|
HANDLE read_state;
|
||||||
int wait_overlapped (bool, bool, DWORD *) __attribute__ ((regparm (3)));
|
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)));
|
void destroy_overlapped () __attribute__ ((regparm (1)));
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -344,6 +344,8 @@ class fhandler_base
|
|||||||
virtual void raw_read (void *ptr, size_t& ulen);
|
virtual void raw_read (void *ptr, size_t& ulen);
|
||||||
virtual int raw_write (const 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 () {return NULL;}
|
||||||
|
virtual OVERLAPPED *get_overlapped_buffer () {return NULL;}
|
||||||
|
virtual void set_overlapped (OVERLAPPED *) {}
|
||||||
|
|
||||||
/* Virtual accessor functions to hide the fact
|
/* Virtual accessor functions to hide the fact
|
||||||
that some fd's have two handles. */
|
that some fd's have two handles. */
|
||||||
@ -532,9 +534,14 @@ class fhandler_pipe: public fhandler_base
|
|||||||
private:
|
private:
|
||||||
pid_t popen_pid;
|
pid_t popen_pid;
|
||||||
OVERLAPPED io_status;
|
OVERLAPPED io_status;
|
||||||
|
OVERLAPPED *overlapped;
|
||||||
public:
|
public:
|
||||||
fhandler_pipe ();
|
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;}
|
void set_popen_pid (pid_t pid) {popen_pid = pid;}
|
||||||
pid_t get_popen_pid () const {return popen_pid;}
|
pid_t get_popen_pid () const {return popen_pid;}
|
||||||
_off64_t lseek (_off64_t offset, int whence);
|
_off64_t lseek (_off64_t offset, int whence);
|
||||||
@ -577,6 +584,7 @@ public:
|
|||||||
bool isfifo () { return true; }
|
bool isfifo () { return true; }
|
||||||
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
|
||||||
OVERLAPPED *get_overlapped () {return &io_status;}
|
OVERLAPPED *get_overlapped () {return &io_status;}
|
||||||
|
OVERLAPPED *get_overlapped_buffer () {return &io_status;}
|
||||||
};
|
};
|
||||||
|
|
||||||
class fhandler_dev_raw: public fhandler_base
|
class fhandler_dev_raw: public fhandler_base
|
||||||
|
@ -23,136 +23,11 @@ details. */
|
|||||||
#include "pinfo.h"
|
#include "pinfo.h"
|
||||||
|
|
||||||
fhandler_pipe::fhandler_pipe ()
|
fhandler_pipe::fhandler_pipe ()
|
||||||
: fhandler_base (), popen_pid (0)
|
: fhandler_base (), popen_pid (0), overlapped (NULL)
|
||||||
{
|
{
|
||||||
get_overlapped ()->hEvent = NULL;
|
|
||||||
need_fork_fixup (true);
|
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
|
void
|
||||||
fhandler_pipe::init (HANDLE f, DWORD a, mode_t mode)
|
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;
|
bool opened_properly = a & FILE_CREATE_PIPE_INSTANCE;
|
||||||
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);
|
fhandler_base::init (f, a, mode);
|
||||||
if (mode & O_NOINHERIT)
|
if (mode & O_NOINHERIT)
|
||||||
close_on_exec (true);
|
close_on_exec (true);
|
||||||
setup_overlapped ();
|
setup_overlapped (opened_properly);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int sscanf (const char *, const char *, ...);
|
extern "C" int sscanf (const char *, const char *, ...);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user