New file.
[kopensolaris-gnu/glibc.git] / hurd / hurd / signal.h
index 76007d5..1973bcd 100644 (file)
@@ -1,5 +1,5 @@
 /* Implementing POSIX.1 signals under the Hurd.
-Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+Copyright (C) 1993, 1994, 1995, 1996 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/or
@@ -40,6 +40,7 @@ Cambridge, MA 02139, USA.  */
 #include <cthreads.h>          /* For `struct mutex'.  */
 #include <spin-lock.h>
 #include <hurd/threadvar.h>    /* We cache sigstate in a threadvar.  */
+struct hurd_signal_preempter;  /* <hurd/sigpreempt.h> */
 
 
 /* Per-thread signal state.  */
@@ -57,6 +58,13 @@ struct hurd_sigstate
     sigset_t pending;          /* Pending signals, possibly blocked.  */
     struct sigaction actions[NSIG];
     struct sigaltstack sigaltstack;
+
+    /* Chain of thread-local signal preempters; see <hurd/sigpreempt.h>.
+       Each element of this chain is in local stack storage, and the chain
+       parallels the stack: the head of this chain is in the innermost
+       stack frame, and each next element in an outermore frame.  */
+    struct hurd_signal_preempter *preempters;
+
     struct
       {
        /* For each signal that may be pending, the
@@ -79,6 +87,15 @@ struct hurd_sigstate
        will be passed to sigreturn after running the handler for a pending
        signal, instead of examining the thread state.  */
     struct sigcontext *context;
+
+    /* This is the head of the thread's list of active resources; see
+       <hurd/userlink.h> for details.  This member is only used by the
+       thread itself, and always inside a critical section.  */
+    struct hurd_userlink *active_resources;
+
+    /* These are locked normally.  */
+    int cancel;                        /* Flag set by hurd_thread_cancel.  */
+    void (*cancel_hook) (void);        /* Called on cancellation.  */
   };
 
 /* Linked list of states of all threads whose state has been asked for.  */
@@ -93,6 +110,13 @@ extern struct hurd_sigstate *_hurd_thread_sigstate (thread_t);
 
 /* Get the sigstate of the current thread.
    This uses a per-thread variable to optimize the lookup.  */
