* errno.cc (errmap): Change mapping of NO_SYSTEM_RESOURCES to EFBIG.
* fhandler.cc (MAX_OVERLAPPED_WRITE_LEN): New constant. (MIN_OVERLAPPED_WRITE_LEN): Ditto. (fhandler_base_overlapped::close): Accommodate change in arguments to wait_overlapped. (fhandler_base_overlapped::setup_overlapped): Add __stdcall and regparm modifiers. (fhandler_base_overlapped::destroy_overlapped): Ditto. (fhandler_base_overlapped::has_ongoing_io): Ditto. (fhandler_base_overlapped::wait_overlapped): Modify to return an enum returning various states. Accept nonblocking parameter. (fhandler_base_overlapped::read_overlapped): Add __stdcall and regparm modifiers. Rework to attempt to be smarter about reacting to states returned by wait_overlapped. (fhandler_base_overlapped::write_overlapped): Ditto. Add fallback option for when wait_overlapped detects that smaller chunks must be written. (fhandler_base_overlapped::write_overlapped_fallback): Ditto. * fhandler.h (DEFAULT_PIPEBUFSIZE): Move definition here from pipe.cc. (fhandler_base::has_ongoing_io): Define with __stdcall and regparm modifiers. (fhandler_base_overlapped::wait_return): New enum. (fhandler_base_overlapped::max_atomic_write): New variable. (fhandler_base_overlapped:: wait_overlapped): Accommodate changes mentioned above to arguments and modifiers. (fhandler_base_overlapped::setup_overlapped): Ditto for modifiers. (fhandler_base_overlapped::read_overlapped): Ditto. (fhandler_base_overlapped::write_overlapped): Ditto. (fhandler_base_overlapped::destroy_overlapped): Ditto. (fhandler_base_overlapped::has_ongoing_io): Ditto. (fhandler_base_overlapped::fhandler_base_overlapped): Zero max_atomic_write. * fhandler_fifo.cc (fhandler_fifo::fhandler_fifo): Set max_atomic_write to the size of the DEFAULT_PIPEBUFSIZE. (fhandler_fifo::wait): Accommodate change in arguments to wait_overlapped. * pipe.cc (fhandler_pipe::fhandler_pipe): Set max_atomic_write to the size of the DEFAULT_PIPEBUFSIZE. (fhandler_pipe::create_selectable): Allow minimum size of DEFAULT_PIPEBUFSIZE. (DEFAULT_PIPEBUFSIZE): Delete here, move to fhandler.h.
This commit is contained in:
parent
e7b5eaaac9
commit
779ece3ce0
|
@ -1,3 +1,46 @@
|
||||||
|
2011-03-09 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
|
* errno.cc (errmap): Change mapping of NO_SYSTEM_RESOURCES to EFBIG.
|
||||||
|
* fhandler.cc (MAX_OVERLAPPED_WRITE_LEN): New constant.
|
||||||
|
(MIN_OVERLAPPED_WRITE_LEN): Ditto.
|
||||||
|
(fhandler_base_overlapped::close): Accommodate change in arguments to
|
||||||
|
wait_overlapped.
|
||||||
|
(fhandler_base_overlapped::setup_overlapped): Add __stdcall and regparm
|
||||||
|
modifiers.
|
||||||
|
(fhandler_base_overlapped::destroy_overlapped): Ditto.
|
||||||
|
(fhandler_base_overlapped::has_ongoing_io): Ditto.
|
||||||
|
(fhandler_base_overlapped::wait_overlapped): Modify to return an enum
|
||||||
|
returning various states. Accept nonblocking parameter.
|
||||||
|
(fhandler_base_overlapped::read_overlapped): Add __stdcall and regparm
|
||||||
|
modifiers. Rework to attempt to be smarter about reacting to states
|
||||||
|
returned by wait_overlapped.
|
||||||
|
(fhandler_base_overlapped::write_overlapped): Ditto. Add fallback
|
||||||
|
option for when wait_overlapped detects that smaller chunks must be
|
||||||
|
written.
|
||||||
|
(fhandler_base_overlapped::write_overlapped_fallback): Ditto.
|
||||||
|
* fhandler.h (DEFAULT_PIPEBUFSIZE): Move definition here from pipe.cc.
|
||||||
|
(fhandler_base::has_ongoing_io): Define with __stdcall and regparm
|
||||||
|
modifiers.
|
||||||
|
(fhandler_base_overlapped::wait_return): New enum.
|
||||||
|
(fhandler_base_overlapped::max_atomic_write): New variable.
|
||||||
|
(fhandler_base_overlapped:: wait_overlapped): Accommodate changes
|
||||||
|
mentioned above to arguments and modifiers.
|
||||||
|
(fhandler_base_overlapped::setup_overlapped): Ditto for modifiers.
|
||||||
|
(fhandler_base_overlapped::read_overlapped): Ditto.
|
||||||
|
(fhandler_base_overlapped::write_overlapped): Ditto.
|
||||||
|
(fhandler_base_overlapped::destroy_overlapped): Ditto.
|
||||||
|
(fhandler_base_overlapped::has_ongoing_io): Ditto.
|
||||||
|
(fhandler_base_overlapped::fhandler_base_overlapped): Zero
|
||||||
|
max_atomic_write.
|
||||||
|
* fhandler_fifo.cc (fhandler_fifo::fhandler_fifo): Set max_atomic_write
|
||||||
|
to the size of the DEFAULT_PIPEBUFSIZE.
|
||||||
|
(fhandler_fifo::wait): Accommodate change in arguments to
|
||||||
|
wait_overlapped.
|
||||||
|
* pipe.cc (fhandler_pipe::fhandler_pipe): Set max_atomic_write to the
|
||||||
|
size of the DEFAULT_PIPEBUFSIZE.
|
||||||
|
(fhandler_pipe::create_selectable): Allow minimum size of DEFAULT_PIPEBUFSIZE.
|
||||||
|
(DEFAULT_PIPEBUFSIZE): Delete here, move to fhandler.h.
|
||||||
|
|
||||||
2011-03-08 Corinna Vinschen <corinna@vinschen.de>
|
2011-03-08 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* security.cc: Fix copyright dates.
|
* security.cc: Fix copyright dates.
|
||||||
|
|
|
@ -118,7 +118,7 @@ static NO_COPY struct
|
||||||
X (NO_MORE_SEARCH_HANDLES, ENFILE),
|
X (NO_MORE_SEARCH_HANDLES, ENFILE),
|
||||||
X (NO_PROC_SLOTS, EAGAIN),
|
X (NO_PROC_SLOTS, EAGAIN),
|
||||||
X (NO_SIGNAL_SENT, EIO),
|
X (NO_SIGNAL_SENT, EIO),
|
||||||
X (NO_SYSTEM_RESOURCES, EAGAIN),
|
X (NO_SYSTEM_RESOURCES, EFBIG),
|
||||||
X (NO_TOKEN, EINVAL),
|
X (NO_TOKEN, EINVAL),
|
||||||
X (OPEN_FAILED, EIO),
|
X (OPEN_FAILED, EIO),
|
||||||
X (OPEN_FILES, EAGAIN),
|
X (OPEN_FILES, EAGAIN),
|
||||||
|
|
|
@ -29,6 +29,9 @@ details. */
|
||||||
#include "cygtls.h"
|
#include "cygtls.h"
|
||||||
#include "sigproc.h"
|
#include "sigproc.h"
|
||||||
|
|
||||||
|
#define MAX_OVERLAPPED_WRITE_LEN (64 * 1024 * 1024)
|
||||||
|
#define MIN_OVERLAPPED_WRITE_LEN (1 * 1024 * 1024)
|
||||||
|
|
||||||
static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
|
static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
|
||||||
|
|
||||||
struct __cygwin_perfile *perfile_table;
|
struct __cygwin_perfile *perfile_table;
|
||||||
|
@ -1056,8 +1059,7 @@ fhandler_base_overlapped::close ()
|
||||||
if (is_nonblocking () && io_pending)
|
if (is_nonblocking () && io_pending)
|
||||||
{
|
{
|
||||||
DWORD bytes;
|
DWORD bytes;
|
||||||
set_nonblocking (false);
|
wait_overlapped (1, !!(get_access () & GENERIC_WRITE), &bytes, false);
|
||||||
wait_overlapped (1, !!(get_access () & GENERIC_WRITE), &bytes);
|
|
||||||
}
|
}
|
||||||
destroy_overlapped ();
|
destroy_overlapped ();
|
||||||
return fhandler_base::close ();
|
return fhandler_base::close ();
|
||||||
|
@ -1686,7 +1688,7 @@ fhandler_base::fpathconf (int v)
|
||||||
|
|
||||||
/* Overlapped I/O */
|
/* Overlapped I/O */
|
||||||
|
|
||||||
int
|
int __stdcall __attribute__ ((regparm (1)))
|
||||||
fhandler_base_overlapped::setup_overlapped ()
|
fhandler_base_overlapped::setup_overlapped ()
|
||||||
{
|
{
|
||||||
OVERLAPPED *ov = get_overlapped_buffer ();
|
OVERLAPPED *ov = get_overlapped_buffer ();
|
||||||
|
@ -1696,7 +1698,7 @@ fhandler_base_overlapped::setup_overlapped ()
|
||||||
return ov->hEvent ? 0 : -1;
|
return ov->hEvent ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void __stdcall __attribute__ ((regparm (1)))
|
||||||
fhandler_base_overlapped::destroy_overlapped ()
|
fhandler_base_overlapped::destroy_overlapped ()
|
||||||
{
|
{
|
||||||
OVERLAPPED *ov = get_overlapped ();
|
OVERLAPPED *ov = get_overlapped ();
|
||||||
|
@ -1709,7 +1711,7 @@ fhandler_base_overlapped::destroy_overlapped ()
|
||||||
get_overlapped () = NULL;
|
get_overlapped () = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool __stdcall __attribute__ ((regparm (1)))
|
||||||
fhandler_base_overlapped::has_ongoing_io ()
|
fhandler_base_overlapped::has_ongoing_io ()
|
||||||
{
|
{
|
||||||
if (!io_pending)
|
if (!io_pending)
|
||||||
|
@ -1723,27 +1725,25 @@ fhandler_base_overlapped::has_ongoing_io ()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
fhandler_base_overlapped::wait_return __stdcall __attribute__ ((regparm (3)))
|
||||||
fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *bytes, DWORD len)
|
fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *bytes, bool nonblocking, DWORD len)
|
||||||
{
|
{
|
||||||
if (!get_overlapped ())
|
if (!get_overlapped ())
|
||||||
return inres;
|
return inres ? overlapped_success : overlapped_error;
|
||||||
|
|
||||||
int res = 0;
|
|
||||||
|
|
||||||
DWORD err = GetLastError ();
|
DWORD err = GetLastError ();
|
||||||
if (is_nonblocking ())
|
if (err == ERROR_NO_SYSTEM_RESOURCES)
|
||||||
|
return overlapped_fallback;
|
||||||
|
|
||||||
|
wait_return res = overlapped_error;
|
||||||
|
if (nonblocking)
|
||||||
{
|
{
|
||||||
if (inres || err == ERROR_IO_PENDING)
|
if (inres || err == ERROR_IO_PENDING)
|
||||||
{
|
{
|
||||||
io_pending = err == ERROR_IO_PENDING;
|
io_pending = err == ERROR_IO_PENDING;
|
||||||
if (writing && !inres)
|
if (writing && !inres)
|
||||||
*bytes = len; /* This really isn't true but it seems like
|
*bytes = len;
|
||||||
this is a corner-case for linux's
|
res = overlapped_success;
|
||||||
non-blocking I/O implementation. How can
|
|
||||||
you know how many bytes were written until
|
|
||||||
the I/O operation really completes? */
|
|
||||||
res = 1;
|
|
||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1768,9 +1768,11 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte
|
||||||
if (signalled)
|
if (signalled)
|
||||||
{
|
{
|
||||||
debug_printf ("got a signal");
|
debug_printf ("got a signal");
|
||||||
|
if (!_my_tls.call_signal_handler ())
|
||||||
set_errno (EINTR);
|
set_errno (EINTR);
|
||||||
|
else
|
||||||
|
res = overlapped_signal;
|
||||||
*bytes = (DWORD) -1;
|
*bytes = (DWORD) -1;
|
||||||
res = 0;
|
|
||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
else if (!wores)
|
else if (!wores)
|
||||||
|
@ -1781,7 +1783,7 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debug_printf ("normal %s, %u bytes", writing ? "write" : "read", *bytes);
|
debug_printf ("normal %s, %u bytes", writing ? "write" : "read", *bytes);
|
||||||
res = 1;
|
res = overlapped_success;
|
||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1793,14 +1795,13 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte
|
||||||
debug_printf ("err %u", err);
|
debug_printf ("err %u", err);
|
||||||
__seterrno_from_win_error (err);
|
__seterrno_from_win_error (err);
|
||||||
*bytes = (DWORD) -1;
|
*bytes = (DWORD) -1;
|
||||||
res = 0;
|
res = overlapped_error;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = 1;
|
|
||||||
*bytes = 0;
|
|
||||||
err = 0;
|
|
||||||
debug_printf ("EOF");
|
debug_printf ("EOF");
|
||||||
|
*bytes = 0;
|
||||||
|
res = overlapped_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writing && (err == ERROR_NO_DATA || err == ERROR_BROKEN_PIPE))
|
if (writing && (err == ERROR_NO_DATA || err == ERROR_BROKEN_PIPE))
|
||||||
|
@ -1808,39 +1809,119 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __stdcall
|
void __stdcall __attribute__ ((regparm (3)))
|
||||||
fhandler_base_overlapped::read_overlapped (void *ptr, size_t& len)
|
fhandler_base_overlapped::read_overlapped (void *ptr, size_t& len)
|
||||||
{
|
{
|
||||||
DWORD nbytes;
|
DWORD nbytes;
|
||||||
if (has_ongoing_io ())
|
if (has_ongoing_io ())
|
||||||
nbytes = (DWORD) -1;
|
nbytes = (DWORD) -1;
|
||||||
else
|
else
|
||||||
while (1)
|
{
|
||||||
|
bool keep_looping;
|
||||||
|
do
|
||||||
{
|
{
|
||||||
bool res = ReadFile (get_handle (), ptr, len, &nbytes,
|
bool res = ReadFile (get_handle (), ptr, len, &nbytes,
|
||||||
get_overlapped ());
|
get_overlapped ());
|
||||||
int wres = wait_overlapped (res, false, &nbytes);
|
switch (wait_overlapped (res, false, &nbytes, is_nonblocking ()))
|
||||||
if (wres || !_my_tls.call_signal_handler ())
|
{
|
||||||
|
case overlapped_signal:
|
||||||
|
keep_looping = true;
|
||||||
break;
|
break;
|
||||||
|
default: /* Added to quiet gcc */
|
||||||
|
case overlapped_success:
|
||||||
|
case overlapped_error:
|
||||||
|
case overlapped_fallback:
|
||||||
|
keep_looping = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (keep_looping);
|
||||||
}
|
}
|
||||||
len = (size_t) nbytes;
|
len = (size_t) nbytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t __stdcall
|
ssize_t __stdcall __attribute__ ((regparm (3)))
|
||||||
fhandler_base_overlapped::write_overlapped (const void *ptr, size_t len)
|
fhandler_base_overlapped::write_overlapped (const void *ptr, size_t len)
|
||||||
{
|
{
|
||||||
DWORD nbytes;
|
DWORD nbytes;
|
||||||
if (has_ongoing_io ())
|
if (has_ongoing_io ())
|
||||||
nbytes = (DWORD) -1;
|
nbytes = (DWORD) -1;
|
||||||
else
|
else
|
||||||
while (1)
|
{
|
||||||
|
bool keep_looping;
|
||||||
|
if (is_nonblocking () && max_atomic_write && len > max_atomic_write)
|
||||||
|
len = max_atomic_write;
|
||||||
|
do
|
||||||
{
|
{
|
||||||
bool res = WriteFile (get_output_handle (), ptr, len, &nbytes,
|
bool res = WriteFile (get_output_handle (), ptr, len, &nbytes,
|
||||||
get_overlapped ());
|
get_overlapped ());
|
||||||
int wres = wait_overlapped (res, true, &nbytes, (size_t) len);
|
switch (wait_overlapped (res, true, &nbytes, (size_t) len))
|
||||||
if (wres || !_my_tls.call_signal_handler ())
|
{
|
||||||
|
case overlapped_fallback:
|
||||||
|
nbytes = write_overlapped_fallback (ptr, len);
|
||||||
|
/* fall through intentionally */;
|
||||||
|
case overlapped_signal:
|
||||||
|
keep_looping = true;
|
||||||
break;
|
break;
|
||||||
|
default: /* Added to quiet gcc */
|
||||||
|
case overlapped_success:
|
||||||
|
case overlapped_error:
|
||||||
|
keep_looping = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (keep_looping);
|
||||||
}
|
}
|
||||||
debug_printf ("returning %u", nbytes);
|
debug_printf ("returning %u", nbytes);
|
||||||
return nbytes;
|
return nbytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* On XP (at least) the size of the buffer that can be used to write to a pipe
|
||||||
|
(pipes are currently the only thing using the overlapped methods) is
|
||||||
|
limited. This function is a fallback for when that problem is detected.
|
||||||
|
It writes to the pipe using smaller buffers but masks this behavior
|
||||||
|
to the caller. */
|
||||||
|
ssize_t __stdcall __attribute__ ((regparm (3)))
|
||||||
|
fhandler_base_overlapped::write_overlapped_fallback (const void *ptr, size_t orig_len)
|
||||||
|
{
|
||||||
|
size_t chunk;
|
||||||
|
if (orig_len > MAX_OVERLAPPED_WRITE_LEN)
|
||||||
|
chunk = MAX_OVERLAPPED_WRITE_LEN;
|
||||||
|
else if (orig_len > MIN_OVERLAPPED_WRITE_LEN)
|
||||||
|
chunk = MIN_OVERLAPPED_WRITE_LEN;
|
||||||
|
else
|
||||||
|
chunk = orig_len / 4;
|
||||||
|
ssize_t nbytes = 0;
|
||||||
|
DWORD nbytes_now = 0;
|
||||||
|
while ((size_t) nbytes < orig_len)
|
||||||
|
{
|
||||||
|
size_t left = orig_len - nbytes;
|
||||||
|
size_t len;
|
||||||
|
if (left > chunk)
|
||||||
|
len = chunk;
|
||||||
|
else
|
||||||
|
len = left;
|
||||||
|
bool res = WriteFile (get_output_handle (), ptr, len, &nbytes_now,
|
||||||
|
get_overlapped ());
|
||||||
|
/* The nonblocking case is not going to be used currently and may
|
||||||
|
eventually disappear. */
|
||||||
|
switch (wait_overlapped (res, true, &nbytes_now,
|
||||||
|
left <= chunk ? is_nonblocking () : false,
|
||||||
|
(size_t) len))
|
||||||
|
{
|
||||||
|
case overlapped_success:
|
||||||
|
nbytes += nbytes_now;
|
||||||
|
/* fall through intentionally */
|
||||||
|
case overlapped_signal:
|
||||||
|
break; /* keep looping */
|
||||||
|
case overlapped_error:
|
||||||
|
case overlapped_fallback: /* Could make this more adaptive
|
||||||
|
if needed */
|
||||||
|
orig_len = 0; /* terminate loop */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!nbytes)
|
||||||
|
nbytes = nbytes_now;
|
||||||
|
return nbytes;
|
||||||
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ details. */
|
||||||
Using this blocksize in read/write calls in the application results
|
Using this blocksize in read/write calls in the application results
|
||||||
in a much better performance than using smaller values. */
|
in a much better performance than using smaller values. */
|
||||||
#define PREFERRED_IO_BLKSIZE ((blksize_t) 65536)
|
#define PREFERRED_IO_BLKSIZE ((blksize_t) 65536)
|
||||||
|
#define DEFAULT_PIPEBUFSIZE PREFERRED_IO_BLKSIZE
|
||||||
|
|
||||||
extern const char *windows_device_names[];
|
extern const char *windows_device_names[];
|
||||||
extern struct __cygwin_perfile *perfile_table;
|
extern struct __cygwin_perfile *perfile_table;
|
||||||
|
@ -397,7 +398,7 @@ public:
|
||||||
bool issymlink () {return pc.issymlink ();}
|
bool issymlink () {return pc.issymlink ();}
|
||||||
bool device_access_denied (int) __attribute__ ((regparm (2)));
|
bool device_access_denied (int) __attribute__ ((regparm (2)));
|
||||||
int fhaccess (int flags, bool) __attribute__ ((regparm (3)));
|
int fhaccess (int flags, bool) __attribute__ ((regparm (3)));
|
||||||
virtual bool has_ongoing_io () {return false;}
|
virtual bool __stdcall has_ongoing_io () __attribute__ ((regparm (1))) {return false;}
|
||||||
};
|
};
|
||||||
|
|
||||||
class fhandler_mailslot : public fhandler_base
|
class fhandler_mailslot : public fhandler_base
|
||||||
|
@ -565,23 +566,33 @@ class fhandler_socket: public fhandler_base
|
||||||
class fhandler_base_overlapped: public fhandler_base
|
class fhandler_base_overlapped: public fhandler_base
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
enum wait_return
|
||||||
|
{
|
||||||
|
overlapped_success = 0,
|
||||||
|
overlapped_signal,
|
||||||
|
overlapped_error,
|
||||||
|
overlapped_fallback
|
||||||
|
};
|
||||||
bool io_pending;
|
bool io_pending;
|
||||||
OVERLAPPED io_status;
|
OVERLAPPED io_status;
|
||||||
OVERLAPPED *overlapped;
|
OVERLAPPED *overlapped;
|
||||||
|
size_t max_atomic_write;
|
||||||
public:
|
public:
|
||||||
int wait_overlapped (bool, bool, DWORD *, DWORD = 0) __attribute__ ((regparm (3)));
|
wait_return __stdcall wait_overlapped (bool, bool, DWORD *, bool, DWORD = 0) __attribute__ ((regparm (3)));
|
||||||
int setup_overlapped () __attribute__ ((regparm (1)));
|
int __stdcall setup_overlapped () __attribute__ ((regparm (1)));
|
||||||
void destroy_overlapped () __attribute__ ((regparm (1)));
|
void __stdcall destroy_overlapped () __attribute__ ((regparm (1)));
|
||||||
void __stdcall read_overlapped (void *ptr, size_t& len) __attribute__ ((regparm (3)));
|
void __stdcall read_overlapped (void *ptr, size_t& len) __attribute__ ((regparm (3)));
|
||||||
ssize_t __stdcall write_overlapped (const void *ptr, size_t len);
|
ssize_t __stdcall write_overlapped (const void *ptr, size_t len) __attribute__ ((regparm (3)));
|
||||||
|
ssize_t __stdcall write_overlapped_fallback (const void *ptr, size_t orig_len)
|
||||||
|
__attribute__ ((regparm (3)));
|
||||||
OVERLAPPED *&get_overlapped () {return overlapped;}
|
OVERLAPPED *&get_overlapped () {return overlapped;}
|
||||||
OVERLAPPED *get_overlapped_buffer () {return &io_status;}
|
OVERLAPPED *get_overlapped_buffer () {return &io_status;}
|
||||||
void set_overlapped (OVERLAPPED *ov) {overlapped = ov;}
|
void set_overlapped (OVERLAPPED *ov) {overlapped = ov;}
|
||||||
fhandler_base_overlapped (): io_pending (false), overlapped (NULL)
|
fhandler_base_overlapped (): io_pending (false), overlapped (NULL), max_atomic_write (0)
|
||||||
{
|
{
|
||||||
memset (&io_status, 0, sizeof io_status);
|
memset (&io_status, 0, sizeof io_status);
|
||||||
}
|
}
|
||||||
bool has_ongoing_io ();
|
bool __stdcall has_ongoing_io () __attribute__ ((regparm (1)));
|
||||||
|
|
||||||
void fixup_after_fork (HANDLE);
|
void fixup_after_fork (HANDLE);
|
||||||
void fixup_after_exec ();
|
void fixup_after_exec ();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* fhandler_fifo.cc - See fhandler.h for a description of the fhandler classes.
|
/* fhandler_fifo.cc - See fhandler.h for a description of the fhandler classes.
|
||||||
|
|
||||||
Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
|
Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||||
|
Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -24,6 +25,7 @@
|
||||||
fhandler_fifo::fhandler_fifo ():
|
fhandler_fifo::fhandler_fifo ():
|
||||||
fhandler_base_overlapped (), wait_state (fifo_unknown), dummy_client (NULL)
|
fhandler_base_overlapped (), wait_state (fifo_unknown), dummy_client (NULL)
|
||||||
{
|
{
|
||||||
|
max_atomic_write = DEFAULT_PIPEBUFSIZE;
|
||||||
need_fork_fixup (true);
|
need_fork_fixup (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +190,7 @@ fhandler_fifo::wait (bool iswrite)
|
||||||
int res = ConnectNamedPipe (get_handle (), get_overlapped ());
|
int res = ConnectNamedPipe (get_handle (), get_overlapped ());
|
||||||
if (GetLastError () != ERROR_NO_DATA && GetLastError () != ERROR_PIPE_CONNECTED)
|
if (GetLastError () != ERROR_NO_DATA && GetLastError () != ERROR_PIPE_CONNECTED)
|
||||||
{
|
{
|
||||||
res = wait_overlapped (res, iswrite, &dummy_bytes);
|
res = wait_overlapped (res, iswrite, &dummy_bytes, false);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
if (get_errno () != EINTR)
|
if (get_errno () != EINTR)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* pipe.cc: pipe for Cygwin.
|
/* pipe.cc: pipe for Cygwin.
|
||||||
|
|
||||||
Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
|
Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
|
||||||
2008, 2009, 2010 Hat, Inc.
|
2008, 2009, 2010, 2011 Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ details. */
|
||||||
fhandler_pipe::fhandler_pipe ()
|
fhandler_pipe::fhandler_pipe ()
|
||||||
: fhandler_base_overlapped (), popen_pid (0)
|
: fhandler_base_overlapped (), popen_pid (0)
|
||||||
{
|
{
|
||||||
|
max_atomic_write = DEFAULT_PIPEBUFSIZE;
|
||||||
need_fork_fixup (true);
|
need_fork_fixup (true);
|
||||||
uninterruptible_io (true);
|
uninterruptible_io (true);
|
||||||
}
|
}
|
||||||
|
@ -217,8 +218,8 @@ fhandler_pipe::create_selectable (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE& r,
|
||||||
r = w = INVALID_HANDLE_VALUE;
|
r = w = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
/* Ensure that there is enough pipe buffer space for atomic writes. */
|
/* Ensure that there is enough pipe buffer space for atomic writes. */
|
||||||
if (psize < PIPE_BUF)
|
if (psize < DEFAULT_PIPEBUFSIZE)
|
||||||
psize = PIPE_BUF;
|
psize = DEFAULT_PIPEBUFSIZE;
|
||||||
|
|
||||||
char pipename[MAX_PATH];
|
char pipename[MAX_PATH];
|
||||||
const size_t len = __small_sprintf (pipename, PIPE_INTRO "%S-",
|
const size_t len = __small_sprintf (pipename, PIPE_INTRO "%S-",
|
||||||
|
@ -373,8 +374,6 @@ fhandler_pipe::fstatvfs (struct statvfs *sfs)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFAULT_PIPEBUFSIZE 65536
|
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
pipe (int filedes[2])
|
pipe (int filedes[2])
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue