* 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.
This commit is contained in:
Christopher Faylor 2011-12-18 04:07:47 +00:00
parent 1b23b30b29
commit d004a27971
3 changed files with 49 additions and 22 deletions

View File

@ -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> 2011-12-17 Corinna Vinschen <vinschen@redhat.com>
* dcrt0.cc (_dll_crt0): Fix formatting. * dcrt0.cc (_dll_crt0): Fix formatting.

View File

@ -1148,7 +1148,6 @@ fhandler_base::close ()
paranoid_printf ("CloseHandle failed, %E"); paranoid_printf ("CloseHandle failed, %E");
__seterrno (); __seterrno ();
} }
isclosed (true);
return res; return res;
} }
@ -1220,8 +1219,7 @@ fhandler_base_overlapped::close ()
else else
{ {
/* Cancelling seems to be necessary for cases where a reader is /* Cancelling seems to be necessary for cases where a reader is
still executing either in another thread or when a signal handler still executing when a signal handler performs a close. */
performs a close. */
CancelIo (get_io_handle ()); CancelIo (get_io_handle ());
destroy_overlapped (); destroy_overlapped ();
res = fhandler_base::close (); res = fhandler_base::close ();
@ -1882,6 +1880,7 @@ fhandler_base_overlapped::destroy_overlapped ()
OVERLAPPED *ov = get_overlapped (); OVERLAPPED *ov = get_overlapped ();
if (ov && ov->hEvent) if (ov && ov->hEvent)
{ {
SetEvent (ov->hEvent);
CloseHandle (ov->hEvent); CloseHandle (ov->hEvent);
ov->hEvent = NULL; 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 (); HANDLE h = writing ? get_output_handle () : get_handle ();
BOOL wores; BOOL wores;
if (isclosed ()) 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 else
{ {
/* Cancelling here to prevent races. It's possible that the I/O has /* Cancelling here to prevent races. It's possible that the I/O has
@ -1945,7 +1958,6 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte
err = GetLastError (); err = GetLastError ();
ResetEvent (get_overlapped ()->hEvent); /* Probably not needed but CYA */ ResetEvent (get_overlapped ()->hEvent); /* Probably not needed but CYA */
debug_printf ("wfres %d, wores %d, bytes %u", wfres, wores, *bytes); debug_printf ("wfres %d, wores %d, bytes %u", wfres, wores, *bytes);
}
if (wores) if (wores)
res = overlapped_success; /* operation succeeded */ res = overlapped_success; /* operation succeeded */
else if (wfres == WAIT_OBJECT_0 + 1) else if (wfres == WAIT_OBJECT_0 + 1)
@ -1954,16 +1966,17 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte
debug_printf ("signal"); debug_printf ("signal");
res = overlapped_error; res = overlapped_error;
} }
else if (nonblocking)
res = overlapped_nonblocking_no_data; /* more handling below */
else if (wfres == WAIT_OBJECT_0 + 2) else if (wfres == WAIT_OBJECT_0 + 2)
pthread::static_cancel_self (); /* never returns */ pthread::static_cancel_self (); /* never returns */
else if (nonblocking)
res = overlapped_nonblocking_no_data; /* more handling below */
else else
{ {
debug_printf ("GetOverLappedResult failed, h %p, bytes %u, %E", h, *bytes); debug_printf ("GetOverLappedResult failed, h %p, bytes %u, %E", h, *bytes);
res = overlapped_error; res = overlapped_error;
} }
} }
}
if (res == overlapped_success) if (res == overlapped_success)
debug_printf ("normal %s, %u bytes", writing ? "write" : "read", *bytes); debug_printf ("normal %s, %u bytes", writing ? "write" : "read", *bytes);

View File

@ -1373,6 +1373,7 @@ close (int fd)
res = -1; res = -1;
else else
{ {
cfd->isclosed (true);
res = cfd->close_with_arch (); res = cfd->close_with_arch ();
cfd.release (); cfd.release ();
} }