2011-05-03 Corinna Vinschen <corinna@vinschen.de>
+ * select.cc (cygwin_select): Make degenerate case cancelable.
+ (select_stuff::destroy): New inline method to delete memory taken
+ by select_stuff.
+ (select_stuff::~select_stuff): Call destroy.
+ (select_stuff::wait): Add case to allow canceling select.
+ * select.h (select_stuff::destroy): Declare.
+ * thread.cc: Mark poll, pselect and poll as cancelable.
+
+2011-05-03 Corinna Vinschen <corinna@vinschen.de>
+
* fhandler.cc (fhandler_base_overlapped::wait_overlapped): Make
cancelable. Remove test for main thread, always add signal_arrived
to waited objects.
/* Degenerate case. No fds to wait for. Just wait. */
if (sel.start.next == NULL)
{
- if (WaitForSingleObject (signal_arrived, ms) == WAIT_OBJECT_0)
+ HANDLE w4[2] = { signal_arrived, pthread::get_cancel_event () };
+ DWORD cnt = w4[1] ? 2 : 1;
+
+ switch (WaitForMultipleObjects (cnt, w4, FALSE, ms))
{
+ case WAIT_OBJECT_0:
select_printf ("signal received");
set_sig_errno (EINTR);
return -1;
+ case WAIT_OBJECT_0 + 1:
+ sel.destroy ();
+ pthread::static_cancel_self ();
+ /*NOTREACHED*/
+ default:
+ break;
}
timeout = 1;
}
}
/* Destroy all storage associated with select stuff. */
-select_stuff::~select_stuff ()
+inline void
+select_stuff::destroy ()
{
- cleanup ();
select_record *s = &start;
select_record *snext = start.next;
}
}
+select_stuff::~select_stuff ()
+{
+ cleanup ();
+ destroy ();
+}
+
/* Add a record to the select chain */
bool
select_stuff::test_and_set (int i, fd_set *readfds, fd_set *writefds,
select_record *s = &start;
int m = 0;
int res = 0;
+ bool is_cancelable = false;
w4[m++] = signal_arrived; /* Always wait for the arrival of a signal. */
+ if ((w4[m] = pthread::get_cancel_event ()) != NULL)
+ {
+ ++m;
+ is_cancelable = true;
+ }
+
/* Loop through the select chain, starting up anything appropriate and
counting the number of active fds. */
while ((s = s->next))
the problem that the call to PeekMessage disarms the queue state
so that a subsequent MWFMO hangs, even if there are still messages
in the queue. */
- wait_ret =
- MsgWaitForMultipleObjectsEx (m, w4, ms,
- QS_ALLINPUT | QS_ALLPOSTMESSAGE,
- MWMO_INPUTAVAILABLE);
+ wait_ret = MsgWaitForMultipleObjectsEx (m, w4, ms,
+ QS_ALLINPUT | QS_ALLPOSTMESSAGE,
+ MWMO_INPUTAVAILABLE);
switch (wait_ret)
{
select_printf ("signal received");
set_sig_errno (EINTR);
return -1;
+ case WAIT_OBJECT_0 + 1:
+ if (is_cancelable)
+ {
+ cleanup ();
+ destroy ();
+ pthread::static_cancel_self ();
+ }
+ break;
case WAIT_FAILED:
cleanup ();
system_printf ("WaitForMultipleObjects failed");
int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
void cleanup ();
+ void destroy ();
select_stuff (): always_ready (0), windows_used (0), start (0),
device_specific_pipe (0),
device_specific_socket (0),