* 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:
parent
1b23b30b29
commit
d004a27971
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1373,6 +1373,7 @@ close (int fd)
|
|||
res = -1;
|
||||
else
|
||||
{
|
||||
cfd->isclosed (true);
|
||||
res = cfd->close_with_arch ();
|
||||
cfd.release ();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue