[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: