summaryrefslogtreecommitdiff
path: root/sysdeps/mach
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2002-09-20 03:31:58 +0000
committerRoland McGrath <roland@gnu.org>2002-09-20 03:31:58 +0000
commit4ac9bb2e4a9c8be4c0f27ef7ede2bc7a9e219083 (patch)
tree9623636c75d05aa97c55066aa37ba1f64860baf6 /sysdeps/mach
parent3c9117108e4bb02d66b454eee6ac6853efee78d5 (diff)
downloadglibc-4ac9bb2e4a9c8be4c0f27ef7ede2bc7a9e219083.tar.gz
* sysdeps/mach/hurd/fork.c (__fork): Do not free the signal
thread's sigstate data structure if it has been allocated.
Diffstat (limited to 'sysdeps/mach')
-rw-r--r--sysdeps/mach/hurd/fork.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c
index c5dee0cdad..b64a83d766 100644
--- a/sysdeps/mach/hurd/fork.c
+++ b/sysdeps/mach/hurd/fork.c
@@ -609,14 +609,17 @@ __fork (void)
for (i = 0; i < _hurd_nports; ++i)
__spin_unlock (&_hurd_ports[i].lock);
- /* We are the only thread in this new task, so we will
- take the task-global signals. */
+ /* We are one of the (exactly) two threads in this new task, we
+ will take the task-global signals. */
_hurd_sigthread = ss->thread;
- /* Unchain the sigstate structures for threads that existed in the
- parent task but don't exist in this task (the child process).
- Delay freeing them until later because some of the further setup
- and unlocking might be required for free to work. */
+ /* Claim our sigstate structure and unchain the rest: the
+ threads existed in the parent task but don't exist in this
+ task (the child process). Delay freeing them until later
+ because some of the further setup and unlocking might be
+ required for free to work. Before we finish cleaning up,
+ we will reclaim the signal thread's sigstate structure (if
+ it had one). */
oldstates = _hurd_sigstates;
if (oldstates == ss)
oldstates = ss->next;
@@ -650,13 +653,26 @@ __fork (void)
if (!err)
err = __thread_resume (_hurd_msgport_thread);
- /* Free the old sigstate structures. */
+ /* Reclaim the signal thread's sigstate structure and free the
+ other old sigstate structures. */
while (oldstates != NULL)
{
struct hurd_sigstate *next = oldstates->next;
- free (oldstates);
+
+ if (oldstates->thread == _hurd_msgport_thread)
+ {
+ /* If we have a second signal state structure then we
+ must have been through here before--not good. */
+ assert (_hurd_sigstates->next == 0);
+ _hurd_sigstates->next = oldstates;
+ oldstates->next = 0;
+ }
+ else
+ free (oldstates);
+
oldstates = next;
}
+
/* XXX what to do if we have any errors here? */
pid = 0;