summaryrefslogtreecommitdiff
path: root/sysdeps/mach
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2014-01-22 01:15:55 +0100
committerRichard Braun <rbraun@sceen.net>2014-01-22 01:15:55 +0100
commit7c6dc6e28b2fc4b67934223f41cf080ffe58b230 (patch)
treed5789b64fea9c9e7021e1ec9591583d3285109d2 /sysdeps/mach
parent014966443ac044ca9d53b6bcec6678b9360cba78 (diff)
Fix up the main thread TCB
Unlike other threads, the TCB of the main thread is created by the C library before libpthread is initialized and needs special care. * sysdeps/mach/hurd/i386/pt-setup.c (__pthread_setup): Set the `self' member of the main thread TCB.
Diffstat (limited to 'sysdeps/mach')
-rw-r--r--sysdeps/mach/hurd/i386/pt-setup.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/sysdeps/mach/hurd/i386/pt-setup.c b/sysdeps/mach/hurd/i386/pt-setup.c
index 548858b..c3abe91 100644
--- a/sysdeps/mach/hurd/i386/pt-setup.c
+++ b/sysdeps/mach/hurd/i386/pt-setup.c
@@ -74,24 +74,35 @@ __pthread_setup (struct __pthread *thread,
void (*entry_point)(struct __pthread *, void *(*)(void *), void *),
void *(*start_routine)(void *), void *arg)
{
+ tcbhead_t *tcb;
error_t err;
mach_port_t ktid;
thread->mcontext.pc = entry_point;
thread->mcontext.sp = stack_setup (thread, start_routine, arg);
- thread->tcb->self = thread->kernel_thread;
-
ktid = __mach_thread_self ();
- if (thread->kernel_thread != ktid)
+ if (thread->kernel_thread == ktid)
+ /* Fix up the TCB for the main thread. The C library has already
+ installed a TCB, which we want to keep using. This TCB must not
+ be freed so don't register it in the thread structure. On the
+ other hand, it's not yet possible to reliably release a TCB.
+ Leave the unused one registered so that it doesn't leak. The
+ only thing left to do is to correctly set the `self' member in
+ the already existing TCB. */
+ tcb = THREAD_SELF;
+ else
{
err = __thread_set_pcsptp (thread->kernel_thread,
1, thread->mcontext.pc,
1, thread->mcontext.sp,
1, thread->tcb);
assert_perror (err);
+ tcb = thread->tcb;
}
__mach_port_deallocate (__mach_task_self (), ktid);
+ tcb->self = thread->kernel_thread;
+
return 0;
}