r5899 - in glibc-package/branches/eglibc-2.18/debian: . patches patches/hurd-i386
Author: sthibault
Date: 2013-12-31 12:30:37 +0000 (Tue, 31 Dec 2013)
New Revision: 5899
Added:
glibc-package/branches/eglibc-2.18/debian/patches/hurd-i386/tg-sigstate_thread_reference.diff
Modified:
glibc-package/branches/eglibc-2.18/debian/changelog
glibc-package/branches/eglibc-2.18/debian/patches/series
Log:
patches/hurd-i386/tg-sigstate_thread_reference.diff: New patch to fix sigstate thread reference counting.
Modified: glibc-package/branches/eglibc-2.18/debian/changelog
===================================================================
--- glibc-package/branches/eglibc-2.18/debian/changelog 2013-12-31 12:26:36 UTC (rev 5898)
+++ glibc-package/branches/eglibc-2.18/debian/changelog 2013-12-31 12:30:37 UTC (rev 5899)
@@ -20,6 +20,8 @@
array.
* patches/hurd-i386/tg-sigstate_locking.diff: New patch to fix sigstate
creation.
+ * patches/hurd-i386/tg-sigstate_thread_reference.diff: New patch to fix
+ sigstate thread reference counting.
-- Adam Conrad <adconrad@ubuntu.com> Tue, 10 Dec 2013 01:59:47 -0700
Added: glibc-package/branches/eglibc-2.18/debian/patches/hurd-i386/tg-sigstate_thread_reference.diff
===================================================================
--- glibc-package/branches/eglibc-2.18/debian/patches/hurd-i386/tg-sigstate_thread_reference.diff (rev 0)
+++ glibc-package/branches/eglibc-2.18/debian/patches/hurd-i386/tg-sigstate_thread_reference.diff 2013-12-31 12:30:37 UTC (rev 5899)
@@ -0,0 +1,124 @@
+From: Richard Braun <rbraun@sceen.net>
+Subject: [PATCH] Hurd: make sigstates hold a reference on thread ports
+
+This change is required in order to correctly release per-thread
+resources. Directly reusing the threading library reference isn't
+possible since the sigstate is also used early in the main thread,
+before threading is initialized.
+
+* hurd/hurd/signal.h (_hurd_self_sigstate): Drop thread reference after
+calling _hurd_thread_sigstate.
+(_hurd_critical_section_lock): Likewise.
+* hurd/hurdsig.c (_hurd_thread_sigstate): Add a reference on the thread.
+(_hurd_sigstate_delete): Drop thread reference.
+
+---
+ hurd/hurd/signal.h | 17 ++++++++++++++---
+ hurd/hurdsig.c | 17 ++++++++++++++---
+ 2 files changed, 28 insertions(+), 6 deletions(-)
+
+diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h
+index db60e6f..1d1218a 100644
+--- a/hurd/hurd/signal.h
++++ b/hurd/hurd/signal.h
+@@ -64,7 +64,9 @@ struct hurd_sigstate
+
+ spin_lock_t lock; /* Locks most of the rest of the structure. */
+
++ /* The signal state holds a reference on the thread port. */
+ thread_t thread;
++
+ struct hurd_sigstate *next; /* Linked-list of thread sigstates. */
+
+ sigset_t blocked; /* What signals are blocked. */
+@@ -118,7 +120,9 @@ extern struct hurd_sigstate *_hurd_sigstates;
+
+ extern struct mutex _hurd_siglock; /* Locks _hurd_sigstates. */
+
+-/* Get the sigstate of a given thread, taking its lock. */
++/* Get the sigstate of a given thread. If there was no sigstate for
++ the thread, one is created, and the thread gains a reference. If
++ the given thread is MACH_PORT_NULL, return the global sigstate. */
+
+ extern struct hurd_sigstate *_hurd_thread_sigstate (thread_t);
+
+@@ -161,7 +165,11 @@ _hurd_self_sigstate (void)
+ _hurd_self_sigstate (void)
+ {
+ if (_hurd_sigstate == NULL)
+- _hurd_sigstate = _hurd_thread_sigstate (__mach_thread_self ());
++ {
++ thread_t self = __mach_thread_self ();
++ _hurd_sigstate = _hurd_thread_sigstate (self);
++ __mach_port_deallocate (__mach_task_self (), self);
++ }
+ return _hurd_sigstate;
+ }
+ #endif
+@@ -192,11 +200,14 @@ _hurd_critical_section_lock (void)
+ ss = _hurd_sigstate;
+ if (ss == NULL)
+ {
++ thread_t self = __mach_thread_self ();
++
+ /* 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. */
+- ss = _hurd_sigstate = _hurd_thread_sigstate (__mach_thread_self ());
++ ss = _hurd_sigstate = _hurd_thread_sigstate (self);
++ __mach_port_deallocate (__mach_task_self (), self);
+ }
+
+ if (! __spin_try_lock (&ss->critical_section_lock))
+diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
+index 72c582f..486be7c 100644
+--- a/hurd/hurdsig.c
++++ b/hurd/hurdsig.c
+@@ -105,6 +105,8 @@ _hurd_thread_sigstate (thread_t thread)
+ }
+ else
+ {
++ error_t err;
++
+ /* Use the global actions as a default for new threads. */
+ struct hurd_sigstate *s = _hurd_global_sigstate;
+ if (s)
+@@ -118,6 +120,11 @@ _hurd_thread_sigstate (thread_t thread)
+
+ ss->next = _hurd_sigstates;
+ _hurd_sigstates = ss;
++
++ err = __mach_port_mod_refs (__mach_task_self (), thread,
++ MACH_PORT_RIGHT_SEND, 1);
++ if (err)
++ __libc_fatal ("hurd: Can't add reference on Mach thread\n");
+ }
+ }
+ __mutex_unlock (&_hurd_siglock);
+@@ -125,8 +132,7 @@ _hurd_thread_sigstate (thread_t thread)
+ }
+
+ /* Destroy a sigstate structure. Called by libpthread just before the
+- * corresponding thread is terminated (the kernel thread port must remain valid
+- * until this function is called.) */
++ * corresponding thread is terminated. */
+ void
+ _hurd_sigstate_delete (thread_t thread)
+ {
+@@ -143,7 +149,12 @@ _hurd_sigstate_delete (thread_t thread)
+
+ __mutex_unlock (&_hurd_siglock);
+ if (ss)
+- free (ss);
++ {
++ if (ss->thread != MACH_PORT_NULL)
++ __mach_port_deallocate (__mach_task_self (), ss->thread);
++
++ free (ss);
++ }
+ }
+
+ /* Make SS a global receiver, with pthread signal semantics. */
+--
+tg: (e631e50..) t/sigstate_thread_reference (depends on: t/hurdsig-global-dispositions)
Modified: glibc-package/branches/eglibc-2.18/debian/patches/series
===================================================================
--- glibc-package/branches/eglibc-2.18/debian/patches/series 2013-12-31 12:26:36 UTC (rev 5898)
+++ glibc-package/branches/eglibc-2.18/debian/patches/series 2013-12-31 12:30:37 UTC (rev 5899)
@@ -145,6 +145,7 @@
hurd-i386/tg-libc_getspecific.diff
hurd-i386/tg-nfds-poll.diff
hurd-i386/tg-sigstate_locking.diff
+hurd-i386/tg-sigstate_thread_reference.diff
i386/local-biarch.diff
i386/local-cmov.diff
Reply to: