mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-28 03:27:46 +08:00
Add '#include "cygwait.h"' throughout, where appropriate.
* DevNotes: Add entry cgf-000012. * Makefile.in (DLL_OFILES): Add cygwait.o. * sigproc.h: Remove cygwait definitions. * cygwait.h: New file. Define/declare Cygwin waitfor functions. * cygwait.cc: Ditto. * exceptions.cc: Include cygwait.h. (handle_sigsuspend): Accommodate change in cancelable_wait arguments. (sigpacket::process): Display thread tls in debugging output. * fhandler.cc (fhandler_base_overlapped::wait_overlapped): Use symbolic names for signal and cancel return. * fhandler_console.cc (fhandler_console::read): Ditto. (fhandler_dev_dsp::Audio_out::waitforspace): Ditto. fhandler_dev_dsp::Audio_in::waitfordata): Ditto. * fhandler_fifo.cc (fhandler_fifo::wait): Ditto. * fhandler_serial.cc (fhandler_serial::raw_read): Ditto. * fhandler_tty.cc (fhandler_pty_slave::read): Ditto. * select.cc (cygwin_select): Ditto. * wait.cc (wait4): Ditto. * thread.cc (cancelable_wait): Move definition to cygwait.h. (pthread_cond::wait): Accommodate change in cancelable_wait arguments. (pthread_mutex::lock): Ditto. (pthread_spinlock::lock): Ditto. (pthread::join): Ditto. (pthread::thread_init_wrapper): Display tls in debugging output. (semaphore::_timedwait): Ditto. * thread.h (cw_sig_wait): Move to cygwait.h. (cw_cancel_action): Delete. (cancelable_wait): Move declaration to cygwait.h.
This commit is contained in:
parent
d66ef282c2
commit
4ae6378382
@ -1,3 +1,35 @@
|
|||||||
|
2012-06-17 Christopher Faylor <me.cygwin2012@cgf.cx>
|
||||||
|
|
||||||
|
Add '#include "cygwait.h"' throughout, where appropriate.
|
||||||
|
* DevNotes: Add entry cgf-000012.
|
||||||
|
* Makefile.in (DLL_OFILES): Add cygwait.o.
|
||||||
|
* sigproc.h: Remove cygwait definitions.
|
||||||
|
* cygwait.h: New file. Define/declare Cygwin waitfor functions.
|
||||||
|
* cygwait.cc: Ditto.
|
||||||
|
* exceptions.cc: Include cygwait.h.
|
||||||
|
(handle_sigsuspend): Accommodate change in cancelable_wait arguments.
|
||||||
|
(sigpacket::process): Display thread tls in debugging output.
|
||||||
|
* fhandler.cc (fhandler_base_overlapped::wait_overlapped): Use symbolic
|
||||||
|
names for signal and cancel return.
|
||||||
|
* fhandler_console.cc (fhandler_console::read): Ditto.
|
||||||
|
(fhandler_dev_dsp::Audio_out::waitforspace): Ditto.
|
||||||
|
fhandler_dev_dsp::Audio_in::waitfordata): Ditto.
|
||||||
|
* fhandler_fifo.cc (fhandler_fifo::wait): Ditto.
|
||||||
|
* fhandler_serial.cc (fhandler_serial::raw_read): Ditto.
|
||||||
|
* fhandler_tty.cc (fhandler_pty_slave::read): Ditto.
|
||||||
|
* select.cc (cygwin_select): Ditto.
|
||||||
|
* wait.cc (wait4): Ditto.
|
||||||
|
* thread.cc (cancelable_wait): Move definition to cygwait.h.
|
||||||
|
(pthread_cond::wait): Accommodate change in cancelable_wait arguments.
|
||||||
|
(pthread_mutex::lock): Ditto.
|
||||||
|
(pthread_spinlock::lock): Ditto.
|
||||||
|
(pthread::join): Ditto.
|
||||||
|
(pthread::thread_init_wrapper): Display tls in debugging output.
|
||||||
|
(semaphore::_timedwait): Ditto.
|
||||||
|
* thread.h (cw_sig_wait): Move to cygwait.h.
|
||||||
|
(cw_cancel_action): Delete.
|
||||||
|
(cancelable_wait): Move declaration to cygwait.h.
|
||||||
|
|
||||||
2012-06-11 Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
|
2012-06-11 Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
|
||||||
|
|
||||||
* regex/regcomp.c (p_ere): Allow vertical-line following
|
* regex/regcomp.c (p_ere): Allow vertical-line following
|
||||||
|
@ -1,3 +1,25 @@
|
|||||||
|
2012-06-12 cgf-000012
|
||||||
|
|
||||||
|
These changes are the preliminary for redoing the way threads wait for
|
||||||
|
signals. The problems are shown by the test case mentioned here:
|
||||||
|
|
||||||
|
http://cygwin.com/ml/cygwin/2012-05/msg00434.html
|
||||||
|
|
||||||
|
I've known that the signal handling in threads wasn't quite right for
|
||||||
|
some time. I lost all of my thread signal tests in the great "rm -r"
|
||||||
|
debacle of a few years ago and have been less than enthusiastic about
|
||||||
|
redoing everything (I had PCTS tests and everyting). But it really is
|
||||||
|
time to redo this signal handling to make it more like it is supposed to
|
||||||
|
be.
|
||||||
|
|
||||||
|
This change should not introduce any new behavior. Things should
|
||||||
|
continue to behave as before. The major differences are a change in the
|
||||||
|
arguments to cancelable_wait and cygwait now uses cancelable_wait and,
|
||||||
|
so, the returns from cygwait now mirror cancelable_wait.
|
||||||
|
|
||||||
|
The next change will consolidate cygwait and cancelable_wait into one
|
||||||
|
cygwait function.
|
||||||
|
|
||||||
2012-06-02 cgf-000011
|
2012-06-02 cgf-000011
|
||||||
|
|
||||||
The refcnt handling was tricky to get right but I had convinced myself
|
The refcnt handling was tricky to get right but I had convinced myself
|
||||||
|
@ -133,16 +133,16 @@ MALLOC_OFILES:=@MALLOC_OFILES@
|
|||||||
DLL_IMPORTS:=$(w32api_lib)/libkernel32.a $(w32api_lib)/libntdll.a
|
DLL_IMPORTS:=$(w32api_lib)/libkernel32.a $(w32api_lib)/libntdll.a
|
||||||
|
|
||||||
MT_SAFE_OBJECTS:=
|
MT_SAFE_OBJECTS:=
|
||||||
# Please maintain this list in sorted order, with maximum files per 86 col line
|
|
||||||
#
|
#
|
||||||
DLL_OFILES:=advapi32.o assert.o autoload.o bsdlib.o ctype.o cxx.o cygheap.o \
|
DLL_OFILES:=advapi32.o assert.o autoload.o bsdlib.o ctype.o cxx.o cygheap.o \
|
||||||
cygthread.o cygtls.o cygxdr.o dcrt0.o debug.o devices.o dir.o dlfcn.o \
|
cygthread.o cygtls.o cygwait.o cygxdr.o dcrt0.o debug.o devices.o \
|
||||||
dll_init.o dtable.o environ.o errno.o exceptions.o exec.o external.o \
|
dir.o dlfcn.o dll_init.o dtable.o environ.o errno.o exceptions.o \
|
||||||
fcntl.o fenv.o fhandler.o fhandler_clipboard.o fhandler_console.o \
|
exec.o external.o fcntl.o fenv.o fhandler.o fhandler_clipboard.o \
|
||||||
fhandler_dev.o fhandler_disk_file.o fhandler_dsp.o fhandler_fifo.o \
|
fhandler_console.o fhandler_dev.o fhandler_disk_file.o fhandler_dsp.o \
|
||||||
fhandler_floppy.o fhandler_mailslot.o fhandler_mem.o fhandler_netdrive.o \
|
fhandler_fifo.o fhandler_floppy.o fhandler_mailslot.o fhandler_mem.o \
|
||||||
fhandler_nodevice.o fhandler_proc.o fhandler_process.o fhandler_procnet.o \
|
fhandler_netdrive.o fhandler_nodevice.o fhandler_proc.o \
|
||||||
fhandler_procsys.o fhandler_procsysvipc.o fhandler_random.o fhandler_raw.o \
|
fhandler_process.o fhandler_procnet.o fhandler_procsys.o \
|
||||||
|
fhandler_procsysvipc.o fhandler_random.o fhandler_raw.o \
|
||||||
fhandler_registry.o fhandler_serial.o fhandler_socket.o fhandler_tape.o \
|
fhandler_registry.o fhandler_serial.o fhandler_socket.o fhandler_tape.o \
|
||||||
fhandler_termios.o fhandler_tty.o fhandler_virtual.o fhandler_windows.o \
|
fhandler_termios.o fhandler_tty.o fhandler_virtual.o fhandler_windows.o \
|
||||||
fhandler_zero.o flock.o fnmatch.o fork.o fts.o ftw.o getopt.o glob.o \
|
fhandler_zero.o flock.o fnmatch.o fork.o fts.o ftw.o getopt.o glob.o \
|
||||||
|
108
winsup/cygwin/cygwait.cc
Normal file
108
winsup/cygwin/cygwait.cc
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/* cygwait.h
|
||||||
|
|
||||||
|
Copyright 2011, 2012 Red Hat, Inc.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include "winsup.h"
|
||||||
|
#include "sigproc.h"
|
||||||
|
#include "cygwait.h"
|
||||||
|
#include "ntdll.h"
|
||||||
|
|
||||||
|
#define is_cw_cancel (mask & cw_cancel)
|
||||||
|
#define is_cw_cancel_self (mask & cw_cancel_self)
|
||||||
|
#define is_cw_sig (mask & cw_sig)
|
||||||
|
#define is_cw_sig_eintr (mask & cw_sig_eintr)
|
||||||
|
#define is_cw_sig_return (mask & cw_sig_return)
|
||||||
|
|
||||||
|
#define is_cw_sig_handle (mask & (is_cw_sig | is_cw_sig_eintr))
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
|
||||||
|
{
|
||||||
|
DWORD res;
|
||||||
|
DWORD num = 0;
|
||||||
|
HANDLE wait_objects[4];
|
||||||
|
pthread_t thread = pthread::self ();
|
||||||
|
|
||||||
|
/* Do not change the wait order.
|
||||||
|
The object must have higher priority than the cancel event,
|
||||||
|
because WaitForMultipleObjects will return the smallest index
|
||||||
|
if both objects are signaled. */
|
||||||
|
if (object)
|
||||||
|
wait_objects[num++] = object;
|
||||||
|
|
||||||
|
DWORD sig_n;
|
||||||
|
if (!is_cw_sig_handle)
|
||||||
|
sig_n = WAIT_TIMEOUT + 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sig_n = WAIT_OBJECT_0 + num++;
|
||||||
|
wait_objects[sig_n] = signal_arrived;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD cancel_n;
|
||||||
|
if (!is_cw_cancel || !pthread::is_good_object (&thread) ||
|
||||||
|
thread->cancelstate == PTHREAD_CANCEL_DISABLE)
|
||||||
|
cancel_n = WAIT_TIMEOUT + 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cancel_n = WAIT_OBJECT_0 + num++;
|
||||||
|
wait_objects[cancel_n] = thread->cancel_event;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD timeout_n;
|
||||||
|
if (!timeout)
|
||||||
|
timeout_n = WAIT_TIMEOUT + 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timeout_n = WAIT_OBJECT_0 + num++;
|
||||||
|
if (!_my_tls.locals.cw_timer)
|
||||||
|
NtCreateTimer (&_my_tls.locals.cw_timer, TIMER_ALL_ACCESS, NULL,
|
||||||
|
NotificationTimer);
|
||||||
|
NtSetTimer (_my_tls.locals.cw_timer, timeout, NULL, NULL, FALSE, 0, NULL);
|
||||||
|
wait_objects[timeout_n] = _my_tls.locals.cw_timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
res = WaitForMultipleObjects (num, wait_objects, FALSE, INFINITE);
|
||||||
|
if (res == cancel_n)
|
||||||
|
{
|
||||||
|
if (is_cw_cancel_self)
|
||||||
|
pthread::static_cancel_self ();
|
||||||
|
res = WAIT_CANCELED;
|
||||||
|
}
|
||||||
|
else if (res == timeout_n)
|
||||||
|
res = WAIT_TIMEOUT;
|
||||||
|
else if (res != sig_n)
|
||||||
|
/* all set */;
|
||||||
|
else if (is_cw_sig_eintr)
|
||||||
|
res = WAIT_SIGNALED;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_my_tls.call_signal_handler ();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeout)
|
||||||
|
{
|
||||||
|
TIMER_BASIC_INFORMATION tbi;
|
||||||
|
|
||||||
|
NtQueryTimer (_my_tls.locals.cw_timer, TimerBasicInformation, &tbi,
|
||||||
|
sizeof tbi, NULL);
|
||||||
|
/* if timer expired, TimeRemaining is negative and represents the
|
||||||
|
system uptime when signalled */
|
||||||
|
if (timeout->QuadPart < 0LL)
|
||||||
|
timeout->QuadPart = tbi.SignalState ? 0LL : tbi.TimeRemaining.QuadPart;
|
||||||
|
NtCancelTimer (_my_tls.locals.cw_timer, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
47
winsup/cygwin/cygwait.h
Normal file
47
winsup/cygwin/cygwait.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/* cygwait.h
|
||||||
|
|
||||||
|
Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
||||||
|
Red Hat, Inc.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
enum cw_wait_mask
|
||||||
|
{
|
||||||
|
cw_cancel = 0x0001,
|
||||||
|
cw_cancel_self = 0x0002,
|
||||||
|
cw_sig = 0x0004,
|
||||||
|
cw_sig_eintr = 0x0008
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned cw_std_mask = cw_cancel | cw_cancel_self | cw_sig;
|
||||||
|
|
||||||
|
DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL,
|
||||||
|
unsigned = cw_std_mask)
|
||||||
|
__attribute__ ((regparm (3)));
|
||||||
|
|
||||||
|
static inline DWORD __attribute__ ((always_inline))
|
||||||
|
cygwait (HANDLE h, DWORD howlong = INFINITE)
|
||||||
|
{
|
||||||
|
PLARGE_INTEGER pli_howlong;
|
||||||
|
LARGE_INTEGER li_howlong;
|
||||||
|
if (howlong == INFINITE)
|
||||||
|
pli_howlong = NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
li_howlong.QuadPart = 10000ULL * howlong;
|
||||||
|
pli_howlong = &li_howlong;
|
||||||
|
}
|
||||||
|
return cancelable_wait (h, pli_howlong, cw_cancel | cw_sig_eintr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline DWORD __attribute__ ((always_inline))
|
||||||
|
cygwait (DWORD howlong)
|
||||||
|
{
|
||||||
|
return cygwait ((HANDLE) NULL, howlong);
|
||||||
|
}
|
@ -31,6 +31,7 @@ details. */
|
|||||||
#include "child_info.h"
|
#include "child_info.h"
|
||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
|
#include "cygwait.h"
|
||||||
|
|
||||||
#define CALL_HANDLER_RETRY_OUTER 10
|
#define CALL_HANDLER_RETRY_OUTER 10
|
||||||
#define CALL_HANDLER_RETRY_INNER 10
|
#define CALL_HANDLER_RETRY_INNER 10
|
||||||
@ -714,7 +715,7 @@ handle_sigsuspend (sigset_t tempmask)
|
|||||||
sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask);
|
sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask);
|
||||||
|
|
||||||
pthread_testcancel ();
|
pthread_testcancel ();
|
||||||
cancelable_wait (signal_arrived);
|
cancelable_wait (signal_arrived, NULL, cw_cancel | cw_cancel_self);
|
||||||
|
|
||||||
set_sig_errno (EINTR); // Per POSIX
|
set_sig_errno (EINTR); // Per POSIX
|
||||||
|
|
||||||
@ -1194,6 +1195,7 @@ sigpacket::process ()
|
|||||||
handler = NULL;
|
handler = NULL;
|
||||||
|
|
||||||
_cygtls *use_tls = tls ?: _main_tls;
|
_cygtls *use_tls = tls ?: _main_tls;
|
||||||
|
sigproc_printf ("tls %p, use_tls %p", tls, use_tls);
|
||||||
|
|
||||||
if (si.si_signo == SIGKILL)
|
if (si.si_signo == SIGKILL)
|
||||||
goto exit_sig;
|
goto exit_sig;
|
||||||
|
@ -31,6 +31,7 @@ details. */
|
|||||||
#include "sigproc.h"
|
#include "sigproc.h"
|
||||||
#include "shared_info.h"
|
#include "shared_info.h"
|
||||||
#include <asm/socket.h>
|
#include <asm/socket.h>
|
||||||
|
#include "cygwait.h"
|
||||||
|
|
||||||
#define MAX_OVERLAPPED_WRITE_LEN (64 * 1024 * 1024)
|
#define MAX_OVERLAPPED_WRITE_LEN (64 * 1024 * 1024)
|
||||||
#define MIN_OVERLAPPED_WRITE_LEN (1 * 1024 * 1024)
|
#define MIN_OVERLAPPED_WRITE_LEN (1 * 1024 * 1024)
|
||||||
@ -1939,7 +1940,7 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte
|
|||||||
case WAIT_OBJECT_0:
|
case WAIT_OBJECT_0:
|
||||||
err = ERROR_INVALID_HANDLE;
|
err = ERROR_INVALID_HANDLE;
|
||||||
break;
|
break;
|
||||||
case WAIT_OBJECT_0 + 1:
|
case WAIT_SIGNALED:
|
||||||
err = ERROR_INVALID_AT_INTERRUPT_TIME;
|
err = ERROR_INVALID_AT_INTERRUPT_TIME;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -36,6 +36,7 @@ details. */
|
|||||||
#include <asm/socket.h>
|
#include <asm/socket.h>
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
#include "child_info.h"
|
#include "child_info.h"
|
||||||
|
#include "cygwait.h"
|
||||||
|
|
||||||
/* Don't make this bigger than NT_MAX_PATH as long as the temporary buffer
|
/* Don't make this bigger than NT_MAX_PATH as long as the temporary buffer
|
||||||
is allocated using tmp_pathbuf!!! */
|
is allocated using tmp_pathbuf!!! */
|
||||||
@ -355,9 +356,9 @@ fhandler_console::read (void *pv, size_t& buflen)
|
|||||||
{
|
{
|
||||||
case WAIT_OBJECT_0:
|
case WAIT_OBJECT_0:
|
||||||
break;
|
break;
|
||||||
case WAIT_OBJECT_0 + 1:
|
case WAIT_SIGNALED:
|
||||||
goto sig_exit;
|
goto sig_exit;
|
||||||
case WAIT_OBJECT_0 + 2:
|
case WAIT_CANCELED:
|
||||||
process_state.pop ();
|
process_state.pop ();
|
||||||
pthread::static_cancel_self ();
|
pthread::static_cancel_self ();
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
|
@ -21,6 +21,7 @@ details. */
|
|||||||
#include "dtable.h"
|
#include "dtable.h"
|
||||||
#include "cygheap.h"
|
#include "cygheap.h"
|
||||||
#include "sigproc.h"
|
#include "sigproc.h"
|
||||||
|
#include "cygwait.h"
|
||||||
|
|
||||||
/*------------------------------------------------------------------------
|
/*------------------------------------------------------------------------
|
||||||
Simple encapsulation of the win32 audio device.
|
Simple encapsulation of the win32 audio device.
|
||||||
@ -544,14 +545,14 @@ fhandler_dev_dsp::Audio_out::waitforspace ()
|
|||||||
debug_printf ("100ms");
|
debug_printf ("100ms");
|
||||||
switch (cygwait (100))
|
switch (cygwait (100))
|
||||||
{
|
{
|
||||||
case WAIT_OBJECT_0:
|
case WAIT_SIGNALED:
|
||||||
if (!_my_tls.call_signal_handler ())
|
if (!_my_tls.call_signal_handler ())
|
||||||
{
|
{
|
||||||
set_errno (EINTR);
|
set_errno (EINTR);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WAIT_OBJECT_0 + 1:
|
case WAIT_CANCELED:
|
||||||
pthread::static_cancel_self ();
|
pthread::static_cancel_self ();
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
default:
|
default:
|
||||||
@ -922,14 +923,14 @@ fhandler_dev_dsp::Audio_in::waitfordata ()
|
|||||||
debug_printf ("100ms");
|
debug_printf ("100ms");
|
||||||
switch (cygwait (100))
|
switch (cygwait (100))
|
||||||
{
|
{
|
||||||
case WAIT_OBJECT_0:
|
case WAIT_SIGNALED:
|
||||||
if (!_my_tls.call_signal_handler ())
|
if (!_my_tls.call_signal_handler ())
|
||||||
{
|
{
|
||||||
set_errno (EINTR);
|
set_errno (EINTR);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WAIT_OBJECT_0 + 1:
|
case WAIT_CANCELED:
|
||||||
pthread::static_cancel_self ();
|
pthread::static_cancel_self ();
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
default:
|
default:
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "cygtls.h"
|
#include "cygtls.h"
|
||||||
#include "shared_info.h"
|
#include "shared_info.h"
|
||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
|
#include "cygwait.h"
|
||||||
|
|
||||||
fhandler_fifo::fhandler_fifo ():
|
fhandler_fifo::fhandler_fifo ():
|
||||||
fhandler_base_overlapped (),
|
fhandler_base_overlapped (),
|
||||||
@ -242,6 +243,14 @@ fhandler_fifo::wait (HANDLE h)
|
|||||||
case WAIT_OBJECT_0:
|
case WAIT_OBJECT_0:
|
||||||
debug_only_printf ("successfully waited for %s", what);
|
debug_only_printf ("successfully waited for %s", what);
|
||||||
return true;
|
return true;
|
||||||
|
case WAIT_SIGNALED:
|
||||||
|
debug_only_printf ("interrupted by signal while waiting for %s", what);
|
||||||
|
set_errno (EINTR);
|
||||||
|
return false;
|
||||||
|
case WAIT_CANCELED:
|
||||||
|
debug_only_printf ("cancellable interruption while waiting for %s", what);
|
||||||
|
pthread::static_cancel_self (); /* never returns */
|
||||||
|
break;
|
||||||
case WAIT_TIMEOUT:
|
case WAIT_TIMEOUT:
|
||||||
if (h == write_ready)
|
if (h == write_ready)
|
||||||
{
|
{
|
||||||
@ -254,14 +263,6 @@ fhandler_fifo::wait (HANDLE h)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WAIT_OBJECT_0 + 1:
|
|
||||||
debug_only_printf ("interrupted by signal while waiting for %s", what);
|
|
||||||
set_errno (EINTR);
|
|
||||||
return false;
|
|
||||||
case WAIT_OBJECT_0 + 2:
|
|
||||||
debug_only_printf ("cancellable interruption while waiting for %s", what);
|
|
||||||
pthread::static_cancel_self (); /* never returns */
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
debug_only_printf ("unknown error while waiting for %s", what);
|
debug_only_printf ("unknown error while waiting for %s", what);
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
|
@ -20,6 +20,7 @@ details. */
|
|||||||
#include "pinfo.h"
|
#include "pinfo.h"
|
||||||
#include <asm/socket.h>
|
#include <asm/socket.h>
|
||||||
#include <ddk/ntddser.h>
|
#include <ddk/ntddser.h>
|
||||||
|
#include "cygwait.h"
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/* fhandler_serial */
|
/* fhandler_serial */
|
||||||
@ -94,13 +95,13 @@ fhandler_serial::raw_read (void *ptr, size_t& ulen)
|
|||||||
goto err;
|
goto err;
|
||||||
debug_printf ("n %d, ev %x", n, ev);
|
debug_printf ("n %d, ev %x", n, ev);
|
||||||
break;
|
break;
|
||||||
case WAIT_OBJECT_0 + 1:
|
case WAIT_SIGNALED:
|
||||||
tot = -1;
|
tot = -1;
|
||||||
PurgeComm (get_handle (), PURGE_RXABORT);
|
PurgeComm (get_handle (), PURGE_RXABORT);
|
||||||
overlapped_armed = 0;
|
overlapped_armed = 0;
|
||||||
set_sig_errno (EINTR);
|
set_sig_errno (EINTR);
|
||||||
goto out;
|
goto out;
|
||||||
case WAIT_OBJECT_0 + 2:
|
case WAIT_CANCELED:
|
||||||
PurgeComm (get_handle (), PURGE_RXABORT);
|
PurgeComm (get_handle (), PURGE_RXABORT);
|
||||||
overlapped_armed = 0;
|
overlapped_armed = 0;
|
||||||
pthread::static_cancel_self ();
|
pthread::static_cancel_self ();
|
||||||
@ -201,12 +202,12 @@ fhandler_serial::raw_write (const void *ptr, size_t len)
|
|||||||
{
|
{
|
||||||
case WAIT_OBJECT_0:
|
case WAIT_OBJECT_0:
|
||||||
break;
|
break;
|
||||||
case WAIT_OBJECT_0 + 1:
|
case WAIT_SIGNALED:
|
||||||
PurgeComm (get_handle (), PURGE_TXABORT);
|
PurgeComm (get_handle (), PURGE_TXABORT);
|
||||||
set_sig_errno (EINTR);
|
set_sig_errno (EINTR);
|
||||||
ForceCloseHandle (write_status.hEvent);
|
ForceCloseHandle (write_status.hEvent);
|
||||||
return -1;
|
return -1;
|
||||||
case WAIT_OBJECT_0 + 2:
|
case WAIT_CANCELED:
|
||||||
PurgeComm (get_handle (), PURGE_TXABORT);
|
PurgeComm (get_handle (), PURGE_TXABORT);
|
||||||
pthread::static_cancel_self ();
|
pthread::static_cancel_self ();
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
|
@ -26,6 +26,7 @@ details. */
|
|||||||
#include "cygthread.h"
|
#include "cygthread.h"
|
||||||
#include "child_info.h"
|
#include "child_info.h"
|
||||||
#include <asm/socket.h>
|
#include <asm/socket.h>
|
||||||
|
#include "cygwait.h"
|
||||||
|
|
||||||
#define close_maybe(h) \
|
#define close_maybe(h) \
|
||||||
do { \
|
do { \
|
||||||
@ -737,14 +738,14 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WAIT_OBJECT_0 + 1:
|
case WAIT_SIGNALED:
|
||||||
if (totalread > 0)
|
if (totalread > 0)
|
||||||
goto out;
|
goto out;
|
||||||
termios_printf ("wait catched signal");
|
termios_printf ("wait catched signal");
|
||||||
set_sig_errno (EINTR);
|
set_sig_errno (EINTR);
|
||||||
totalread = -1;
|
totalread = -1;
|
||||||
goto out;
|
goto out;
|
||||||
case WAIT_OBJECT_0 + 2:
|
case WAIT_CANCELED:
|
||||||
process_state.pop ();
|
process_state.pop ();
|
||||||
pthread::static_cancel_self ();
|
pthread::static_cancel_self ();
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
@ -772,14 +773,14 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
|
|||||||
case WAIT_OBJECT_0:
|
case WAIT_OBJECT_0:
|
||||||
case WAIT_ABANDONED_0:
|
case WAIT_ABANDONED_0:
|
||||||
break;
|
break;
|
||||||
case WAIT_OBJECT_0 + 1:
|
case WAIT_SIGNALED:
|
||||||
if (totalread > 0)
|
if (totalread > 0)
|
||||||
goto out;
|
goto out;
|
||||||
termios_printf ("wait for mutex catched signal");
|
termios_printf ("wait for mutex caught signal");
|
||||||
set_sig_errno (EINTR);
|
set_sig_errno (EINTR);
|
||||||
totalread = -1;
|
totalread = -1;
|
||||||
goto out;
|
goto out;
|
||||||
case WAIT_OBJECT_0 + 2:
|
case WAIT_CANCELED:
|
||||||
process_state.pop ();
|
process_state.pop ();
|
||||||
pthread::static_cancel_self ();
|
pthread::static_cancel_self ();
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
|
@ -34,6 +34,7 @@ details. */
|
|||||||
#include "pinfo.h"
|
#include "pinfo.h"
|
||||||
#include "sigproc.h"
|
#include "sigproc.h"
|
||||||
#include "cygtls.h"
|
#include "cygtls.h"
|
||||||
|
#include "cygwait.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All these defines below should be in sys/types.h
|
* All these defines below should be in sys/types.h
|
||||||
@ -143,7 +144,7 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||||||
if (sel.start.next == NULL)
|
if (sel.start.next == NULL)
|
||||||
switch (cygwait (ms))
|
switch (cygwait (ms))
|
||||||
{
|
{
|
||||||
case WAIT_OBJECT_0:
|
case WAIT_SIGNALED:
|
||||||
select_printf ("signal received");
|
select_printf ("signal received");
|
||||||
_my_tls.call_signal_handler ();
|
_my_tls.call_signal_handler ();
|
||||||
if (!sel.return_on_signal)
|
if (!sel.return_on_signal)
|
||||||
@ -154,7 +155,7 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||||||
res = select_stuff::select_error;
|
res = select_stuff::select_error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WAIT_OBJECT_0 + 1:
|
case WAIT_CANCELED:
|
||||||
sel.destroy ();
|
sel.destroy ();
|
||||||
pthread::static_cancel_self ();
|
pthread::static_cancel_self ();
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
|
@ -22,6 +22,7 @@ details. */
|
|||||||
#include "fhandler.h"
|
#include "fhandler.h"
|
||||||
#include "dtable.h"
|
#include "dtable.h"
|
||||||
#include "cygheap.h"
|
#include "cygheap.h"
|
||||||
|
#include "cygwait.h"
|
||||||
|
|
||||||
#define _SA_NORESTART 0x8000
|
#define _SA_NORESTART 0x8000
|
||||||
|
|
||||||
|
@ -80,33 +80,6 @@ void __stdcall proc_terminate ();
|
|||||||
void __stdcall sigproc_init ();
|
void __stdcall sigproc_init ();
|
||||||
#ifdef __INSIDE_CYGWIN__
|
#ifdef __INSIDE_CYGWIN__
|
||||||
void __stdcall sigproc_terminate (enum exit_states);
|
void __stdcall sigproc_terminate (enum exit_states);
|
||||||
|
|
||||||
static inline DWORD __attribute__ ((always_inline))
|
|
||||||
cygwait (HANDLE h, DWORD howlong = INFINITE)
|
|
||||||
{
|
|
||||||
HANDLE w4[3];
|
|
||||||
DWORD n = 0;
|
|
||||||
DWORD wait_signal;
|
|
||||||
if ((w4[n] = h) != NULL)
|
|
||||||
wait_signal = WAIT_OBJECT_0 + ++n;
|
|
||||||
else
|
|
||||||
wait_signal = WAIT_OBJECT_0 + 15; /* Arbitrary. Don't call signal
|
|
||||||
handler if only waiting for signal */
|
|
||||||
w4[n++] = signal_arrived;
|
|
||||||
if ((w4[n] = pthread::get_cancel_event ()) != NULL)
|
|
||||||
n++;
|
|
||||||
DWORD res;
|
|
||||||
while ((res = WaitForMultipleObjects (n, w4, FALSE, howlong)) == wait_signal
|
|
||||||
&& (_my_tls.call_signal_handler () || &_my_tls != _main_tls))
|
|
||||||
continue;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline DWORD __attribute__ ((always_inline))
|
|
||||||
cygwait (DWORD wait)
|
|
||||||
{
|
|
||||||
return cygwait ((HANDLE) NULL, wait);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
bool __stdcall pid_exists (pid_t) __attribute__ ((regparm(1)));
|
bool __stdcall pid_exists (pid_t) __attribute__ ((regparm(1)));
|
||||||
int __stdcall sig_send (_pinfo *, siginfo_t&, class _cygtls *tls = NULL) __attribute__ ((regparm (3)));
|
int __stdcall sig_send (_pinfo *, siginfo_t&, class _cygtls *tls = NULL) __attribute__ ((regparm (3)));
|
||||||
|
@ -32,6 +32,7 @@ details. */
|
|||||||
#include "dtable.h"
|
#include "dtable.h"
|
||||||
#include "cygheap.h"
|
#include "cygheap.h"
|
||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
|
#include "cygwait.h"
|
||||||
|
|
||||||
extern "C" void __fp_lock_all ();
|
extern "C" void __fp_lock_all ();
|
||||||
extern "C" void __fp_unlock_all ();
|
extern "C" void __fp_unlock_all ();
|
||||||
@ -937,92 +938,6 @@ pthread::static_cancel_self ()
|
|||||||
pthread::self ()->cancel_self ();
|
pthread::self ()->cancel_self ();
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD
|
|
||||||
cancelable_wait (HANDLE object, PLARGE_INTEGER timeout,
|
|
||||||
const cw_cancel_action cancel_action,
|
|
||||||
const enum cw_sig_wait sig_wait)
|
|
||||||
{
|
|
||||||
DWORD res;
|
|
||||||
DWORD num = 0;
|
|
||||||
HANDLE wait_objects[4];
|
|
||||||
pthread_t thread = pthread::self ();
|
|
||||||
|
|
||||||
/* Do not change the wait order.
|
|
||||||
The object must have higher priority than the cancel event,
|
|
||||||
because WaitForMultipleObjects will return the smallest index
|
|
||||||
if both objects are signaled. */
|
|
||||||
wait_objects[num++] = object;
|
|
||||||
DWORD cancel_n;
|
|
||||||
if (cancel_action == cw_no_cancel || !pthread::is_good_object (&thread) ||
|
|
||||||
thread->cancelstate == PTHREAD_CANCEL_DISABLE)
|
|
||||||
cancel_n = WAIT_TIMEOUT + 1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cancel_n = WAIT_OBJECT_0 + num++;
|
|
||||||
wait_objects[cancel_n] = thread->cancel_event;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD sig_n;
|
|
||||||
if (sig_wait == cw_sig_nosig)
|
|
||||||
sig_n = WAIT_TIMEOUT + 1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sig_n = WAIT_OBJECT_0 + num++;
|
|
||||||
wait_objects[sig_n] = signal_arrived;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD timeout_n;
|
|
||||||
if (!timeout)
|
|
||||||
timeout_n = WAIT_TIMEOUT + 1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
timeout_n = WAIT_OBJECT_0 + num++;
|
|
||||||
if (!_my_tls.locals.cw_timer)
|
|
||||||
NtCreateTimer (&_my_tls.locals.cw_timer, TIMER_ALL_ACCESS, NULL,
|
|
||||||
NotificationTimer);
|
|
||||||
NtSetTimer (_my_tls.locals.cw_timer, timeout, NULL, NULL, FALSE, 0, NULL);
|
|
||||||
wait_objects[timeout_n] = _my_tls.locals.cw_timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
res = WaitForMultipleObjects (num, wait_objects, FALSE, INFINITE);
|
|
||||||
if (res == cancel_n)
|
|
||||||
{
|
|
||||||
if (cancel_action == cw_cancel_self)
|
|
||||||
pthread::static_cancel_self ();
|
|
||||||
res = WAIT_CANCELED;
|
|
||||||
}
|
|
||||||
else if (res == timeout_n)
|
|
||||||
res = WAIT_TIMEOUT;
|
|
||||||
else if (res != sig_n)
|
|
||||||
/* all set */;
|
|
||||||
else if (sig_wait == cw_sig_eintr)
|
|
||||||
res = WAIT_SIGNALED;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_my_tls.call_signal_handler ();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timeout)
|
|
||||||
{
|
|
||||||
TIMER_BASIC_INFORMATION tbi;
|
|
||||||
|
|
||||||
NtQueryTimer (_my_tls.locals.cw_timer, TimerBasicInformation, &tbi,
|
|
||||||
sizeof tbi, NULL);
|
|
||||||
/* if timer expired, TimeRemaining is negative and represents the
|
|
||||||
system uptime when signalled */
|
|
||||||
if (timeout->QuadPart < 0LL)
|
|
||||||
timeout->QuadPart = tbi.SignalState ? 0LL : tbi.TimeRemaining.QuadPart;
|
|
||||||
NtCancelTimer (_my_tls.locals.cw_timer, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
pthread::setcancelstate (int state, int *oldstate)
|
pthread::setcancelstate (int state, int *oldstate)
|
||||||
{
|
{
|
||||||
@ -1313,7 +1228,7 @@ pthread_cond::wait (pthread_mutex_t mutex, PLARGE_INTEGER timeout)
|
|||||||
++mutex->condwaits;
|
++mutex->condwaits;
|
||||||
mutex->unlock ();
|
mutex->unlock ();
|
||||||
|
|
||||||
rv = cancelable_wait (sem_wait, timeout, cw_no_cancel_self, cw_sig_eintr);
|
rv = cancelable_wait (sem_wait, timeout, cw_cancel | cw_sig_eintr);
|
||||||
|
|
||||||
mtx_out.lock ();
|
mtx_out.lock ();
|
||||||
|
|
||||||
@ -1828,7 +1743,8 @@ pthread_mutex::lock ()
|
|||||||
else if (type == PTHREAD_MUTEX_NORMAL /* potentially causes deadlock */
|
else if (type == PTHREAD_MUTEX_NORMAL /* potentially causes deadlock */
|
||||||
|| !pthread::equal (owner, self))
|
|| !pthread::equal (owner, self))
|
||||||
{
|
{
|
||||||
cancelable_wait (win32_obj_id, NULL, cw_no_cancel, cw_sig_resume);
|
/* FIXME: no cancel? */
|
||||||
|
cancelable_wait (win32_obj_id, NULL, cw_sig);
|
||||||
set_owner (self);
|
set_owner (self);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1968,7 +1884,8 @@ pthread_spinlock::lock ()
|
|||||||
/* Minimal timeout to minimize CPU usage while still spinning. */
|
/* Minimal timeout to minimize CPU usage while still spinning. */
|
||||||
LARGE_INTEGER timeout;
|
LARGE_INTEGER timeout;
|
||||||
timeout.QuadPart = -10000LL;
|
timeout.QuadPart = -10000LL;
|
||||||
cancelable_wait (win32_obj_id, &timeout, cw_no_cancel, cw_sig_resume);
|
/* FIXME: no cancel? */
|
||||||
|
cancelable_wait (win32_obj_id, &timeout, cw_sig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (result == -1);
|
while (result == -1);
|
||||||
@ -2013,6 +1930,7 @@ pthread::thread_init_wrapper (void *arg)
|
|||||||
_my_tls.sigmask = thread->parent_sigmask;
|
_my_tls.sigmask = thread->parent_sigmask;
|
||||||
thread->mutex.unlock ();
|
thread->mutex.unlock ();
|
||||||
|
|
||||||
|
debug_printf ("tid %p", &_my_tls);
|
||||||
thread_printf ("started thread %p %p %p %p %p %p", arg, &_my_tls.local_clib,
|
thread_printf ("started thread %p %p %p %p %p %p", arg, &_my_tls.local_clib,
|
||||||
_impure_ptr, thread, thread->function, thread->arg);
|
_impure_ptr, thread, thread->function, thread->arg);
|
||||||
|
|
||||||
@ -2446,7 +2364,7 @@ pthread::join (pthread_t *thread, void **return_val)
|
|||||||
(*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
|
(*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
|
||||||
(*thread)->mutex.unlock ();
|
(*thread)->mutex.unlock ();
|
||||||
|
|
||||||
switch (cancelable_wait ((*thread)->win32_obj_id, NULL, cw_no_cancel_self, cw_sig_resume))
|
switch (cancelable_wait ((*thread)->win32_obj_id, NULL, cw_sig | cw_cancel))
|
||||||
{
|
{
|
||||||
case WAIT_OBJECT_0:
|
case WAIT_OBJECT_0:
|
||||||
if (return_val)
|
if (return_val)
|
||||||
@ -3561,7 +3479,7 @@ semaphore::_timedwait (const struct timespec *abstime)
|
|||||||
timeout.QuadPart = abstime->tv_sec * NSPERSEC
|
timeout.QuadPart = abstime->tv_sec * NSPERSEC
|
||||||
+ (abstime->tv_nsec + 99) / 100 + FACTOR;
|
+ (abstime->tv_nsec + 99) / 100 + FACTOR;
|
||||||
|
|
||||||
switch (cancelable_wait (win32_obj_id, &timeout, cw_cancel_self, cw_sig_eintr))
|
switch (cancelable_wait (win32_obj_id, &timeout, cw_cancel | cw_cancel_self | cw_sig_eintr))
|
||||||
{
|
{
|
||||||
case WAIT_OBJECT_0:
|
case WAIT_OBJECT_0:
|
||||||
currentvalue--;
|
currentvalue--;
|
||||||
@ -3583,7 +3501,7 @@ semaphore::_timedwait (const struct timespec *abstime)
|
|||||||
int
|
int
|
||||||
semaphore::_wait ()
|
semaphore::_wait ()
|
||||||
{
|
{
|
||||||
switch (cancelable_wait (win32_obj_id, NULL, cw_cancel_self, cw_sig_eintr))
|
switch (cancelable_wait (win32_obj_id, NULL, cw_cancel | cw_cancel_self | cw_sig_eintr))
|
||||||
{
|
{
|
||||||
case WAIT_OBJECT_0:
|
case WAIT_OBJECT_0:
|
||||||
currentvalue--;
|
currentvalue--;
|
||||||
|
@ -29,25 +29,7 @@ details. */
|
|||||||
#include "security.h"
|
#include "security.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "cygerrno.h"
|
#include "cygerrno.h"
|
||||||
|
#include "cygwait.h"
|
||||||
enum cw_sig_wait
|
|
||||||
{
|
|
||||||
cw_sig_nosig,
|
|
||||||
cw_sig_eintr,
|
|
||||||
cw_sig_resume
|
|
||||||
};
|
|
||||||
|
|
||||||
enum cw_cancel_action
|
|
||||||
{
|
|
||||||
cw_cancel_self,
|
|
||||||
cw_no_cancel_self,
|
|
||||||
cw_no_cancel
|
|
||||||
};
|
|
||||||
|
|
||||||
DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL,
|
|
||||||
const cw_cancel_action = cw_cancel_self,
|
|
||||||
const enum cw_sig_wait = cw_sig_nosig)
|
|
||||||
__attribute__ ((regparm (3)));
|
|
||||||
|
|
||||||
class fast_mutex
|
class fast_mutex
|
||||||
{
|
{
|
||||||
@ -78,7 +60,7 @@ public:
|
|||||||
void lock ()
|
void lock ()
|
||||||
{
|
{
|
||||||
if (InterlockedIncrement ((long *) &lock_counter) != 1)
|
if (InterlockedIncrement ((long *) &lock_counter) != 1)
|
||||||
cancelable_wait (win32_obj_id, NULL, cw_no_cancel, cw_sig_resume);
|
cancelable_wait (win32_obj_id, NULL, cw_sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unlock ()
|
void unlock ()
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* wait.cc: Posix wait routines.
|
/* wait.cc: Posix wait routines.
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||||
2005, 2009, 2011 Red Hat, Inc.
|
2005, 2009, 2011, 2012 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -14,6 +14,7 @@ details. */
|
|||||||
#include "sigproc.h"
|
#include "sigproc.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "cygtls.h"
|
#include "cygtls.h"
|
||||||
|
#include "cygwait.h"
|
||||||
|
|
||||||
/* This is called _wait and not wait because the real wait is defined
|
/* This is called _wait and not wait because the real wait is defined
|
||||||
in libc/syscalls/syswait.c. It calls us. */
|
in libc/syscalls/syswait.c. It calls us. */
|
||||||
@ -79,7 +80,7 @@ wait4 (int intpid, int *status, int options, struct rusage *r)
|
|||||||
if ((waitfor = w->ev) == NULL)
|
if ((waitfor = w->ev) == NULL)
|
||||||
goto nochildren;
|
goto nochildren;
|
||||||
|
|
||||||
res = cancelable_wait (waitfor);
|
res = cancelable_wait (waitfor, NULL, cw_cancel | cw_cancel_self);
|
||||||
|
|
||||||
sigproc_printf ("%d = cancelable_wait (...)", res);
|
sigproc_printf ("%d = cancelable_wait (...)", res);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user