4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-01-15 19:09:58 +08:00
Christopher Faylor 962f9a2ccc * 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 22:58:20 +00:00

172 lines
4.0 KiB
C++

/* sigproc.h
Copyright 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
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
#include <signal.h>
#include "sync.h"
#ifdef NSIG
enum
{
__SIGFLUSH = -(NSIG + 1),
__SIGSTRACE = -(NSIG + 2),
__SIGCOMMUNE = -(NSIG + 3),
__SIGPENDING = -(NSIG + 4),
__SIGDELETE = -(NSIG + 5),
__SIGFLUSHFAST = -(NSIG + 6),
__SIGHOLD = -(NSIG + 7),
__SIGNOHOLD = -(NSIG + 8),
__SIGEXIT = -(NSIG + 9),
__SIGSETPGRP = -(NSIG + 10)
};
#endif
#define SIG_BAD_MASK (1 << (SIGKILL - 1))
enum procstuff
{
PROC_ADDCHILD = 1, // add a new subprocess to list
PROC_REATTACH_CHILD = 2, // reattach after exec
PROC_EXEC_CLEANUP = 3, // cleanup waiting children after exec
PROC_DETACHED_CHILD = 4, // set up a detached child
PROC_CLEARWAIT = 5, // clear all waits - signal arrived
PROC_WAIT = 6, // setup for wait() for subproc
PROC_EXECING = 7, // used to get a lock when execing
PROC_NOTHING = 8 // nothing, really
};
struct sigpacket
{
siginfo_t si;
pid_t pid;
class _cygtls *tls;
sigset_t *mask;
union
{
HANDLE wakeup;
HANDLE thread_handle;
struct sigpacket *next;
};
int __stdcall process () __attribute__ ((regparm (1)));
};
extern HANDLE sigCONT;
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)));
void __stdcall sig_clear (int) __attribute__ ((regparm (1)));
void __stdcall sig_set_pending (int) __attribute__ ((regparm (1)));
int __stdcall handle_sigsuspend (sigset_t);
int __stdcall proc_subproc (DWORD, DWORD) __attribute__ ((regparm (2)));
class _pinfo;
void __stdcall proc_terminate ();
void __stdcall sigproc_init ();
#ifdef __INSIDE_CYGWIN__
void __stdcall sigproc_terminate (enum exit_states);
#endif
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 *, int) __attribute__ ((regparm (2)));
void __stdcall signal_fixup_after_exec ();
void __stdcall sigalloc ();
int kill_pgrp (pid_t, siginfo_t&);
int killsys (pid_t, int);
extern char myself_nowait_dummy[];
extern struct sigaction *global_sigs;
class lock_signals
{
bool worked;
public:
lock_signals ()
{
worked = sig_send (NULL, __SIGHOLD) == 0;
}
operator int () const
{
return worked;
}
void dont_bother ()
{
worked = false;
}
~lock_signals ()
{
if (worked)
sig_send (NULL, __SIGNOHOLD);
}
};
class lock_pthread
{
bool bother;
public:
lock_pthread (): bother (1)
{
pthread::atforkprepare ();
}
void dont_bother ()
{
bother = false;
}
~lock_pthread ()
{
if (bother)
pthread::atforkparent ();
}
};
class hold_everything
{
bool ischild;
/* Note the order of the locks below. It is important,
to avoid races, that the lock order be preserved.
pthread is first because it serves as a master lock
against other forks being attempted while this one is active.
signals is next to stop signal processing for the duration
of the fork.
process is last. If it is put before signals, then a deadlock
could be introduced if the process attempts to exit due to a signal. */
lock_pthread pthread;
lock_signals signals;
lock_process process;
public:
hold_everything (bool x = false): ischild (x) {}
operator int () const {return signals;}
~hold_everything()
{
if (ischild)
{
pthread.dont_bother ();
process.dont_bother ();
signals.dont_bother ();
}
}
};
#define myself_nowait ((_pinfo *) myself_nowait_dummy)