diff options
author | Christopher Faylor <me@cgf.cx> | 2011-12-18 08:07:47 +0400 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2011-12-18 08:07:47 +0400 |
commit | d004a279716433bf3dc8477bc838d490028d223d (patch) | |
tree | 31e07ddaf6d7fc259343f355df0395f0baba43a9 /winsup/cygwin | |
parent | 1b23b30b29eebbe7c9953f2a7470f31a0feb8702 (diff) |
* fhandler.cc (fhandler_base::close): Move setting isclosed() from here to
closed().
(fhandler_base_overlapped::close): Correct comment.
(fhandler_base_overlapped::destroy_overlapped): Signal overlapped event before
closing it to potentially wake up a waiting thread.
(fhandler_base_overlapped::wait_overlapped): Expand setting of err when closed
to encompass non-signal event. Test for a cancel event before making
nonblocking decisions.
* syscalls.cc (close): Set closed flag here so that any concurrently executing
functions will be notified ASAP.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r-- | winsup/cygwin/ChangeLog | 13 | ||||
-rw-r--r-- | winsup/cygwin/fhandler.cc | 57 | ||||
-rw-r--r-- | winsup/cygwin/syscalls.cc | 1 |
3 files changed, 49 insertions, 22 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index d07638cd0..7bfdc5d80 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,16 @@ +2011-12-17 Christopher Faylor <me.cygwin2011@cgf.cx> + + * fhandler.cc (fhandler_base::close): Move setting isclosed() from here + to closed(). + (fhandler_base_overlapped::close): Correct comment. + (fhandler_base_overlapped::destroy_overlapped): Signal overlapped event + before closing it to potentially wake up a waiting thread. + (fhandler_base_overlapped::wait_overlapped): Expand setting of err when + closed to encompass non-signal event. Test for a cancel event before + making nonblocking decisions. + * syscalls.cc (close): Set closed flag here so that any concurrently + executing functions will be notified ASAP. + 2011-12-17 Corinna Vinschen <vinschen@redhat.com> * dcrt0.cc (_dll_crt0): Fix formatting. diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 6624bc7da..a93b45436 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1148,7 +1148,6 @@ fhandler_base::close () paranoid_printf ("CloseHandle failed, %E"); __seterrno (); } - isclosed (true); return res; } @@ -1219,9 +1218,8 @@ fhandler_base_overlapped::close () } else { - /* Cancelling seems to be necessary for cases where a reader is - still executing either in another thread or when a signal handler - performs a close. */ + /* Cancelling seems to be necessary for cases where a reader is + still executing when a signal handler performs a close. */ CancelIo (get_io_handle ()); destroy_overlapped (); res = fhandler_base::close (); @@ -1882,6 +1880,7 @@ fhandler_base_overlapped::destroy_overlapped () OVERLAPPED *ov = get_overlapped (); if (ov && ov->hEvent) { + SetEvent (ov->hEvent); CloseHandle (ov->hEvent); ov->hEvent = NULL; } @@ -1931,7 +1930,21 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte HANDLE h = writing ? get_output_handle () : get_handle (); BOOL wores; if (isclosed ()) - wores = 0; /* closed in another thread or via signal handler */ + { + switch (err) + { + case WAIT_OBJECT_0: + err = ERROR_INVALID_HANDLE; + break; + case WAIT_OBJECT_0 + 1: + err = ERROR_INVALID_AT_INTERRUPT_TIME; + break; + default: + err = GetLastError (); + break; + } + res = overlapped_error; + } else { /* Cancelling here to prevent races. It's possible that the I/O has @@ -1945,23 +1958,23 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte err = GetLastError (); ResetEvent (get_overlapped ()->hEvent); /* Probably not needed but CYA */ debug_printf ("wfres %d, wores %d, bytes %u", wfres, wores, *bytes); - } - if (wores) - res = overlapped_success; /* operation succeeded */ - else if (wfres == WAIT_OBJECT_0 + 1) - { - err = ERROR_INVALID_AT_INTERRUPT_TIME; /* forces an EINTR below */ - debug_printf ("signal"); - res = overlapped_error; - } - else if (nonblocking) - res = overlapped_nonblocking_no_data; /* more handling below */ - else if (wfres == WAIT_OBJECT_0 + 2) - pthread::static_cancel_self (); /* never returns */ - else - { - debug_printf ("GetOverLappedResult failed, h %p, bytes %u, %E", h, *bytes); - res = overlapped_error; + if (wores) + res = overlapped_success; /* operation succeeded */ + else if (wfres == WAIT_OBJECT_0 + 1) + { + err = ERROR_INVALID_AT_INTERRUPT_TIME; /* forces an EINTR below */ + debug_printf ("signal"); + res = overlapped_error; + } + else if (wfres == WAIT_OBJECT_0 + 2) + pthread::static_cancel_self (); /* never returns */ + else if (nonblocking) + res = overlapped_nonblocking_no_data; /* more handling below */ + else + { + debug_printf ("GetOverLappedResult failed, h %p, bytes %u, %E", h, *bytes); + res = overlapped_error; + } } } diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index ea0c23d0b..f86e0442a 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1373,6 +1373,7 @@ close (int fd) res = -1; else { + cfd->isclosed (true); res = cfd->close_with_arch (); cfd.release (); } |