📄 signal.h
字号:
/* Implementing POSIX.1 signals under the Hurd.Copyright (C) 1993, 1994 Free Software Foundation, Inc.This file is part of the GNU C Library.The GNU C Library is free software; you can redistribute it and/ormodify it under the terms of the GNU Library General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, or (at your option) any later version.The GNU C Library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with the GNU C Library; see the file COPYING.LIB. Ifnot, write to the Free Software Foundation, Inc., 675 Mass Ave,Cambridge, MA 02139, USA. */#ifndef _HURD_SIGNAL_H#define _HURD_SIGNAL_H 1#include <features.h>/* Make sure <signal.h> is going to define NSIG. */#ifndef __USE_GNU#error "Must have `_GNU_SOURCE' feature test macro to use this file"#endif#define __need_NULL#include <stddef.h>#include <mach/mach_types.h>#include <mach/port.h>#include <mach/message.h>#include <hurd/hurd_types.h>#include <signal.h>#include <errno.h>#include <cthreads.h> /* For `struct mutex'. */#include <lock-intern.h>#include <hurd/threadvar.h> /* We cache sigstate in a threadvar. *//* Per-thread signal state. */struct hurd_sigstate { /* This mutex locks most of the rest of this structure. It also acts as a critical section lock for the thread (see below). */ struct mutex lock; int critical_section; /* XXX This should perhaps instead be something that identifies cthreads multiplexed on a single kernel thread. */ thread_t thread; struct hurd_sigstate *next; /* Linked-list of thread sigstates. */ sigset_t blocked; sigset_t pending; struct sigaction actions[NSIG]; struct sigaltstack sigaltstack; struct { /* For each signal that may be pending, the sigcode and error code to deliver it with. */ int code, error; } pending_data[NSIG]; /* If `suspended' is set when this thread gets a signal, the signal thread sends an empty message to it. */ mach_port_t suspended; /* Not locked. Used only by this thread, or by the signal thread with this thread suspended. */ volatile mach_port_t intr_port; /* Port interruptible RPC was sent on. */ /* If this is not null, the thread is in sigreturn awaiting delivery of pending signals. This context (the machine-dependent portions only) will be passed to sigreturn after running the handler for a pending signal, instead of examining the thread state. */ struct sigcontext *context; };/* Linked list of states of all threads whose state has been asked for. */extern struct hurd_sigstate *_hurd_sigstates;extern struct mutex _hurd_siglock; /* Locks _hurd_sigstates. *//* Get the sigstate of a given thread, taking its lock. */extern struct hurd_sigstate *_hurd_thread_sigstate (thread_t);/* Get the sigstate of the current thread, taking its lock. This uses a per-thread variable to optimize the lookup. */_EXTERN_INLINE struct hurd_sigstate *_hurd_self_sigstate_unlocked (void){ struct hurd_sigstate **location = (void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE); if (! *location) { *location = _hurd_thread_sigstate (__mach_thread_self ()); __mutex_unlock (&(*location)->lock); } return *location;}_EXTERN_INLINE struct hurd_sigstate *_hurd_self_sigstate (void){ struct hurd_sigstate **location = (void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE); if (*location) __mutex_lock (&(*location)->lock); else *location = _hurd_thread_sigstate (__mach_thread_self ()); return *location;}/* Critical sections. A critical section is a section of code which cannot safely be interrupted to run a signal handler; for example, code that holds any lock cannot be interrupted lest the signal handler try to take the same lock and deadlock result. Before entering a critical section, a thread must make sure it holds its own sigstate lock. The thread sets the `critical_section' flag (which is not itself locked) to indicate the lock is already held by the same thread. Subroutines which contain critical sections of their own then test this flag; if it is set, they don't try to acquire the sigstate lock again, to avoid deadlock. */_EXTERN_INLINE void *_hurd_critical_section_lock (void){ struct hurd_sigstate **location = (void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE); struct hurd_sigstate *ss = *location; if (ss == NULL) /* The thread variable is unset; this must be the first time we've asked for it. In this case, the critical section flag cannot possible already be set. Look up our sigstate structure the slow way; this locks the sigstate lock. */ ss = *location = _hurd_thread_sigstate (__mach_thread_self ()); else { if (ss->critical_section) /* Some caller higher up has already acquired the critical section lock. We need do nothing. The null pointer we return will make _hurd_critical_section_unlock (below) be a no-op. */ return NULL; /* Acquire the sigstate lock to prevent any signal from arriving. */ __mutex_lock (&ss->lock); } /* Set the critical section flag so no later call will try to take the sigstate lock while we already have it locked. */ ss->critical_section = 1; /* Return our sigstate pointer; this will be passed to _hurd_critical_section_unlock to clear the critical section flag. */ return ss;}_EXTERN_INLINE void_hurd_critical_section_unlock (void *our_lock){ if (our_lock == NULL) /* The critical section lock was held when we began. Do nothing. */ return; else { /* It was us who acquired the critical section lock. Clear the critical section flag and unlock the sigstate lock. */ struct hurd_sigstate *ss = our_lock; ss->critical_section = 0; __mutex_unlock (&ss->lock); }}/* Convenient macros for simple uses of critical sections. These two must be used as a pair at the same C scoping level. */#define HURD_CRITICAL_BEGIN \ { void *__hurd_critical__ = _hurd_critical_section_lock ()#define HURD_CRITICAL_END \ _hurd_critical_section_unlock (__hurd_critical__); } while (0)/* Thread listening on our message port; also called the "signal thread". */extern thread_t _hurd_msgport_thread;/* Our message port. We hold the receive right and _hurd_msgport_thread listens for messages on it. We also hold a send right, for convenience. */extern mach_port_t _hurd_msgport;/* Thread to receive process-global signals. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -