Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2011-03-13 23:20:58 +0300
committerChristopher Faylor <me@cgf.cx>2011-03-13 23:20:58 +0300
commit9636c4262e16846fb595d1fffa711ca4aa70dc47 (patch)
tree56b6dcfb435d0bab56385857c0923faaea4814b0 /winsup
parent7a9064faa5e409a77f59a9a26ec4168f800f234d (diff)
* fhandler.cc (fhandler_base_overlapped::wait_overlapped): Remove special
treatment for ERROR_NO_SYSTEM_RESOURCES. Cancel I/O and reset the overlapped handle on error. (fhandler_base_overlapped::write_overlapped): Limit writes to max_atomic_write bytes in blocking case. Incorporate code from now-defunct write_overlapped_fallback. Fix serious oversight where ptr was not advanced as buffer was written. (fhandler_base_overlapped::write_overlapped_fallback): Eliminate. * fhandler.h (fhandler_base_overlapped::write_overlapped_fallback): Ditto for declaration. (DEFAULT_PIPEBUFSIZE): Lower size to slightly less than documented worst-case atomic write size. (fhandler_overlapped::wait_return): Remove unused element.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog18
-rw-r--r--winsup/cygwin/fhandler.cc115
-rw-r--r--winsup/cygwin/fhandler.h6
3 files changed, 56 insertions, 83 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index a01d83b04..2ff87cb80 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,19 @@
+2011-03-13 Christopher Faylor <me.cygwin2011@cgf.cx>
+
+ * fhandler.cc (fhandler_base_overlapped::wait_overlapped): Remove
+ special treatment for ERROR_NO_SYSTEM_RESOURCES. Cancel I/O and reset
+ the overlapped handle on error.
+ (fhandler_base_overlapped::write_overlapped): Limit writes to
+ max_atomic_write bytes in blocking case. Incorporate code from
+ now-defunct write_overlapped_fallback. Fix serious oversight where ptr
+ was not advanced as buffer was written.
+ (fhandler_base_overlapped::write_overlapped_fallback): Eliminate.
+ * fhandler.h (fhandler_base_overlapped::write_overlapped_fallback):
+ Ditto for declaration.
+ (DEFAULT_PIPEBUFSIZE): Lower size to slightly less than documented
+ worst-case atomic write size.
+ (fhandler_overlapped::wait_return): Remove unused element.
+
2011-03-09 Christopher Faylor <me.cygwin2011@cgf.cx>
* fhandler.cc (fhandler_base_overlapped::wait_overlapped): Handle
@@ -10,7 +26,7 @@
(fhandler_base_overlapped::write_overlapped_fallback): Add some more
comments.
-2011-03-09 Christopher Faylor <me.cygwin@cgf.cx>
+2011-03-09 Christopher Faylor <me.cygwin2011@cgf.cx>
* fhandler.cc (fhandler_base_overlapped::write_overlapp): Oops!
Accommodate change in arguments to wait_overlapped.
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 56d2872cd..79c9a919e 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -1733,9 +1733,7 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte
wait_return res;
DWORD err = GetLastError ();
- if (err == ERROR_NO_SYSTEM_RESOURCES)
- res = overlapped_fallback;
- else if (nonblocking)
+ if (nonblocking)
{
if (!inres && err != ERROR_IO_PENDING)
res = overlapped_error;
@@ -1806,6 +1804,9 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte
else
{
debug_printf ("err %u", err);
+ HANDLE h = writing ? get_output_handle () : get_handle ();
+ CancelIo (h);
+ ResetEvent (get_overlapped ());
__seterrno_from_win_error (err);
*bytes = (DWORD) -1;
}
@@ -1836,7 +1837,6 @@ fhandler_base_overlapped::read_overlapped (void *ptr, size_t& len)
default: /* Added to quiet gcc */
case overlapped_success:
case overlapped_error:
- case overlapped_fallback:
keep_looping = false;
break;
}
@@ -1849,92 +1849,51 @@ fhandler_base_overlapped::read_overlapped (void *ptr, size_t& len)
ssize_t __stdcall __attribute__ ((regparm (3)))
fhandler_base_overlapped::write_overlapped (const void *ptr, size_t len)
{
- DWORD nbytes;
+ size_t nbytes;
if (has_ongoing_io ())
nbytes = (DWORD) -1;
else
{
- int last_errno = get_errno ();
- bool keep_looping;
- if (is_nonblocking () && max_atomic_write && len > max_atomic_write)
- len = max_atomic_write;
- do
+ size_t chunk;
+ if (!max_atomic_write || len < max_atomic_write)
+ chunk = len;
+ else if (is_nonblocking ())
+ chunk = len = max_atomic_write;
+ else
+ chunk = max_atomic_write;
+
+ nbytes = 0;
+ DWORD nbytes_now = 0;
+ /* Write to fd in smaller chunks, accumlating a total.
+ If there's an error, just return the accumulated total
+ unless the first write fails, in which case return value
+ from wait_overlapped(). */
+ while (nbytes < len)
{
- bool res = WriteFile (get_output_handle (), ptr, len, &nbytes,
+ size_t left = len - nbytes;
+ size_t len1;
+ if (left > chunk)
+ len1 = chunk;
+ else
+ len1 = left;
+ bool res = WriteFile (get_output_handle (), ptr, len1, &nbytes_now,
get_overlapped ());
- switch (wait_overlapped (res, true, &nbytes, is_nonblocking (), (size_t) len))
+ switch (wait_overlapped (res, true, &nbytes_now,
+ is_nonblocking (), len1))
{
- case overlapped_signal:
- keep_looping = true;
- break;
- case overlapped_fallback:
- set_errno (last_errno); /* Avoid setting a random EFBIG errno */
- nbytes = write_overlapped_fallback (ptr, len);
- /* fall through intentionally */;
- default: /* Added to quiet gcc */
case overlapped_success:
+ ptr = ((char *) ptr) + chunk;
+ nbytes += nbytes_now;
+ /* fall through intentionally */
+ case overlapped_signal:
+ break; /* keep looping */
case overlapped_error:
- keep_looping = false;
+ len = 0; /* terminate loop */
break;
}
}
- while (keep_looping);
- }
- debug_printf ("returning %u", 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;
- /* So far, in testing, only the first if test has been necessary */
- 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;
- /* Write to fd in smaller chunks, accumlating a total.
- If there's an error, just return the accumulated total
- unless the first write fails, in which case return value
- from wait_overlapped(). */
- 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: /* XXX Could make this more adaptive
- if needed */
- orig_len = 0; /* terminate loop */
- break;
- }
+ if (!nbytes)
+ nbytes = nbytes_now;
}
- if (!nbytes)
- nbytes = nbytes_now;
return nbytes;
}
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index ee08e5990..ffe8ee15e 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -29,7 +29,7 @@ details. */
Using this blocksize in read/write calls in the application results
in a much better performance than using smaller values. */
#define PREFERRED_IO_BLKSIZE ((blksize_t) 65536)
-#define DEFAULT_PIPEBUFSIZE PREFERRED_IO_BLKSIZE
+#define DEFAULT_PIPEBUFSIZE (31 * 1024 * 1024)
extern const char *windows_device_names[];
extern struct __cygwin_perfile *perfile_table;
@@ -570,8 +570,7 @@ protected:
{
overlapped_success = 0,
overlapped_signal,
- overlapped_error,
- overlapped_fallback
+ overlapped_error
};
bool io_pending;
OVERLAPPED io_status;
@@ -583,7 +582,6 @@ public:
void __stdcall destroy_overlapped () __attribute__ ((regparm (1)));
void __stdcall read_overlapped (void *ptr, size_t& len) __attribute__ ((regparm (3)));
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_buffer () {return &io_status;}