diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2011-10-30 20:08:16 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2011-10-30 20:08:16 +0100 |
commit | 62e8551e80d71082c6e2ae74cca0b1a157beedce (patch) | |
tree | 6a8003e9c758e5548dea718b0a29b0a7134fb8a4 | |
parent | 7e4f7c4a573b02011cfc6582fc2c306875b41af7 (diff) |
Enable global signal support
* debian/patches/libpthread_globsigdisp.patch,posix-sigcodes.patch: New
patches from Jeremie Koenig to enable global signal support.
* debian/patches/libpthread_sigmask.patch: Update to global signal support.
-rw-r--r-- | debian/changelog | 3 | ||||
-rw-r--r-- | debian/patches/libpthread_globsigdisp.patch | 59 | ||||
-rw-r--r-- | debian/patches/libpthread_sigmask.patch | 33 | ||||
-rw-r--r-- | debian/patches/posix-sigcodes.patch | 270 | ||||
-rw-r--r-- | debian/patches/series | 2 |
5 files changed, 350 insertions, 17 deletions
diff --git a/debian/changelog b/debian/changelog index f7956578..8b177dd2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -15,6 +15,9 @@ hurd (20110821-1) UNRELEASED; urgency=low * debian/control, debian/local/setup-translators: Use native random server instead of random-egd. * debian/local/cdrom.h: Add header for basic CD-ROM ioctl support. + * debian/patches/libpthread_globsigdisp.patch,posix-sigcodes.patch: New + patches from Jeremie Koenig to enable global signal support. + * debian/patches/libpthread_sigmask.patch: Update to global signal support. -- Samuel Thibault <sthibault@debian.org> Thu, 18 Aug 2011 01:15:04 +0000 diff --git a/debian/patches/libpthread_globsigdisp.patch b/debian/patches/libpthread_globsigdisp.patch new file mode 100644 index 00000000..06c3486c --- /dev/null +++ b/debian/patches/libpthread_globsigdisp.patch @@ -0,0 +1,59 @@ +commit 60d1b9b9198bc8c618596cb0e48687bd41e8adb7 +Author: Jeremie Koenig <jk@jk.fr.eu.org> +Date: Fri Jun 10 05:46:39 2011 +0000 + + Mark new threads as global signal receivers + + * sysdeps/mach/hurd/pt-sigstate-init.c (__pthread_sigstate_init): + Call _hurd_sigstate_set_global_rcv for newly created threads. + * sysdeps/mach/pt-thread-halt.c (__pthread_thread_halt): + Call _hurd_sigstate_delete on terminated threads. + +diff --git a/libpthread/sysdeps/mach/hurd/pt-sigstate-init.c b/libpthread/sysdeps/mach/hurd/pt-sigstate-init.c +index da5a945..f8398f4 100644 +--- a/libpthread/sysdeps/mach/hurd/pt-sigstate-init.c ++++ b/libpthread/sysdeps/mach/hurd/pt-sigstate-init.c +@@ -19,6 +19,7 @@ + + #include <pthread.h> + #include <hurd/threadvar.h> ++#include <hurd/signal.h> + + #include <pt-internal.h> + +@@ -30,8 +31,21 @@ __pthread_sigstate_init (struct __pthread *thread) + thread->stackaddr); + + /* The real initialization happens internally in glibc the first +- time that _hurd_thead_sigstate is called. */ ++ time that _hurd_self_sigstate is called. */ + *location = 0; + ++ /* Mark the thread as a global signal receiver so as to conform with ++ the pthread semantics. However, we must be careful. The first ++ pthread created is the main thread, during libpthread initialization. ++ We must not mark it, otherwise the sigprocmask call in ++ __pthread_create would try to access _hurd_global_sigstate, ++ which is not initialized yet. When glibc runs _hurdsig_init later ++ on, the message thread is created, which must not be marked either. */ ++ if (__pthread_num_threads > 2) ++ { ++ struct hurd_sigstate *ss = _hurd_thread_sigstate (thread->kernel_thread); ++ _hurd_sigstate_set_global_rcv (ss); ++ } ++ + return 0; + } +diff --git a/libpthread/sysdeps/mach/pt-thread-halt.c b/libpthread/sysdeps/mach/pt-thread-halt.c +index a9c3858..808043d 100644 +--- a/libpthread/sysdeps/mach/pt-thread-halt.c ++++ b/libpthread/sysdeps/mach/pt-thread-halt.c +@@ -34,6 +34,8 @@ __pthread_thread_halt (struct __pthread *thread) + { + if (thread->have_kernel_resources) + { ++ _hurd_sigstate_delete (thread->kernel_thread); ++ + if (thread == _pthread_self ()) + { + while (1) diff --git a/debian/patches/libpthread_sigmask.patch b/debian/patches/libpthread_sigmask.patch index 71aaf2ad..7315a80d 100644 --- a/debian/patches/libpthread_sigmask.patch +++ b/debian/patches/libpthread_sigmask.patch @@ -1,15 +1,13 @@ * libpthread/sysdeps/mach/hurd/pt-sigstate.c (__pthread_sigstate): Wake up the message thread if any pending signals have been unblocked (code grabbed from glibc). - -Will be replaced by proper global signal support from Jeremie --- libpthread/sysdeps/mach/hurd/pt-sigstate.c | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-) -diff --git a/libpthread/sysdeps/mach/hurd/pt-sigstate.c b/libpthread/sysdeps/mach/hurd/pt-sigstate.c -index 68c79c5..51263ac 100644 ---- a/libpthread/sysdeps/mach/hurd/pt-sigstate.c -+++ b/libpthread/sysdeps/mach/hurd/pt-sigstate.c +Index: hurd/libpthread/sysdeps/mach/hurd/pt-sigstate.c +=================================================================== +--- hurd.orig/libpthread/sysdeps/mach/hurd/pt-sigstate.c 2011-05-29 15:23:30.000000000 +0000 ++++ hurd/libpthread/sysdeps/mach/hurd/pt-sigstate.c 2011-06-10 04:53:53.000000000 +0000 @@ -21,6 +21,7 @@ #include <assert.h> #include <signal.h> @@ -18,7 +16,7 @@ index 68c79c5..51263ac 100644 #include <pt-internal.h> -@@ -31,6 +32,7 @@ __pthread_sigstate (struct __pthread *thread, int how, +@@ -31,11 +32,12 @@ { error_t err = 0; struct hurd_sigstate *ss; @@ -26,23 +24,24 @@ index 68c79c5..51263ac 100644 ss = _hurd_thread_sigstate (thread->kernel_thread); assert (ss); -@@ -63,7 +65,14 @@ __pthread_sigstate (struct __pthread *thread, int how, + +- __pthread_spin_lock (&ss->lock); ++ _hurd_sigstate_lock (ss); + + if (oset) + *oset = ss->blocked; +@@ -63,7 +65,13 @@ if (! err && clear_pending) __sigemptyset (&ss->pending); -+ pending = ss->pending & ~ss->blocked; +- __pthread_spin_unlock (&ss->lock); ++ pending = _hurd_sigstate_pending (ss) & ~ss->blocked; ++ _hurd_sigstate_unlock (ss); + - __pthread_spin_unlock (&ss->lock); - + if (! err && pending) + /* Send a message to the signal thread so it + will wake up and check for pending signals. */ + __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ()); -+ + return err; } --- -1.7.1 - - - diff --git a/debian/patches/posix-sigcodes.patch b/debian/patches/posix-sigcodes.patch new file mode 100644 index 00000000..34e089f2 --- /dev/null +++ b/debian/patches/posix-sigcodes.patch @@ -0,0 +1,270 @@ +commit 2a54ebafd46a26d537ac38d46dc82568f751cc42 +Author: Jeremie Koenig <jk@jk.fr.eu.org> +Date: Wed Jun 8 03:00:37 2011 +0000 + + proc: send signals with POSIX sigcodes + + * proc/stubs.c (send_signal): Add a sigcode argument. + * proc/proc.h (send_signal): Declare the sigcode argument. + * proc/pgrp.c (leave_pgrp): Specify a null sigcode. + * proc/wait.c (alert_parent): Use CLD_EXITED for SIGCHLD on exit. + (S_proc_mark_stop): Use CLD_STOPPED for SIGCHLD on stop. + +diff --git a/proc/pgrp.c b/proc/pgrp.c +index 2d6ca93..72c09ba 100644 +--- a/proc/pgrp.c ++++ b/proc/pgrp.c +@@ -399,42 +399,42 @@ leave_pgrp (struct proc *p) + else if (p->p_parent->p_pgrp != pg + && p->p_parent->p_pgrp->pg_session == pg->pg_session + && !--pg->pg_orphcnt) + { + /* We were the last process keeping this from being + an orphaned process group -- do the orphaning gook */ + struct proc *ip; + int dosignal = 0; + + for (ip = pg->pg_plist; ip; ip = ip->p_gnext) + { + if (ip->p_stopped) + dosignal = 1; + if (ip->p_msgport != MACH_PORT_NULL) + nowait_msg_proc_newids (ip->p_msgport, ip->p_task, ip->p_parent->p_pid, + ip->p_pid, 1); + } + if (dosignal) + for (ip = pg->pg_plist; ip; ip = ip->p_gnext) + { +- send_signal (ip->p_msgport, SIGHUP, ip->p_task); +- send_signal (ip->p_msgport, SIGCONT, ip->p_task); ++ send_signal (ip->p_msgport, SIGHUP, 0, ip->p_task); ++ send_signal (ip->p_msgport, SIGCONT, 0, ip->p_task); + } + } + } + + /* Cause process P to join its process group. */ + void + join_pgrp (struct proc *p) + { + struct pgrp *pg = p->p_pgrp; + struct proc *tp; + int origorphcnt; + + p->p_gnext = pg->pg_plist; + p->p_gprevp = &pg->pg_plist; + if (pg->pg_plist) + pg->pg_plist->p_gprevp = &p->p_gnext; + pg->pg_plist = p; + + origorphcnt = !!pg->pg_orphcnt; + if (p->p_parent->p_pgrp != pg +diff --git a/proc/proc.h b/proc/proc.h +index 7943e0b..b52ca1d 100644 +--- a/proc/proc.h ++++ b/proc/proc.h +@@ -192,24 +192,24 @@ void exc_clean (void *); + + struct proc *add_tasks (task_t); + int pidfree (pid_t); + + struct proc *create_startup_proc (void); + struct proc *allocate_proc (task_t); + void proc_death_notify (struct proc *); + void complete_proc (struct proc *, pid_t); + + void leave_pgrp (struct proc *); + void join_pgrp (struct proc *); + void boot_setsid (struct proc *); + + void process_has_exited (struct proc *); + void alert_parent (struct proc *); + void reparent_zombies (struct proc *); + void complete_exit (struct proc *); + + void initialize_version_info (void); + +-void send_signal (mach_port_t, int, mach_port_t); ++void send_signal (mach_port_t, int, int, mach_port_t); + + + #endif +diff --git a/proc/stubs.c b/proc/stubs.c +index de3a9b1..ee8e578 100644 +--- a/proc/stubs.c ++++ b/proc/stubs.c +@@ -59,40 +59,41 @@ blocking_message_send (any_t arg) + case MACH_SEND_INTERRUPTED: + case MACH_SEND_INVALID_NOTIFY: + case MACH_SEND_NO_NOTIFY: + case MACH_SEND_NOTIFY_IN_PROGRESS: + assert_perror (err); + break; + + default: /* Other errors are safe to ignore. */ + break; + } + + + return 0; + } + + /* Send signal SIGNO to MSGPORT with REFPORT as reference. Don't + block in any fashion. */ + void + send_signal (mach_port_t msgport, + int signal, ++ int sigcode, + mach_port_t refport) + { + error_t err; + + /* This message buffer might be modified by mach_msg in some error cases, + so we cannot safely use a shared static buffer. */ + struct msg_sig_post_request message = + { + { + /* Message header: */ + (MACH_MSGH_BITS_COMPLEX + | MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, + MACH_MSG_TYPE_MAKE_SEND_ONCE)), /* msgh_bits */ + sizeof message, /* msgh_size */ + msgport, /* msgh_remote_port */ + MACH_PORT_NULL, /* msgh_local_port */ + 0, /* msgh_seqno */ + RPCID_SIG_POST, /* msgh_id */ + }, + { +@@ -101,41 +102,41 @@ send_signal (mach_port_t msgport, + 32, /* msgt_size */ + 1, /* msgt_number */ + 1, /* msgt_inline */ + 0, /* msgt_longform */ + 0, /* msgt_deallocate */ + 0, /* msgt_unused */ + }, + /* Signal number */ + signal, + /* Type descriptor for sigcode */ + { + MACH_MSG_TYPE_INTEGER_32, /* msgt_name */ + 32, /* msgt_size */ + 1, /* msgt_number */ + 1, /* msgt_inline */ + 0, /* msgt_longform */ + 0, /* msgt_deallocate */ + 0, /* msgt_unused */ + }, + /* Sigcode */ +- 0, ++ sigcode, + { + /* Type descriptor for refport */ + MACH_MSG_TYPE_COPY_SEND, /* msgt_name */ + 32, /* msgt_size */ + 1, /* msgt_number */ + 1, /* msgt_inline */ + 0, /* msgt_longform */ + 0, /* msgt_deallocate */ + 0, /* msgt_unused */ + }, + refport + }; + + err = mach_msg ((mach_msg_header_t *)&message, + MACH_SEND_MSG|MACH_SEND_TIMEOUT, sizeof message, 0, + MACH_PORT_NULL, 0, MACH_PORT_NULL); + switch (err) + { + case MACH_SEND_TIMED_OUT: + /* The send could not complete immediately, and we do not want to +diff --git a/proc/wait.c b/proc/wait.c +index 6fc94e8..332aaf6 100644 +--- a/proc/wait.c ++++ b/proc/wait.c +@@ -127,41 +127,41 @@ sample_rusage (struct proc *p) + /* Return nonzero if a `waitpid' on WAIT_PID by a process + in MYPGRP cares about the death of PID/PGRP. */ + static inline int + waiter_cares (pid_t wait_pid, pid_t mypgrp, + pid_t pid, pid_t pgrp) + { + return (wait_pid == pid || + wait_pid == -pgrp || + wait_pid == WAIT_ANY || + (wait_pid == WAIT_MYPGRP && pgrp == mypgrp)); + } + + /* A process is dying. Send SIGCHLD to the parent. + Wake the parent if it is waiting for us to exit. */ + void + alert_parent (struct proc *p) + { + /* We accumulate the aggregate usage stats of all our dead children. */ + rusage_add (&p->p_parent->p_child_rusage, &p->p_rusage); + +- send_signal (p->p_parent->p_msgport, SIGCHLD, p->p_parent->p_task); ++ send_signal (p->p_parent->p_msgport, SIGCHLD, CLD_EXITED, p->p_parent->p_task); + + if (!p->p_exiting) + { + p->p_status = W_EXITCODE (0, SIGKILL); + p->p_sigcode = -1; + } + + if (p->p_parent->p_waiting) + { + condition_broadcast (&p->p_parent->p_wakeup); + p->p_parent->p_waiting = 0; + } + } + + kern_return_t + S_proc_wait (struct proc *p, + mach_port_t reply_port, + mach_msg_type_name_t reply_port_type, + pid_t pid, + int options, +@@ -240,41 +240,41 @@ S_proc_wait (struct proc *p, + kern_return_t + S_proc_mark_stop (struct proc *p, + int signo, + int sigcode) + { + if (!p) + return EOPNOTSUPP; + + p->p_stopped = 1; + p->p_status = W_STOPCODE (signo); + p->p_sigcode = sigcode; + p->p_waited = 0; + + if (p->p_parent->p_waiting) + { + condition_broadcast (&p->p_parent->p_wakeup); + p->p_parent->p_waiting = 0; + } + + if (!p->p_parent->p_nostopcld) +- send_signal (p->p_parent->p_msgport, SIGCHLD, p->p_parent->p_task); ++ send_signal (p->p_parent->p_msgport, SIGCHLD, CLD_STOPPED, p->p_parent->p_task); + + return 0; + } + + /* Implement proc_mark_exit as described in <hurd/process.defs>. */ + kern_return_t + S_proc_mark_exit (struct proc *p, + int status, + int sigcode) + { + if (!p) + return EOPNOTSUPP; + + if (WIFSTOPPED (status)) + return EINVAL; + + sample_rusage (p); /* See comments above sample_rusage. */ + + if (p->p_exiting) + return EBUSY; diff --git a/debian/patches/series b/debian/patches/series index 7fa2ef15..cbb8a6bf 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -29,3 +29,5 @@ ext2fs_nowait.patch libpager_deadlock.patch libdiskfs_self-reauth.patch libdiskfs_sync.patch +libpthread_globsigdisp.patch +posix-sigcodes.patch |