+
+extern struct hurd_sigstate *_hurd_self_sigstate (void)
+     /* This declaration tells the compiler that the value is constant.
+       We assume this won't be called twice from the same stack frame
+       by different threads.  */
+     __attribute__ ((__const__));
+
 _EXTERN_INLINE struct hurd_sigstate *
 _hurd_self_sigstate (void)
 {
@@ -241,20 +265,14 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
 
 extern void _hurd_msgport_receive (void);
 
-/* STATE describes a thread that had intr_port set (meaning it was inside
-   HURD_EINTR_RPC), after it has been thread_abort'd.  It it looks to have
-   just completed a mach_msg_trap system call that returned
-   MACH_RCV_INTERRUPTED, return nonzero and set *PORT to the receive right
-   being waited on.  */
-
-extern int _hurdsig_rcv_interrupted_p (struct machine_thread_all_state *state,
-                                      mach_port_t *port);
-
 /* Set up STATE with a thread state that, when resumed, is
    like `longjmp (_hurd_sigthread_fault_env, 1)'.  */
 
 extern void _hurd_initialize_fault_recovery_state (void *state);
 
+/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'.  */
+
+extern void _hurd_longjmp_thread_state (void *state, jmp_buf env, int value);
 
 /* Function run for SIGINFO when its action is SIG_DFL and the current
    process is the session leader.  */
@@ -262,50 +280,10 @@ extern void _hurd_initialize_fault_recovery_state (void *state);
 extern void _hurd_siginfo_handler (int);
 
 
-/* Perform interruptible RPC CALL on PORT.
-   The call should use 
-   The args in CALL should be constant or local variable refs.
-   They may be evaluated many times, and must not change.
-   PORT must not be deallocated before this RPC is finished.  */
-#define        HURD_EINTR_RPC(port, call)                                            \
-  ({                                                                         \
-    __label__ __do_call;       /* Give this label block scope.  */           \
-    error_t __err;                                                           \
-    struct hurd_sigstate *__ss = _hurd_self_sigstate ();                     \
-    __do_call:                                                               \
-    /* Tell the signal thread that we are doing an interruptible RPC on              \
-       this port.  If we get a signal and should return EINTR, the signal     \
-       thread will set this variable to MACH_PORT_NULL.  The RPC might       \
-       return EINTR when some other thread gets a signal, in which case we    \
-       want to restart our call.  */                                         \
-    __ss->intr_port = (port);                                                \
-    /* A signal may arrive here, after intr_port is set, but before the              \
-       mach_msg system call.  The signal handler might do an interruptible    \
-       RPC, and clobber intr_port; then it would not be set properly when     \
-       we actually did send the RPC, and a later signal wouldn't interrupt    \
-       that RPC.  So, _hurd_setup_sighandler saves intr_port in the          \
-       sigcontext, and sigreturn restores it.  */                            \
-    switch (__err = (call))                                                  \
-      {                                                                              \
-      case EINTR:              /* RPC went out and was interrupted.  */      \
-      case MACH_SEND_INTERRUPTED: /* RPC didn't get out.  */                 \
-       if (__ss->intr_port != MACH_PORT_NULL)                                \
-         /* If this signal was for us and it should interrupt calls, the     \
-             signal thread will have cleared SS->intr_port.  Since it's not   \
-             cleared, the signal was for another thread, or SA_RESTART is     \
-             set.  Restart the interrupted call.  */                         \
-         goto __do_call;                                                     \
-       /* FALLTHROUGH */                                                     \
-      case MACH_RCV_PORT_DIED:                                               \
-       /* Server didn't respond to interrupt_operation,                      \
-          so the signal thread destroyed the reply port.  */                 \
-       __err = EINTR;                                                        \
-       break;                                                                \
-      default:                 /* Quiet -Wswitch-enum.  */                   \
-      }                                                                              \
-    __ss->intr_port = MACH_PORT_NULL;                                        \
-    __err;                                                                   \
-  })                                                                         \
+/* Milliseconds to wait for an interruptible RPC to return after
+   `interrupt_operation'.  */
+
+extern mach_msg_timeout_t _hurd_interrupted_rpc_timeout;
 
 
 /* Mask of signals that cannot be caught, blocked, or ignored.  */
@@ -360,32 +338,6 @@ extern void _hurd_siginfo_handler (int);
               __err == MIG_SERVER_DIED);                                     \
     __err;                                                                   \
 })
-\f
-/* Some other parts of the library need to preempt signals, to detect
-   errors that should not result in a POSIX signal.  For example, when
-   some mapped region of memory is used, an extraneous SIGSEGV might be
-   generated when the mapping server returns an error for a page fault.  */
-
-struct hurd_signal_preempt
-  {
-    /* Function to examine a thread receiving a given signal.  The handler
-       is called even for blocked signals.  This function is run in the
-       signal thread, with THREAD's sigstate locked; it should be as simple
-       and robust as possible.  THREAD is the thread which is about to
-       receive the signal.  SIGNO and SIGCODE would be passed to the normal
-       handler.
-
-       If the return value is SIG_DFL, normal signal processing continues.
-       If it is SIG_IGN, the signal is ignored.
-       Any other value is used in place of the normal handler.  */
-    sighandler_t (*handler) (thread_t thread,
-                            int signo, long int sigcode, int sigerror);
-    long int first, last;      /* Range of sigcodes this handler wants.  */
-    struct hurd_signal_preempt *next; /* Next handler on the chain. */
-  };
-
-extern struct hurd_signal_preempt *_hurd_signal_preempt[NSIG];
-extern struct mutex _hurd_signal_preempt_lock;
 
 
 #endif /* hurd/signal.h */