* DevNotes: Add entry cgf-000013.
* cygserver_ipc.h (ipc_set_proc_info): Use _cygtls::ipc_set_proc_info to set per-thread signal arrived value. * cygthread.cc (cygthread::detach): Use per-thread signal_arrived via set_thread_waiting. * fork.cc (_cygtls::fixup_after_fork): Clear signal_arrived. (_cygtls::remove): Close any signal_arrived handle when thread exists. (_cygtls::find_tls): Remove unneeded function. * cygtls.h: Update copyright. (class _cygtls): Reorganize to help avoid rebuilding newlib when structure changes. (_cygtls::event): Delete. (_cygtls::threadkill): Ditto. (_cygtls::signal_waiting): Declare new bool. (_cygtls::find_tls): Delete declaration. (_cygtls::set_threadkill): Ditto. (_cygtls::reset_threadkill): Ditto. (_cygtls::set_signal_arrived): Declare new function. (class set_thread_waiting): Declare new class. * cygwait.cc (cw_nowait_storage): Define. (cygwait): Set per-thread signal_arrived via set_thread_waiting. Don't special-case _main_tls. * cygwait.h (cw_nowait): Define. (cw_infinite): Ditto. (cygwait): Redefine pathological wait-only case. * dcrt0.cc (dll_crt0_0): Remove call to now-defunct events_init(). (dll_crt0_1): Remove call to now-defunct create_signal_arrived(). * exceptions.cc: Reflect set_signal_mask() argument reordering throughout. Remove signal mask synchronization throughout. (events_init): Delete definition. (mask_sync): Delete now-unneeded mask synchronization. (set_signal_mask): Reverse order of arguments to "standard" to, from layout. Rename "newmask" argument to "setmask". Remove debugging. (sig_handle_tty_stop): Use cancelable_wait rather than WFMO. (_cygtls::interrupt_setup): Don't treat "threadkill" events specially. Conditionally set signal_arrived depending on whether the thread has created it or not. (sigpacket::process): Reorganize to reflect thread-specific sending of signals which is more in line with the way it was actually supposed to work. * fhandler_socket.cc (get_inet_addr): Use cancelable_wait rather than IsEventSignalled to avoid potential race. (fhandler_socket::wait_for_events): Set signal_arrived event using set_thread_waiting(). (fhandler_socket::close): Use cygwait for the case of just waiting 10 ms for a signal. * fhandler_tape.cc (fhandler_dev_tape::_lock): Use cancelable_wait rather than WFMO. Redo switch/case tests accordingly. * fhandler_termios.cc (fhandler_termios::bg_check): Use cygwait for case of just waiting 0 ms for a potential signal. * fhandler_tty.cc (fhandler_pty_master::process_slave_output): Use cancelable_wait rather than WFSO. * fhandler_windows.cc (fhandler_windows::read): Set per-thread signal_arrived via set_thread_waiting(). * flock.cc (lf_setlock): Ditto. * select.cc (pselect): Ditto. Set per-thread signal_arrived using set_thread_waiting(). * gendef: Don't special case handling of _cygtls::sig for threads. * gentls_offsets: Use #pragma once in tlsoffsets.h. * ntdll.h: Use #pragma once. * poll.cc: Reflect set_signal_mask() argument reordering. * posix_ipc.cc (ipc_mutex_lock): Use cancelable_wait rather than WFMO. (ipc_cond_timedwait): Set perl-thread signal arrived using set_thread_waiting(). * security.h: Use #pragma once. * signal.cc (abort): Reflect set_signal_mask() argument reordering. (clock_nanosleep): Ditto. Change call to cancelable_wait to properly specify handling of cancel and interrupt. (sigwaitinfo): Remove handling of per-thread event in favor of per-thread signal_arrived. Use cancelable_wait rather than WFSO. * sigproc.cc (signal_arrived): Delete definition. (create_signal_arrived): Ditto. * sigproc.h (signal_arrived): Delete declaration. (set_signal_mask): Avoid defining as a "C" function. Don't conditionally declare. (create_signal_arrived): Delete declaration. * syscalls.cc (rename): Use cygwait() rather than WFSO. * thread.h (fast_mutex::lock): Use cw_infinite rather than LARGE_NULL. * wait.cc (wait4): Ditto. * thread.cc (pthread_mutex::lock): Ditto. (pthread::join): Ditto. (semaphore::_wait): Ditto. (pthread_kill): Remove set_threadkill() accommodation. * tlsoffsets.h: Regenerate.
This commit is contained in:
parent
b8a84b73d7
commit
962f9a2ccc
@ -1,3 +1,90 @@
|
||||
2012-07-21 Christopher Faylor <me.cygwin2012@cgf.cx>
|
||||
|
||||
* DevNotes: Add entry cgf-000013.
|
||||
* cygserver_ipc.h (ipc_set_proc_info): Use _cygtls::ipc_set_proc_info
|
||||
to set per-thread signal arrived value.
|
||||
* cygthread.cc (cygthread::detach): Use per-thread signal_arrived via
|
||||
set_thread_waiting.
|
||||
* fork.cc (_cygtls::fixup_after_fork): Clear signal_arrived.
|
||||
(_cygtls::remove): Close any signal_arrived handle when thread exists.
|
||||
(_cygtls::find_tls): Remove unneeded function.
|
||||
* cygtls.h: Update copyright.
|
||||
(class _cygtls): Reorganize to help avoid rebuilding newlib when
|
||||
structure changes.
|
||||
(_cygtls::event): Delete.
|
||||
(_cygtls::threadkill): Ditto.
|
||||
(_cygtls::signal_waiting): Declare new bool.
|
||||
(_cygtls::find_tls): Delete declaration.
|
||||
(_cygtls::set_threadkill): Ditto.
|
||||
(_cygtls::reset_threadkill): Ditto.
|
||||
(_cygtls::set_signal_arrived): Declare new function.
|
||||
(class set_thread_waiting): Declare new class.
|
||||
* cygwait.cc (cw_nowait_storage): Define.
|
||||
(cygwait): Set per-thread signal_arrived via set_thread_waiting. Don't
|
||||
special-case _main_tls.
|
||||
* cygwait.h (cw_nowait): Define.
|
||||
(cw_infinite): Ditto.
|
||||
(cygwait): Redefine pathological wait-only case.
|
||||
* dcrt0.cc (dll_crt0_0): Remove call to now-defunct events_init().
|
||||
(dll_crt0_1): Remove call to now-defunct create_signal_arrived().
|
||||
* exceptions.cc: Reflect set_signal_mask() argument reordering
|
||||
throughout. Remove signal mask synchronization throughout.
|
||||
(events_init): Delete definition.
|
||||
(mask_sync): Delete now-unneeded mask synchronization.
|
||||
(set_signal_mask): Reverse order of arguments to "standard" to, from
|
||||
layout. Rename "newmask" argument to "setmask". Remove debugging.
|
||||
(sig_handle_tty_stop): Use cancelable_wait rather than WFMO.
|
||||
(_cygtls::interrupt_setup): Don't treat "threadkill" events specially.
|
||||
Conditionally set signal_arrived depending on whether the thread has
|
||||
created it or not.
|
||||
(sigpacket::process): Reorganize to reflect thread-specific sending of
|
||||
signals which is more in line with the way it was actually supposed to
|
||||
work.
|
||||
* fhandler_socket.cc (get_inet_addr): Use cancelable_wait rather than
|
||||
IsEventSignalled to avoid potential race.
|
||||
(fhandler_socket::wait_for_events): Set signal_arrived event using
|
||||
set_thread_waiting().
|
||||
(fhandler_socket::close): Use cygwait for the case of just
|
||||
waiting 10 ms for a signal.
|
||||
* fhandler_tape.cc (fhandler_dev_tape::_lock): Use cancelable_wait
|
||||
rather than WFMO. Redo switch/case tests accordingly.
|
||||
* fhandler_termios.cc (fhandler_termios::bg_check): Use cygwait for
|
||||
case of just waiting 0 ms for a potential signal.
|
||||
* fhandler_tty.cc (fhandler_pty_master::process_slave_output): Use
|
||||
cancelable_wait rather than WFSO.
|
||||
* fhandler_windows.cc (fhandler_windows::read): Set per-thread
|
||||
signal_arrived via set_thread_waiting().
|
||||
* flock.cc (lf_setlock): Ditto.
|
||||
* select.cc (pselect): Ditto. Set per-thread signal_arrived using
|
||||
set_thread_waiting().
|
||||
* gendef: Don't special case handling of _cygtls::sig for threads.
|
||||
* gentls_offsets: Use #pragma once in tlsoffsets.h.
|
||||
* ntdll.h: Use #pragma once.
|
||||
* poll.cc: Reflect set_signal_mask() argument reordering.
|
||||
* posix_ipc.cc (ipc_mutex_lock): Use cancelable_wait rather than WFMO.
|
||||
(ipc_cond_timedwait): Set perl-thread signal arrived using
|
||||
set_thread_waiting().
|
||||
* security.h: Use #pragma once.
|
||||
* signal.cc (abort): Reflect set_signal_mask() argument reordering.
|
||||
(clock_nanosleep): Ditto. Change call to cancelable_wait to properly
|
||||
specify handling of cancel and interrupt.
|
||||
(sigwaitinfo): Remove handling of per-thread event in favor of
|
||||
per-thread signal_arrived. Use cancelable_wait rather than WFSO.
|
||||
* sigproc.cc (signal_arrived): Delete definition.
|
||||
(create_signal_arrived): Ditto.
|
||||
* sigproc.h (signal_arrived): Delete declaration.
|
||||
(set_signal_mask): Avoid defining as a "C" function. Don't
|
||||
conditionally declare.
|
||||
(create_signal_arrived): Delete declaration.
|
||||
* syscalls.cc (rename): Use cygwait() rather than WFSO.
|
||||
* thread.h (fast_mutex::lock): Use cw_infinite rather than LARGE_NULL.
|
||||
* wait.cc (wait4): Ditto.
|
||||
* thread.cc (pthread_mutex::lock): Ditto.
|
||||
(pthread::join): Ditto.
|
||||
(semaphore::_wait): Ditto.
|
||||
(pthread_kill): Remove set_threadkill() accommodation.
|
||||
* tlsoffsets.h: Regenerate.
|
||||
|
||||
2012-07-21 Christopher Faylor <me.cygwin2012@cgf.cx>
|
||||
|
||||
* include/cygwin/version.h (CYGWIN_VERSION_DLL_MINOR): Bump to 17.
|
||||
|
@ -1,3 +1,24 @@
|
||||
2012-07-21 cgf-000013
|
||||
|
||||
These changes reflect a revamp of the "wait for signal" functionality
|
||||
which has existed in Cygwin through several signal massages.
|
||||
|
||||
We now create a signal event only when a thread is waiting for a signal
|
||||
and arm it only for that thread. The "set_thread_waiting" function is
|
||||
used to establish the event and set it in a location referencable by
|
||||
the caller.
|
||||
|
||||
I still do not handle all of the race conditions. What happens when
|
||||
a signal comes in just after a WF?O succeeds for some other purpose? I
|
||||
suspect that it will arm the next WF?O call and the subsequent call to
|
||||
call_signal_handler could cause a function to get an EINTR when possibly
|
||||
it shouldn't have.
|
||||
|
||||
I haven't yet checked all of the test cases for the URL listed in the
|
||||
previous entry.
|
||||
|
||||
Baby steps.
|
||||
|
||||
2012-06-12 cgf-000012
|
||||
|
||||
These changes are the preliminary for redoing the way threads wait for
|
||||
|
@ -43,7 +43,7 @@ ipc_set_proc_info (proc &blk)
|
||||
blk.gidcnt = 0;
|
||||
blk.gidlist = NULL;
|
||||
blk.is_admin = false;
|
||||
blk.signal_arrived = signal_arrived;
|
||||
_my_tls.set_signal_arrived (true, blk.signal_arrived);
|
||||
}
|
||||
#endif /* __INSIDE_CYGWIN__ */
|
||||
|
||||
|
@ -377,7 +377,7 @@ cygthread::detach (HANDLE sigwait)
|
||||
unsigned n = 2;
|
||||
DWORD howlong = INFINITE;
|
||||
w4[0] = sigwait;
|
||||
w4[1] = signal_arrived;
|
||||
set_thread_waiting here (w4[1]);
|
||||
/* For a description of the below loop see the end of this file */
|
||||
for (int i = 0; i < 2; i++)
|
||||
switch (res = WaitForMultipleObjects (n, w4, FALSE, howlong))
|
||||
|
@ -190,6 +190,7 @@ _cygtls::fixup_after_fork ()
|
||||
sig = 0;
|
||||
}
|
||||
stacklock = spinning = 0;
|
||||
signal_arrived = NULL;
|
||||
locals.select.sockevt = NULL;
|
||||
locals.cw_timer = NULL;
|
||||
wq.thread_ev = NULL;
|
||||
@ -214,6 +215,13 @@ _cygtls::remove (DWORD wait)
|
||||
/* FIXME: Need some sort of atthreadexit function to allow things like
|
||||
select to control this themselves. */
|
||||
|
||||
if (signal_arrived)
|
||||
{
|
||||
HANDLE h = signal_arrived;
|
||||
signal_arrived = NULL;
|
||||
CloseHandle (h);
|
||||
}
|
||||
|
||||
/* Close handle and free memory used by select. */
|
||||
if (locals.select.sockevt)
|
||||
{
|
||||
@ -254,31 +262,6 @@ _cygtls::push (__stack_t addr)
|
||||
*stackptr++ = (__stack_t) addr;
|
||||
}
|
||||
|
||||
|
||||
_cygtls *
|
||||
_cygtls::find_tls (int sig)
|
||||
{
|
||||
static int NO_COPY threadlist_ix;
|
||||
|
||||
debug_printf ("signal %d\n", sig);
|
||||
sentry here (INFINITE);
|
||||
|
||||
_cygtls *res = NULL;
|
||||
threadlist_ix = -1;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
cygheap->threadlist[threadlist_ix]->remove (INFINITE);
|
||||
|
||||
while (++threadlist_ix < (int) nthreads)
|
||||
if (sigismember (&(cygheap->threadlist[threadlist_ix]->sigwait_mask), sig))
|
||||
{
|
||||
res = cygheap->threadlist[threadlist_ix];
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
_cygtls::set_siginfo (sigpacket *pack)
|
||||
{
|
||||
|
@ -1,13 +1,12 @@
|
||||
/* cygtls.h
|
||||
|
||||
Copyright 2003, 2004, 2005, 2008, 2009, 2010, 2011 Red Hat, Inc.
|
||||
Copyright 2003, 2004, 2005, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#ifndef _CYGTLS_H
|
||||
#define _CYGTLS_H
|
||||
#pragma once
|
||||
|
||||
#include <signal.h>
|
||||
#include <pwd.h>
|
||||
@ -158,6 +157,7 @@ typedef struct struct_waitq
|
||||
|
||||
/*gentls_offsets*/
|
||||
#include "cygerrno.h"
|
||||
#include "security.h"
|
||||
|
||||
extern "C" int __sjfault (jmp_buf);
|
||||
extern "C" int __ljfault (jmp_buf, int);
|
||||
@ -169,27 +169,29 @@ typedef __uint32_t __stack_t;
|
||||
class _cygtls
|
||||
{
|
||||
public:
|
||||
void (*func) /*gentls_offsets*/(int)/*gentls_offsets*/;
|
||||
int saved_errno;
|
||||
int sa_flags;
|
||||
sigset_t oldmask;
|
||||
sigset_t deltamask;
|
||||
HANDLE event;
|
||||
int *errno_addr;
|
||||
sigset_t sigmask;
|
||||
sigset_t sigwait_mask;
|
||||
siginfo_t *sigwait_info;
|
||||
struct ucontext thread_context;
|
||||
DWORD thread_id;
|
||||
unsigned threadkill;
|
||||
siginfo_t infodata;
|
||||
struct pthread *tid;
|
||||
/* Please keep these two declarations first */
|
||||
struct _local_storage locals;
|
||||
union
|
||||
{
|
||||
struct _reent local_clib;
|
||||
char __dontuse[8 * ((sizeof(struct _reent) + 4) / 8)];
|
||||
};
|
||||
struct _local_storage locals;
|
||||
/**/
|
||||
void (*func) /*gentls_offsets*/(int)/*gentls_offsets*/;
|
||||
int saved_errno;
|
||||
int sa_flags;
|
||||
sigset_t oldmask;
|
||||
sigset_t deltamask;
|
||||
int *errno_addr;
|
||||
sigset_t sigmask;
|
||||
sigset_t sigwait_mask;
|
||||
siginfo_t *sigwait_info;
|
||||
HANDLE signal_arrived;
|
||||
bool signal_waiting;
|
||||
struct ucontext thread_context;
|
||||
DWORD thread_id;
|
||||
siginfo_t infodata;
|
||||
struct pthread *tid;
|
||||
class cygthread *_ctinfo;
|
||||
class san *andreas;
|
||||
waitq wq;
|
||||
@ -205,7 +207,6 @@ public:
|
||||
static void init ();
|
||||
void init_thread (void *, DWORD (*) (void *, void *));
|
||||
static void call (DWORD (*) (void *, void *), void *);
|
||||
static struct _cygtls *find_tls (int sig);
|
||||
void remove (DWORD);
|
||||
void push (__stack_t) __attribute__ ((regparm (2)));
|
||||
__stack_t pop () __attribute__ ((regparm (1)));
|
||||
@ -229,14 +230,24 @@ public:
|
||||
operator HANDLE () const {return tid->win32_obj_id;}
|
||||
#endif
|
||||
void set_siginfo (struct sigpacket *) __attribute__ ((regparm (3)));
|
||||
void set_threadkill () {threadkill = true;}
|
||||
void reset_threadkill () {threadkill = false;}
|
||||
int call_signal_handler () __attribute__ ((regparm (1)));
|
||||
void remove_wq (DWORD) __attribute__ ((regparm (1)));
|
||||
void fixup_after_fork () __attribute__ ((regparm (1)));
|
||||
void lock () __attribute__ ((regparm (1)));
|
||||
void unlock () __attribute__ ((regparm (1)));
|
||||
bool locked () __attribute__ ((regparm (1)));
|
||||
void set_signal_arrived (bool setit, HANDLE& h)
|
||||
{
|
||||
if (!setit)
|
||||
signal_waiting = false;
|
||||
else
|
||||
{
|
||||
if (!signal_arrived)
|
||||
signal_arrived = CreateEvent (&sec_none_nih, false, false, NULL);
|
||||
h = signal_arrived;
|
||||
signal_waiting = true;
|
||||
}
|
||||
}
|
||||
private:
|
||||
void call2 (DWORD (*) (void *, void *), void *, void *) __attribute__ ((regparm (3)));
|
||||
/*gentls_offsets*/
|
||||
@ -304,6 +315,15 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#define __getreent() (&_my_tls.local_clib)
|
||||
class set_thread_waiting
|
||||
{
|
||||
public:
|
||||
set_thread_waiting (bool setit, HANDLE& h) { _my_tls.set_signal_arrived (setit, h); }
|
||||
set_thread_waiting (HANDLE& h) { _my_tls.set_signal_arrived (true, h); }
|
||||
|
||||
#endif /*_CYGTLS_H*/ /*gentls_offsets*/
|
||||
operator int () const {return _my_tls.signal_waiting;}
|
||||
~set_thread_waiting () { _my_tls.signal_waiting = false; }
|
||||
};
|
||||
|
||||
#define __getreent() (&_my_tls.local_clib)
|
||||
/*gentls_offsets*/
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#define is_cw_sig_handle (mask & (is_cw_sig | is_cw_sig_eintr))
|
||||
|
||||
LARGE_INTEGER cw_nowait_storage;
|
||||
|
||||
DWORD
|
||||
cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
|
||||
{
|
||||
@ -36,14 +38,13 @@ cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
|
||||
if (object)
|
||||
wait_objects[num++] = object;
|
||||
|
||||
set_thread_waiting thread_waiting (is_cw_sig_handle, wait_objects[num]);
|
||||
debug_printf ("thread waiting %d, signal_arrived %p", (int) thread_waiting, _my_tls.signal_arrived);
|
||||
DWORD sig_n;
|
||||
if (!is_cw_sig_handle)
|
||||
if (!thread_waiting)
|
||||
sig_n = WAIT_TIMEOUT + 1;
|
||||
else
|
||||
{
|
||||
sig_n = WAIT_OBJECT_0 + num++;
|
||||
wait_objects[sig_n] = signal_arrived;
|
||||
}
|
||||
sig_n = WAIT_OBJECT_0 + num++;
|
||||
|
||||
DWORD cancel_n;
|
||||
if (!is_cw_cancel || !pthread::is_good_object (&thread) ||
|
||||
@ -79,7 +80,7 @@ cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
|
||||
/* all set */;
|
||||
else if (is_cw_sig_eintr)
|
||||
res = WAIT_SIGNALED; /* caller will deal with signals */
|
||||
else if (_my_tls.call_signal_handler () || &_my_tls != _main_tls)
|
||||
else if (_my_tls.call_signal_handler ())
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
@ -22,7 +22,10 @@ enum cw_wait_mask
|
||||
cw_sig_eintr = 0x0008
|
||||
};
|
||||
|
||||
#define LARGE_NULL ((PLARGE_INTEGER) NULL)
|
||||
extern LARGE_INTEGER cw_nowait_storage;
|
||||
#define cw_nowait (&cw_nowait_storage)
|
||||
#define cw_infinite ((PLARGE_INTEGER) NULL)
|
||||
|
||||
const unsigned cw_std_mask = cw_cancel | cw_cancel_self | cw_sig;
|
||||
|
||||
DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL,
|
||||
@ -53,5 +56,5 @@ cygwait (HANDLE h, DWORD howlong = INFINITE)
|
||||
static inline DWORD __attribute__ ((always_inline))
|
||||
cygwait (DWORD howlong)
|
||||
{
|
||||
return cancelable_wait (NULL, howlong, cw_cancel | cw_sig_eintr);
|
||||
return cygwait (NULL, howlong);
|
||||
}
|
||||
|
@ -774,9 +774,6 @@ dll_crt0_0 ()
|
||||
user_data->threadinterface->Init ();
|
||||
|
||||
_cygtls::init ();
|
||||
|
||||
/* Initialize events */
|
||||
events_init ();
|
||||
tty_list::init_session ();
|
||||
|
||||
_main_tls = &_my_tls;
|
||||
@ -843,8 +840,6 @@ dll_crt0_1 (void *)
|
||||
strace.microseconds ();
|
||||
#endif
|
||||
|
||||
create_signal_arrived (); /* FIXME: move into wait_sig? */
|
||||
|
||||
/* Initialize debug muto, if DLL is built with --enable-debugging.
|
||||
Need to do this before any helper threads start. */
|
||||
debug_init ();
|
||||
|
@ -19,8 +19,8 @@ details. */
|
||||
#include <syslog.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include "pinfo.h"
|
||||
#include "cygtls.h"
|
||||
#include "pinfo.h"
|
||||
#include "sigproc.h"
|
||||
#include "shared_info.h"
|
||||
#include "perprocess.h"
|
||||
@ -31,7 +31,6 @@ details. */
|
||||
#include "child_info.h"
|
||||
#include "ntdll.h"
|
||||
#include "exception.h"
|
||||
#include "cygwait.h"
|
||||
|
||||
#define CALL_HANDLER_RETRY_OUTER 10
|
||||
#define CALL_HANDLER_RETRY_INNER 10
|
||||
@ -47,7 +46,6 @@ static BOOL WINAPI ctrl_c_handler (DWORD);
|
||||
/* This is set to indicate that we have already exited. */
|
||||
|
||||
static NO_COPY int exit_already = 0;
|
||||
static muto NO_COPY mask_sync;
|
||||
|
||||
NO_COPY static struct
|
||||
{
|
||||
@ -710,11 +708,11 @@ handle_sigsuspend (sigset_t tempmask)
|
||||
{
|
||||
sigset_t oldmask = _my_tls.sigmask; // Remember for restoration
|
||||
|
||||
set_signal_mask (tempmask, _my_tls.sigmask);
|
||||
set_signal_mask (_my_tls.sigmask, tempmask);
|
||||
sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask);
|
||||
|
||||
pthread_testcancel ();
|
||||
cancelable_wait (signal_arrived, LARGE_NULL, cw_cancel | cw_cancel_self);
|
||||
cancelable_wait (NULL, cw_infinite, cw_cancel | cw_cancel_self | cw_sig_eintr);
|
||||
|
||||
set_sig_errno (EINTR); // Per POSIX
|
||||
|
||||
@ -747,8 +745,7 @@ sig_handle_tty_stop (int sig)
|
||||
sigproc_printf ("process %d stopped by signal %d", myself->pid, sig);
|
||||
HANDLE w4[2];
|
||||
w4[0] = sigCONT;
|
||||
w4[1] = signal_arrived;
|
||||
switch (WaitForMultipleObjects (2, w4, TRUE, INFINITE))
|
||||
switch (cancelable_wait (sigCONT, cw_infinite, cw_sig_eintr))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
@ -804,20 +801,11 @@ _cygtls::interrupt_setup (int sig, void *handler, struct sigaction& siga)
|
||||
|
||||
this->sig = sig; // Should always be last thing set to avoid a race
|
||||
|
||||
if (!event)
|
||||
threadkill = false;
|
||||
else
|
||||
{
|
||||
HANDLE h = event;
|
||||
event = NULL;
|
||||
SetEvent (h);
|
||||
}
|
||||
if (signal_arrived)
|
||||
SetEvent (signal_arrived);
|
||||
|
||||
/* Clear any waiting threads prior to dispatching to handler function */
|
||||
int res = SetEvent (signal_arrived); // For an EINTR case
|
||||
proc_subproc (PROC_CLEARWAIT, 1);
|
||||
sigproc_printf ("armed signal_arrived %p, signal %d, res %d", signal_arrived,
|
||||
sig, res);
|
||||
sigproc_printf ("armed signal_arrived %p, signal %d", signal_arrived, sig);
|
||||
}
|
||||
|
||||
extern "C" void __stdcall
|
||||
@ -1021,7 +1009,7 @@ ctrl_c_handler (DWORD type)
|
||||
extern "C" void __stdcall
|
||||
set_process_mask (sigset_t newmask)
|
||||
{
|
||||
set_signal_mask (newmask, _my_tls.sigmask);
|
||||
set_signal_mask (_my_tls.sigmask, newmask);
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
@ -1034,11 +1022,9 @@ sighold (int sig)
|
||||
syscall_printf ("signal %d out of range", sig);
|
||||
return -1;
|
||||
}
|
||||
mask_sync.acquire (INFINITE);
|
||||
sigset_t mask = _my_tls.sigmask;
|
||||
sigaddset (&mask, sig);
|
||||
set_signal_mask (mask, _my_tls.sigmask);
|
||||
mask_sync.release ();
|
||||
set_signal_mask (_my_tls.sigmask, mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1052,11 +1038,9 @@ sigrelse (int sig)
|
||||
syscall_printf ("signal %d out of range", sig);
|
||||
return -1;
|
||||
}
|
||||
mask_sync.acquire (INFINITE);
|
||||
sigset_t mask = _my_tls.sigmask;
|
||||
sigdelset (&mask, sig);
|
||||
set_signal_mask (mask, _my_tls.sigmask);
|
||||
mask_sync.release ();
|
||||
set_signal_mask (_my_tls.sigmask, mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1074,7 +1058,6 @@ sigset (int sig, _sig_func_ptr func)
|
||||
return (_sig_func_ptr) SIG_ERR;
|
||||
}
|
||||
|
||||
mask_sync.acquire (INFINITE);
|
||||
sigset_t mask = _my_tls.sigmask;
|
||||
/* If sig was in the signal mask return SIG_HOLD, otherwise return the
|
||||
previous disposition. */
|
||||
@ -1093,8 +1076,7 @@ sigset (int sig, _sig_func_ptr func)
|
||||
signal (sig, func);
|
||||
sigdelset (&mask, sig);
|
||||
}
|
||||
set_signal_mask (mask, _my_tls.sigmask);
|
||||
mask_sync.release ();
|
||||
set_signal_mask (_my_tls.sigmask, mask);
|
||||
return prev;
|
||||
}
|
||||
|
||||
@ -1109,7 +1091,6 @@ sigignore (int sig)
|
||||
extern "C" sigset_t
|
||||
set_process_mask_delta ()
|
||||
{
|
||||
mask_sync.acquire (INFINITE);
|
||||
sigset_t newmask, oldmask;
|
||||
|
||||
if (_my_tls.deltamask & SIG_NONMASKABLE)
|
||||
@ -1120,28 +1101,22 @@ set_process_mask_delta ()
|
||||
sigproc_printf ("oldmask %p, newmask %p, deltamask %p", oldmask, newmask,
|
||||
_my_tls.deltamask);
|
||||
_my_tls.sigmask = newmask;
|
||||
mask_sync.release ();
|
||||
return oldmask;
|
||||
}
|
||||
|
||||
/* Set the signal mask for this process.
|
||||
Note that some signals are unmaskable, as in UNIX. */
|
||||
extern "C" void __stdcall
|
||||
set_signal_mask (sigset_t newmask, sigset_t& oldmask)
|
||||
|
||||
void
|
||||
set_signal_mask (sigset_t& setmask, sigset_t newmask)
|
||||
{
|
||||
#ifdef CGF
|
||||
if (&_my_tls == _sig_tls)
|
||||
small_printf ("********* waiting in signal thread\n");
|
||||
#endif
|
||||
mask_sync.acquire (INFINITE);
|
||||
newmask &= ~SIG_NONMASKABLE;
|
||||
sigset_t mask_bits = oldmask & ~newmask;
|
||||
sigproc_printf ("oldmask %p, newmask %p, mask_bits %p", oldmask, newmask,
|
||||
sigset_t mask_bits = setmask & ~newmask;
|
||||
sigproc_printf ("setmask %p, newmask %p, mask_bits %p", setmask, newmask,
|
||||
mask_bits);
|
||||
oldmask = newmask;
|
||||
setmask = newmask;
|
||||
if (mask_bits)
|
||||
sig_dispatch_pending (true);
|
||||
mask_sync.release ();
|
||||
}
|
||||
|
||||
int __stdcall
|
||||
@ -1184,17 +1159,23 @@ sigpacket::process ()
|
||||
|
||||
myself->rusage_self.ru_nsignals++;
|
||||
|
||||
bool masked;
|
||||
void *handler;
|
||||
if (!have_execed || (void *) thissig.sa_handler == (void *) SIG_IGN)
|
||||
handler = (void *) thissig.sa_handler;
|
||||
else if (tls)
|
||||
return 1;
|
||||
else
|
||||
void *handler = (void *) thissig.sa_handler;
|
||||
if (handler == SIG_IGN)
|
||||
{
|
||||
sigproc_printf ("signal %d ignored", si.si_signo);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (have_execed)
|
||||
handler = NULL;
|
||||
|
||||
_cygtls *use_tls = tls ?: _main_tls;
|
||||
sigproc_printf ("tls %p, use_tls %p", tls, use_tls);
|
||||
if (tls)
|
||||
sigproc_printf ("using tls %p", tls);
|
||||
else
|
||||
{
|
||||
tls = _main_tls;
|
||||
sigproc_printf ("using main tls %p", _main_tls);
|
||||
}
|
||||
|
||||
if (si.si_signo == SIGKILL)
|
||||
goto exit_sig;
|
||||
@ -1204,30 +1185,12 @@ sigpacket::process ()
|
||||
goto stop;
|
||||
}
|
||||
|
||||
bool insigwait_mask;
|
||||
if ((masked = ISSTATE (myself, PID_STOPPED)))
|
||||
insigwait_mask = false;
|
||||
else if (tls)
|
||||
insigwait_mask = sigismember (&tls->sigwait_mask, si.si_signo);
|
||||
else if (!(tls = _cygtls::find_tls (si.si_signo)))
|
||||
insigwait_mask = false;
|
||||
else
|
||||
if (sigismember (&tls->sigwait_mask, si.si_signo))
|
||||
{
|
||||
use_tls = tls;
|
||||
insigwait_mask = true;
|
||||
tls->sigwait_mask = 0;
|
||||
goto dosig;
|
||||
}
|
||||
|
||||
if (insigwait_mask)
|
||||
goto thread_specific;
|
||||
|
||||
if (masked)
|
||||
/* nothing to do */;
|
||||
else if (sigismember (mask, si.si_signo))
|
||||
masked = true;
|
||||
else if (tls)
|
||||
masked = sigismember (&tls->sigmask, si.si_signo);
|
||||
|
||||
if (masked)
|
||||
if (sigismember (&tls->sigmask, si.si_signo) || ISSTATE (myself, PID_STOPPED))
|
||||
{
|
||||
sigproc_printf ("signal %d blocked", si.si_signo);
|
||||
rc = -1;
|
||||
@ -1240,14 +1203,12 @@ sigpacket::process ()
|
||||
|
||||
if (handler == (void *) SIG_DFL)
|
||||
{
|
||||
if (insigwait_mask)
|
||||
goto thread_specific;
|
||||
if (si.si_signo == SIGCHLD || si.si_signo == SIGIO || si.si_signo == SIGCONT || si.si_signo == SIGWINCH
|
||||
|| si.si_signo == SIGURG)
|
||||
{
|
||||
sigproc_printf ("default signal %d ignored", si.si_signo);
|
||||
if (continue_now)
|
||||
SetEvent (signal_arrived);
|
||||
SetEvent (tls->signal_arrived);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -1257,16 +1218,9 @@ sigpacket::process ()
|
||||
goto exit_sig;
|
||||
}
|
||||
|
||||
if (handler == (void *) SIG_IGN)
|
||||
{
|
||||
sigproc_printf ("signal %d ignored", si.si_signo);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (handler == (void *) SIG_ERR)
|
||||
goto exit_sig;
|
||||
|
||||
use_tls->set_siginfo (this);
|
||||
goto dosig;
|
||||
|
||||
stop:
|
||||
@ -1277,33 +1231,19 @@ stop:
|
||||
thissig = dummy;
|
||||
|
||||
dosig:
|
||||
tls->set_siginfo (this);
|
||||
/* Dispatch to the appropriate function. */
|
||||
sigproc_printf ("signal %d, about to call %p", si.si_signo, handler);
|
||||
rc = setup_handler (si.si_signo, handler, thissig, use_tls);
|
||||
sigproc_printf ("signal %d, signal handler %p", si.si_signo, handler);
|
||||
rc = setup_handler (si.si_signo, handler, thissig, tls);
|
||||
|
||||
done:
|
||||
tls = use_tls;
|
||||
if (continue_now)
|
||||
SetEvent (sigCONT);
|
||||
sigproc_printf ("returning %d", rc);
|
||||
return rc;
|
||||
|
||||
thread_specific:
|
||||
use_tls->sig = si.si_signo;
|
||||
use_tls->set_siginfo (this);
|
||||
use_tls->func = NULL;
|
||||
sigproc_printf ("releasing sigwait for thread");
|
||||
SetEvent (use_tls->event);
|
||||
goto done;
|
||||
|
||||
exit_sig:
|
||||
use_tls->signal_exit (si.si_signo); /* never returns */
|
||||
}
|
||||
|
||||
void
|
||||
events_init ()
|
||||
{
|
||||
mask_sync.init ("mask_sync");
|
||||
tls->signal_exit (si.si_signo); /* never returns */
|
||||
}
|
||||
|
||||
void
|
||||
@ -1321,23 +1261,7 @@ _cygtls::call_signal_handler ()
|
||||
lock ();
|
||||
if (sig)
|
||||
pop ();
|
||||
else if (this != _main_tls)
|
||||
{
|
||||
_main_tls->lock ();
|
||||
if (_main_tls->sig && _main_tls->incyg)
|
||||
{
|
||||
paranoid_printf ("Redirecting to main_tls signal %d", _main_tls->sig);
|
||||
sig = _main_tls->sig;
|
||||
sa_flags = _main_tls->sa_flags;
|
||||
func = _main_tls->func;
|
||||
infodata = _main_tls->infodata;
|
||||
_main_tls->pop ();
|
||||
_main_tls->sig = 0;
|
||||
|
||||
}
|
||||
_main_tls->unlock ();
|
||||
}
|
||||
if (!sig)
|
||||
else
|
||||
break;
|
||||
|
||||
debug_only_printf ("dealing with signal %d", sig);
|
||||
@ -1364,7 +1288,7 @@ _cygtls::call_signal_handler ()
|
||||
sigact (thissig, &thissi, NULL);
|
||||
}
|
||||
incyg = true;
|
||||
set_signal_mask (this_oldmask, _my_tls.sigmask);
|
||||
set_signal_mask (_my_tls.sigmask, this_oldmask);
|
||||
if (this_errno >= 0)
|
||||
set_errno (this_errno);
|
||||
}
|
||||
|
@ -125,9 +125,7 @@ get_inet_addr (const struct sockaddr *in, int inlen,
|
||||
some greedy Win32 application. Therefore we should never wait
|
||||
endlessly without checking for signals and thread cancel event. */
|
||||
pthread_testcancel ();
|
||||
/* Using IsEventSignalled like this is racy since another thread could
|
||||
be waiting for signal_arrived. */
|
||||
if (IsEventSignalled (signal_arrived)
|
||||
if (cancelable_wait (NULL, cw_nowait, cw_sig_eintr) == WAIT_SIGNALED
|
||||
&& !_my_tls.call_signal_handler ())
|
||||
{
|
||||
set_errno (EINTR);
|
||||
@ -659,7 +657,8 @@ fhandler_socket::wait_for_events (const long event_mask, const DWORD flags)
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
WSAEVENT ev[2] = { wsock_evt, signal_arrived };
|
||||
WSAEVENT ev[2] = { wsock_evt };
|
||||
set_thread_waiting here (ev[1]);
|
||||
switch (WSAWaitForMultipleEvents (2, ev, FALSE, 50, FALSE))
|
||||
{
|
||||
case WSA_WAIT_TIMEOUT:
|
||||
@ -1778,7 +1777,7 @@ fhandler_socket::close ()
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0)
|
||||
if (cygwait (10) == WAIT_SIGNALED)
|
||||
{
|
||||
set_errno (EINTR);
|
||||
res = -1;
|
||||
|
@ -1147,26 +1147,13 @@ mtinfo::initialize ()
|
||||
inline bool
|
||||
fhandler_dev_tape::_lock (bool cancelable)
|
||||
{
|
||||
HANDLE w4[3] = { mt_mtx, signal_arrived, NULL };
|
||||
DWORD cnt = 2;
|
||||
if (cancelable && (w4[2] = pthread::get_cancel_event ()) != NULL)
|
||||
cnt = 3;
|
||||
/* O_NONBLOCK is only valid in a read or write call. Only those are
|
||||
cancelable. */
|
||||
DWORD timeout = cancelable && is_nonblocking () ? 0 : INFINITE;
|
||||
restart:
|
||||
switch (WaitForMultipleObjects (cnt, w4, FALSE, timeout))
|
||||
switch (cancelable_wait (mt_mtx, timeout, cw_sig | cw_cancel | cw_cancel_self))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
return true;
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
if (_my_tls.call_signal_handler ())
|
||||
goto restart;
|
||||
set_errno (EINTR);
|
||||
return false;
|
||||
case WAIT_OBJECT_0 + 2:
|
||||
pthread::static_cancel_self ();
|
||||
/*NOTREACHED*/
|
||||
case WAIT_TIMEOUT:
|
||||
set_errno (EAGAIN);
|
||||
return false;
|
||||
|
@ -204,7 +204,7 @@ fhandler_termios::bg_check (int sig)
|
||||
{
|
||||
/* Don't raise a SIGTT* signal if we have already been
|
||||
interrupted by another signal. */
|
||||
if (WaitForSingleObject (signal_arrived, 0) != WAIT_OBJECT_0)
|
||||
if (cygwait ((DWORD) 0) != WAIT_SIGNALED)
|
||||
{
|
||||
siginfo_t si = {0};
|
||||
si.si_signo = sig;
|
||||
|
@ -281,7 +281,7 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
|
||||
goto out;
|
||||
}
|
||||
pthread_testcancel ();
|
||||
if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0
|
||||
if (cancelable_wait (NULL, 10, cw_sig_eintr) == WAIT_SIGNALED
|
||||
&& !_my_tls.call_signal_handler ())
|
||||
{
|
||||
set_errno (EINTR);
|
||||
|
@ -96,43 +96,47 @@ fhandler_windows::read (void *buf, size_t& len)
|
||||
return;
|
||||
}
|
||||
|
||||
HANDLE w4[3] = { get_handle (), signal_arrived, NULL };
|
||||
HANDLE w4[3] = { get_handle (), };
|
||||
set_thread_waiting here (w4[1]);
|
||||
DWORD cnt = 2;
|
||||
if ((w4[cnt] = pthread::get_cancel_event ()) != NULL)
|
||||
++cnt;
|
||||
restart:
|
||||
switch (MsgWaitForMultipleObjectsEx (cnt, w4,
|
||||
is_nonblocking () ? 0 : INFINITE,
|
||||
QS_ALLINPUT | QS_ALLPOSTMESSAGE,
|
||||
MWMO_INPUTAVAILABLE))
|
||||
for (;;)
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
if (!PeekMessageW (ptr, hWnd_, 0, 0, PM_REMOVE))
|
||||
switch (MsgWaitForMultipleObjectsEx (cnt, w4,
|
||||
is_nonblocking () ? 0 : INFINITE,
|
||||
QS_ALLINPUT | QS_ALLPOSTMESSAGE,
|
||||
MWMO_INPUTAVAILABLE))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
if (!PeekMessageW (ptr, hWnd_, 0, 0, PM_REMOVE))
|
||||
{
|
||||
len = (size_t) -1;
|
||||
__seterrno ();
|
||||
}
|
||||
else if (ptr->message == WM_QUIT)
|
||||
len = 0;
|
||||
else
|
||||
len = sizeof (MSG);
|
||||
break;
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
if (_my_tls.call_signal_handler ())
|
||||
continue;
|
||||
len = (size_t) -1;
|
||||
set_errno (EINTR);
|
||||
break;
|
||||
case WAIT_OBJECT_0 + 2:
|
||||
pthread::static_cancel_self ();
|
||||
break;
|
||||
case WAIT_TIMEOUT:
|
||||
len = (size_t) -1;
|
||||
set_errno (EAGAIN);
|
||||
break;
|
||||
default:
|
||||
len = (size_t) -1;
|
||||
__seterrno ();
|
||||
break;
|
||||
}
|
||||
else if (ptr->message == WM_QUIT)
|
||||
len = 0;
|
||||
else
|
||||
len = sizeof (MSG);
|
||||
break;
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
if (_my_tls.call_signal_handler ())
|
||||
goto restart;
|
||||
len = (size_t) -1;
|
||||
set_errno (EINTR);
|
||||
break;
|
||||
case WAIT_OBJECT_0 + 2:
|
||||
pthread::static_cancel_self ();
|
||||
break;
|
||||
case WAIT_TIMEOUT:
|
||||
len = (size_t) -1;
|
||||
set_errno (EAGAIN);
|
||||
break;
|
||||
default:
|
||||
len = (size_t) -1;
|
||||
__seterrno ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1247,7 +1247,7 @@ lf_setlock (lockf_t *lock, inode_t *node, lockf_t **clean, HANDLE fhdl)
|
||||
timeout = 100L;
|
||||
|
||||
DWORD WAIT_SIGNAL_ARRIVED = WAIT_OBJECT_0 + wait_count;
|
||||
w4[wait_count++] = signal_arrived;
|
||||
set_thread_waiting here (w4[wait_count++]);
|
||||
|
||||
DWORD WAIT_THREAD_CANCELED = WAIT_TIMEOUT + 1;
|
||||
HANDLE cancel_event = pthread::get_cancel_event ();
|
||||
|
@ -202,8 +202,6 @@ _sigdelayed:
|
||||
|
||||
pushl \$_sigreturn # where to return
|
||||
pushl $tls::func(%ebx) # user-supplied signal func
|
||||
cmpl \$0,$tls::threadkill(%ebx)#pthread_kill signal?
|
||||
jnz 4f # yes. callee clears signal number
|
||||
movl \$0,$tls::sig(%ebx) # zero the signal number as a
|
||||
# flag to the signal handler thread
|
||||
# that it is ok to set up sigsave
|
||||
|
@ -14,10 +14,10 @@ my $struct = '';
|
||||
my @fields = ();
|
||||
my $def = '';
|
||||
$tls = join('', <TLS>);
|
||||
$tls =~ s/\A.*\n#pragma once\n//os;
|
||||
$tls =~ s/\n[^\n]*gentls_offsets[^\n]*\n(.+)\Z/$1/os;
|
||||
my $pre = $`;
|
||||
substr($tls, 0, length($pre)) = '';
|
||||
$pre =~ s/\n#ifndef _[^\n]+\n/\n/os;
|
||||
$pre .= "\n//*/";
|
||||
$tls =~ s%/\*\s*gentls_offsets.*?/\*\s*gentls_offsets\s*\*/%%ogs;
|
||||
foreach ($tls =~ /^.*\n/mg) {
|
||||
|
@ -9,8 +9,7 @@
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#ifndef _NTDLL_H
|
||||
#define _NTDLL_H 1
|
||||
#pragma once
|
||||
|
||||
#ifndef __MINGW64_VERSION_MAJOR
|
||||
# include <ddk/ntstatus.h>
|
||||
@ -1425,4 +1424,3 @@ extern "C"
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /*_NTDLL_H*/
|
||||
|
@ -152,9 +152,9 @@ ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts,
|
||||
? -1
|
||||
: (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000);
|
||||
if (sigmask)
|
||||
set_signal_mask (*sigmask, _my_tls.sigmask);
|
||||
set_signal_mask (_my_tls.sigmask, *sigmask);
|
||||
int ret = poll (fds, nfds, timeout);
|
||||
if (sigmask)
|
||||
set_signal_mask (oldset, _my_tls.sigmask);
|
||||
set_signal_mask (_my_tls.sigmask, oldset);
|
||||
return ret;
|
||||
}
|
||||
|
@ -119,14 +119,12 @@ ipc_mutex_init (HANDLE *pmtx, const char *name)
|
||||
static int
|
||||
ipc_mutex_lock (HANDLE mtx)
|
||||
{
|
||||
HANDLE h[2] = { mtx, signal_arrived };
|
||||
|
||||
switch (WaitForMultipleObjects (2, h, FALSE, INFINITE))
|
||||
switch (cancelable_wait (mtx, cw_infinite, cw_sig_eintr | cw_cancel | cw_cancel_self))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
case WAIT_ABANDONED_0:
|
||||
return 0;
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
case WAIT_SIGNALED:
|
||||
set_errno (EINTR);
|
||||
return 1;
|
||||
default:
|
||||
@ -174,11 +172,12 @@ ipc_cond_init (HANDLE *pevt, const char *name, char sr)
|
||||
static int
|
||||
ipc_cond_timedwait (HANDLE evt, HANDLE mtx, const struct timespec *abstime)
|
||||
{
|
||||
HANDLE w4[4] = { evt, signal_arrived, NULL, NULL };
|
||||
HANDLE w4[4] = { evt, };
|
||||
DWORD cnt = 2;
|
||||
DWORD timer_idx = 0;
|
||||
int ret = 0;
|
||||
|
||||
set_thread_waiting here (w4[1]);
|
||||
if ((w4[cnt] = pthread::get_cancel_event ()) != NULL)
|
||||
++cnt;
|
||||
if (abstime)
|
||||
|
@ -9,8 +9,7 @@ This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#ifndef _SECURITY_H
|
||||
#define _SECURITY_H
|
||||
#pragma once
|
||||
|
||||
#include <accctrl.h>
|
||||
|
||||
@ -513,5 +512,3 @@ sec_user (SECURITY_ATTRIBUTES *sa_buf, PSID sid1, PSID sid2 = NULL,
|
||||
{
|
||||
return __sec_user (sa_buf, sid1, sid2, access2, TRUE);
|
||||
}
|
||||
|
||||
#endif /*_SECURITY_H*/
|
||||
|
@ -100,20 +100,28 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||
select_printf ("select(%d, %p, %p, %p, %p)", maxfds, readfds, writefds, exceptfds, to);
|
||||
|
||||
pthread_testcancel ();
|
||||
|
||||
/* Convert to milliseconds or INFINITE if to == NULL */
|
||||
DWORD ms = to ? (to->tv_sec * 1000) + (to->tv_usec / 1000) : INFINITE;
|
||||
if (ms == 0 && to->tv_usec)
|
||||
ms = 1; /* At least 1 ms granularity */
|
||||
|
||||
if (to)
|
||||
select_printf ("to->tv_sec %d, to->tv_usec %d, ms %d", to->tv_sec, to->tv_usec, ms);
|
||||
int res;
|
||||
if (maxfds < 0)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
res = -1;
|
||||
}
|
||||
else
|
||||
select_printf ("to NULL, ms %x", ms);
|
||||
{
|
||||
/* Convert to milliseconds or INFINITE if to == NULL */
|
||||
DWORD ms = to ? (to->tv_sec * 1000) + (to->tv_usec / 1000) : INFINITE;
|
||||
if (ms == 0 && to->tv_usec)
|
||||
ms = 1; /* At least 1 ms granularity */
|
||||
|
||||
int res = select (maxfds, readfds ?: allocfd_set (maxfds),
|
||||
if (to)
|
||||
select_printf ("to->tv_sec %d, to->tv_usec %d, ms %d", to->tv_sec, to->tv_usec, ms);
|
||||
else
|
||||
select_printf ("to NULL, ms %x", ms);
|
||||
|
||||
res = select (maxfds, readfds ?: allocfd_set (maxfds),
|
||||
writefds ?: allocfd_set (maxfds),
|
||||
exceptfds ?: allocfd_set (maxfds), ms);
|
||||
}
|
||||
syscall_printf ("%R = select(%d, %p, %p, %p, %p)", res, maxfds, readfds,
|
||||
writefds, exceptfds, to);
|
||||
return res;
|
||||
@ -179,6 +187,7 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||
else
|
||||
res = sel.wait (r, w, e, ms); /* wait for an fd to become
|
||||
become active or time out */
|
||||
select_printf ("res %d", res);
|
||||
if (res >= 0)
|
||||
{
|
||||
copyfd_set (readfds, r, maxfds);
|
||||
@ -197,7 +206,10 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||
select_printf ("recalculating ms");
|
||||
LONGLONG now = gtod.msecs ();
|
||||
if (now > (start_time + ms))
|
||||
select_printf ("timed out after verification");
|
||||
{
|
||||
select_printf ("timed out after verification");
|
||||
res = select_stuff::select_error;
|
||||
}
|
||||
else
|
||||
{
|
||||
ms -= (now - start_time);
|
||||
@ -228,11 +240,11 @@ pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||
tv.tv_usec = ts->tv_nsec / 1000;
|
||||
}
|
||||
if (set)
|
||||
set_signal_mask (*set, _my_tls.sigmask);
|
||||
set_signal_mask (_my_tls.sigmask, *set);
|
||||
int ret = cygwin_select (maxfds, readfds, writefds, exceptfds,
|
||||
ts ? &tv : NULL);
|
||||
if (set)
|
||||
set_signal_mask (oldset, _my_tls.sigmask);
|
||||
set_signal_mask (_my_tls.sigmask, oldset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -320,7 +332,7 @@ select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||
select_record *s = &start;
|
||||
DWORD m = 0;
|
||||
|
||||
w4[m++] = signal_arrived; /* Always wait for the arrival of a signal. */
|
||||
set_thread_waiting here (w4[m++]);
|
||||
if ((w4[m] = pthread::get_cancel_event ()) != NULL)
|
||||
m++;
|
||||
|
||||
|
@ -120,12 +120,9 @@ clock_nanosleep (clockid_t clk_id, int flags, const struct timespec *rqtp,
|
||||
|
||||
syscall_printf ("clock_nanosleep (%ld.%09ld)", rqtp->tv_sec, rqtp->tv_nsec);
|
||||
|
||||
int rc = cancelable_wait (signal_arrived, &timeout);
|
||||
if (rc == WAIT_OBJECT_0)
|
||||
{
|
||||
_my_tls.call_signal_handler ();
|
||||
res = EINTR;
|
||||
}
|
||||
int rc = cancelable_wait (NULL, &timeout, cw_sig | cw_cancel | cw_cancel_self);
|
||||
if (rc == WAIT_SIGNALED)
|
||||
res = EINTR;
|
||||
|
||||
/* according to POSIX, rmtp is used only if !abstime */
|
||||
if (rmtp && !abstime)
|
||||
@ -226,7 +223,7 @@ handle_sigprocmask (int how, const sigset_t *set, sigset_t *oldset, sigset_t& op
|
||||
newmask = *set;
|
||||
break;
|
||||
}
|
||||
set_signal_mask (newmask, opmask);
|
||||
set_signal_mask (opmask, newmask);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -379,7 +376,7 @@ abort (void)
|
||||
sigset_t sig_mask;
|
||||
sigfillset (&sig_mask);
|
||||
sigdelset (&sig_mask, SIGABRT);
|
||||
set_signal_mask (sig_mask, _my_tls.sigmask);
|
||||
set_signal_mask (_my_tls.sigmask, sig_mask);
|
||||
|
||||
raise (SIGABRT);
|
||||
_my_tls.call_signal_handler (); /* Call any signal handler */
|
||||
@ -568,21 +565,18 @@ extern "C" int
|
||||
sigwaitinfo (const sigset_t *set, siginfo_t *info)
|
||||
{
|
||||
pthread_testcancel ();
|
||||
HANDLE h;
|
||||
h = _my_tls.event = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
|
||||
if (!h)
|
||||
{
|
||||
__seterrno ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
_my_tls.sigwait_mask = *set;
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return EFAULT;
|
||||
|
||||
set_signal_mask (_my_tls.sigwait_mask, *set);
|
||||
sig_dispatch_pending (true);
|
||||
|
||||
int res;
|
||||
switch (WaitForSingleObject (h, INFINITE))
|
||||
switch (cancelable_wait (NULL, cw_infinite, cw_sig | cw_cancel | cw_cancel_self))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
case WAIT_SIGNALED:
|
||||
if (!sigismember (set, _my_tls.infodata.si_signo))
|
||||
{
|
||||
set_errno (EINTR);
|
||||
@ -593,6 +587,7 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info)
|
||||
if (info)
|
||||
*info = _my_tls.infodata;
|
||||
res = _my_tls.infodata.si_signo;
|
||||
/* FIXME: Is this right? */
|
||||
InterlockedExchange ((LONG *) &_my_tls.sig, (LONG) 0);
|
||||
}
|
||||
break;
|
||||
@ -601,8 +596,6 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info)
|
||||
res = -1;
|
||||
}
|
||||
|
||||
_my_tls.event = NULL;
|
||||
CloseHandle (h);
|
||||
sigproc_printf ("returning signal %d", res);
|
||||
return res;
|
||||
}
|
||||
|
@ -43,9 +43,6 @@ int __sp_ln;
|
||||
|
||||
char NO_COPY myself_nowait_dummy[1] = {'0'};// Flag to sig_send that signal goes to
|
||||
// current process but no wait is required
|
||||
HANDLE NO_COPY signal_arrived; // Event signaled when a signal has
|
||||
// resulted in a user-specified
|
||||
// function call
|
||||
|
||||
#define Static static NO_COPY
|
||||
|
||||
@ -518,17 +515,6 @@ sig_dispatch_pending (bool fast)
|
||||
sig_send (myself, fast ? __SIGFLUSHFAST : __SIGFLUSH);
|
||||
}
|
||||
|
||||
void __stdcall
|
||||
create_signal_arrived ()
|
||||
{
|
||||
if (signal_arrived)
|
||||
return;
|
||||
/* local event signaled when main thread has been dispatched
|
||||
to a signal handler function. */
|
||||
signal_arrived = CreateEvent (&sec_none_nih, false, false, NULL);
|
||||
ProtectHandle (signal_arrived);
|
||||
}
|
||||
|
||||
/* Signal thread initialization. Called from dll_crt0_1.
|
||||
This routine starts the signal handling thread. */
|
||||
void __stdcall
|
||||
@ -1233,7 +1219,7 @@ stopped_or_terminated (waitq *parent_w, _pinfo *child)
|
||||
int might_match;
|
||||
waitq *w = parent_w->next;
|
||||
|
||||
sigproc_printf ("considering pid %d", child->pid);
|
||||
sigproc_printf ("considering pid %d, pgid %d, w->pid %d", child->pid, child->pgid, w->pid);
|
||||
if (w->pid == -1)
|
||||
might_match = 1;
|
||||
else if (w->pid == 0)
|
||||
|
@ -58,13 +58,11 @@ struct sigpacket
|
||||
int __stdcall process () __attribute__ ((regparm (1)));
|
||||
};
|
||||
|
||||
extern HANDLE signal_arrived;
|
||||
extern HANDLE sigCONT;
|
||||
|
||||
void __stdcall sig_dispatch_pending (bool fast = false);
|
||||
#ifdef EXITCODE_SET
|
||||
extern "C" void __stdcall set_signal_mask (sigset_t newmask, sigset_t&);
|
||||
#endif
|
||||
void __stdcall sig_dispatch_pending (bool fast = false)
|
||||
__attribute__ ((regparm (1)));
|
||||
void set_signal_mask (sigset_t&, sigset_t) __attribute__ ((regparm (2)));
|
||||
int __stdcall handle_sigprocmask (int sig, const sigset_t *set,
|
||||
sigset_t *oldset, sigset_t& opmask)
|
||||
__attribute__ ((regparm (3)));
|
||||
@ -86,7 +84,6 @@ int __stdcall sig_send (_pinfo *, siginfo_t&, class _cygtls *tls = NULL) __attri
|
||||
int __stdcall sig_send (_pinfo *, int) __attribute__ ((regparm (2)));
|
||||
void __stdcall signal_fixup_after_exec ();
|
||||
void __stdcall sigalloc ();
|
||||
void __stdcall create_signal_arrived ();
|
||||
|
||||
int kill_pgrp (pid_t, siginfo_t&);
|
||||
int killsys (pid_t, int);
|
||||
|
@ -2295,7 +2295,7 @@ retry:
|
||||
{
|
||||
debug_printf ("status %p", status);
|
||||
if (status == STATUS_SHARING_VIOLATION
|
||||
&& WaitForSingleObject (signal_arrived, 10L) != WAIT_OBJECT_0)
|
||||
&& cygwait (10L) != WAIT_SIGNALED)
|
||||
{
|
||||
/* Typical BLODA problem. Some virus scanners check newly generated
|
||||
files and while doing that disallow DELETE access. That's really
|
||||
|
@ -1744,7 +1744,7 @@ pthread_mutex::lock ()
|
||||
|| !pthread::equal (owner, self))
|
||||
{
|
||||
/* FIXME: no cancel? */
|
||||
cancelable_wait (win32_obj_id, LARGE_NULL, cw_sig);
|
||||
cancelable_wait (win32_obj_id, cw_infinite, cw_sig);
|
||||
set_owner (self);
|
||||
}
|
||||
else
|
||||
@ -2364,7 +2364,7 @@ pthread::join (pthread_t *thread, void **return_val)
|
||||
(*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
|
||||
(*thread)->mutex.unlock ();
|
||||
|
||||
switch (cancelable_wait ((*thread)->win32_obj_id, LARGE_NULL, cw_sig | cw_cancel))
|
||||
switch (cancelable_wait ((*thread)->win32_obj_id, cw_infinite, cw_sig | cw_cancel))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
if (return_val)
|
||||
@ -3015,10 +3015,7 @@ pthread_kill (pthread_t thread, int sig)
|
||||
if (!thread->valid)
|
||||
rval = ESRCH;
|
||||
else if (sig)
|
||||
{
|
||||
thread->cygtls->set_threadkill ();
|
||||
rval = sig_send (NULL, si, thread->cygtls);
|
||||
}
|
||||
rval = sig_send (NULL, si, thread->cygtls);
|
||||
else
|
||||
switch (WaitForSingleObject (thread->win32_obj_id, 0))
|
||||
{
|
||||
@ -3501,7 +3498,7 @@ semaphore::_timedwait (const struct timespec *abstime)
|
||||
int
|
||||
semaphore::_wait ()
|
||||
{
|
||||
switch (cancelable_wait (win32_obj_id, LARGE_NULL, cw_cancel | cw_cancel_self | cw_sig_eintr))
|
||||
switch (cancelable_wait (win32_obj_id, cw_infinite, cw_cancel | cw_cancel_self | cw_sig_eintr))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
currentvalue--;
|
||||
|
@ -60,7 +60,7 @@ public:
|
||||
void lock ()
|
||||
{
|
||||
if (InterlockedIncrement ((long *) &lock_counter) != 1)
|
||||
cancelable_wait (win32_obj_id, LARGE_NULL, cw_sig);
|
||||
cancelable_wait (win32_obj_id, cw_infinite, cw_sig);
|
||||
}
|
||||
|
||||
void unlock ()
|
||||
|
@ -1,42 +1,42 @@
|
||||
//;# autogenerated: Do not edit.
|
||||
|
||||
//; $tls::sizeof__cygtls = 4048;
|
||||
//; $tls::func = -12700;
|
||||
//; $tls::pfunc = 0;
|
||||
//; $tls::saved_errno = -12696;
|
||||
//; $tls::psaved_errno = 4;
|
||||
//; $tls::sa_flags = -12692;
|
||||
//; $tls::psa_flags = 8;
|
||||
//; $tls::oldmask = -12688;
|
||||
//; $tls::poldmask = 12;
|
||||
//; $tls::deltamask = -12684;
|
||||
//; $tls::pdeltamask = 16;
|
||||
//; $tls::event = -12680;
|
||||
//; $tls::pevent = 20;
|
||||
//; $tls::errno_addr = -12676;
|
||||
//; $tls::perrno_addr = 24;
|
||||
//; $tls::sigmask = -12672;
|
||||
//; $tls::psigmask = 28;
|
||||
//; $tls::sigwait_mask = -12668;
|
||||
//; $tls::psigwait_mask = 32;
|
||||
//; $tls::sigwait_info = -12664;
|
||||
//; $tls::psigwait_info = 36;
|
||||
//; $tls::thread_context = -12660;
|
||||
//; $tls::pthread_context = 40;
|
||||
//; $tls::thread_id = -12448;
|
||||
//; $tls::pthread_id = 252;
|
||||
//; $tls::threadkill = -12444;
|
||||
//; $tls::pthreadkill = 256;
|
||||
//; $tls::infodata = -12440;
|
||||
//; $tls::pinfodata = 260;
|
||||
//; $tls::tid = -12292;
|
||||
//; $tls::ptid = 408;
|
||||
//; $tls::local_clib = -12288;
|
||||
//; $tls::plocal_clib = 412;
|
||||
//; $tls::__dontuse = -12288;
|
||||
//; $tls::p__dontuse = 412;
|
||||
//; $tls::locals = -11200;
|
||||
//; $tls::plocals = 1500;
|
||||
//; $tls::locals = -12700;
|
||||
//; $tls::plocals = 0;
|
||||
//; $tls::local_clib = -11236;
|
||||
//; $tls::plocal_clib = 1464;
|
||||
//; $tls::__dontuse = -11236;
|
||||
//; $tls::p__dontuse = 1464;
|
||||
//; $tls::func = -10148;
|
||||
//; $tls::pfunc = 2552;
|
||||
//; $tls::saved_errno = -10144;
|
||||
//; $tls::psaved_errno = 2556;
|
||||
//; $tls::sa_flags = -10140;
|
||||
//; $tls::psa_flags = 2560;
|
||||
//; $tls::oldmask = -10136;
|
||||
//; $tls::poldmask = 2564;
|
||||
//; $tls::deltamask = -10132;
|
||||
//; $tls::pdeltamask = 2568;
|
||||
//; $tls::errno_addr = -10128;
|
||||
//; $tls::perrno_addr = 2572;
|
||||
//; $tls::sigmask = -10124;
|
||||
//; $tls::psigmask = 2576;
|
||||
//; $tls::sigwait_mask = -10120;
|
||||
//; $tls::psigwait_mask = 2580;
|
||||
//; $tls::sigwait_info = -10116;
|
||||
//; $tls::psigwait_info = 2584;
|
||||
//; $tls::signal_arrived = -10112;
|
||||
//; $tls::psignal_arrived = 2588;
|
||||
//; $tls::signal_waiting = -10108;
|
||||
//; $tls::psignal_waiting = 2592;
|
||||
//; $tls::thread_context = -10104;
|
||||
//; $tls::pthread_context = 2596;
|
||||
//; $tls::thread_id = -9892;
|
||||
//; $tls::pthread_id = 2808;
|
||||
//; $tls::infodata = -9888;
|
||||
//; $tls::pinfodata = 2812;
|
||||
//; $tls::tid = -9740;
|
||||
//; $tls::ptid = 2960;
|
||||
//; $tls::_ctinfo = -9736;
|
||||
//; $tls::p_ctinfo = 2964;
|
||||
//; $tls::andreas = -9732;
|
||||
@ -59,42 +59,42 @@
|
||||
//; $tls::pinitialized = 4044;
|
||||
//; __DATA__
|
||||
|
||||
#define tls_func (-12700)
|
||||
#define tls_pfunc (0)
|
||||
#define tls_saved_errno (-12696)
|
||||
#define tls_psaved_errno (4)
|
||||
#define tls_sa_flags (-12692)
|
||||
#define tls_psa_flags (8)
|
||||
#define tls_oldmask (-12688)
|
||||
#define tls_poldmask (12)
|
||||
#define tls_deltamask (-12684)
|
||||
#define tls_pdeltamask (16)
|
||||
#define tls_event (-12680)
|
||||
#define tls_pevent (20)
|
||||
#define tls_errno_addr (-12676)
|
||||
#define tls_perrno_addr (24)
|
||||
#define tls_sigmask (-12672)
|
||||
#define tls_psigmask (28)
|
||||
#define tls_sigwait_mask (-12668)
|
||||
#define tls_psigwait_mask (32)
|
||||
#define tls_sigwait_info (-12664)
|
||||
#define tls_psigwait_info (36)
|
||||
#define tls_thread_context (-12660)
|
||||
#define tls_pthread_context (40)
|
||||
#define tls_thread_id (-12448)
|
||||
#define tls_pthread_id (252)
|
||||
#define tls_threadkill (-12444)
|
||||
#define tls_pthreadkill (256)
|
||||
#define tls_infodata (-12440)
|
||||
#define tls_pinfodata (260)
|
||||
#define tls_tid (-12292)
|
||||
#define tls_ptid (408)
|
||||
#define tls_local_clib (-12288)
|
||||
#define tls_plocal_clib (412)
|
||||
#define tls___dontuse (-12288)
|
||||
#define tls_p__dontuse (412)
|
||||
#define tls_locals (-11200)
|
||||
#define tls_plocals (1500)
|
||||
#define tls_locals (-12700)
|
||||
#define tls_plocals (0)
|
||||
#define tls_local_clib (-11236)
|
||||
#define tls_plocal_clib (1464)
|
||||
#define tls___dontuse (-11236)
|
||||
#define tls_p__dontuse (1464)
|
||||
#define tls_func (-10148)
|
||||
#define tls_pfunc (2552)
|
||||
#define tls_saved_errno (-10144)
|
||||
#define tls_psaved_errno (2556)
|
||||
#define tls_sa_flags (-10140)
|
||||
#define tls_psa_flags (2560)
|
||||
#define tls_oldmask (-10136)
|
||||
#define tls_poldmask (2564)
|
||||
#define tls_deltamask (-10132)
|
||||
#define tls_pdeltamask (2568)
|
||||
#define tls_errno_addr (-10128)
|
||||
#define tls_perrno_addr (2572)
|
||||
#define tls_sigmask (-10124)
|
||||
#define tls_psigmask (2576)
|
||||
#define tls_sigwait_mask (-10120)
|
||||
#define tls_psigwait_mask (2580)
|
||||
#define tls_sigwait_info (-10116)
|
||||
#define tls_psigwait_info (2584)
|
||||
#define tls_signal_arrived (-10112)
|
||||
#define tls_psignal_arrived (2588)
|
||||
#define tls_signal_waiting (-10108)
|
||||
#define tls_psignal_waiting (2592)
|
||||
#define tls_thread_context (-10104)
|
||||
#define tls_pthread_context (2596)
|
||||
#define tls_thread_id (-9892)
|
||||
#define tls_pthread_id (2808)
|
||||
#define tls_infodata (-9888)
|
||||
#define tls_pinfodata (2812)
|
||||
#define tls_tid (-9740)
|
||||
#define tls_ptid (2960)
|
||||
#define tls__ctinfo (-9736)
|
||||
#define tls_p_ctinfo (2964)
|
||||
#define tls_andreas (-9732)
|
||||
|
@ -80,7 +80,7 @@ wait4 (int intpid, int *status, int options, struct rusage *r)
|
||||
if ((waitfor = w->ev) == NULL)
|
||||
goto nochildren;
|
||||
|
||||
res = cancelable_wait (waitfor, LARGE_NULL, cw_cancel | cw_cancel_self);
|
||||
res = cancelable_wait (waitfor, cw_infinite, cw_cancel | cw_cancel_self);
|
||||
|
||||
sigproc_printf ("%d = cancelable_wait (...)", res);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user