summary refs log tree commit diff
path: root/linuxthreads
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-09-27 00:14:27 +0000
committerUlrich Drepper <drepper@redhat.com>2000-09-27 00:14:27 +0000
commit75dbc100bf903f908c4e5e90783307cf445b19db (patch)
treec92289288e27adeeb6fb0a7d728e2c42db5c82a7 /linuxthreads
parentb0557314bc23ed0020cc673cabd540518ab3ed16 (diff)
downloadglibc-75dbc100bf903f908c4e5e90783307cf445b19db.tar.gz
glibc-75dbc100bf903f908c4e5e90783307cf445b19db.tar.xz
glibc-75dbc100bf903f908c4e5e90783307cf445b19db.zip
Update.
2000-09-26  Ulrich Drepper  <drepper@redhat.com>

	* sysdeps/unix/sysv/linux/i386/bits/time.h: Remove CLOCK_MONOTONIC.
Diffstat (limited to 'linuxthreads')
-rw-r--r--linuxthreads/ChangeLog3
-rw-r--r--linuxthreads/spinlock.h23
2 files changed, 20 insertions, 6 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog
index daa6f06951..6d22d9b8a5 100644
--- a/linuxthreads/ChangeLog
+++ b/linuxthreads/ChangeLog
@@ -1,5 +1,8 @@
 2000-09-26  Ulrich Drepper  <drepper@redhat.com>
 
+	* spinlock.h (__pthread_set_own_extricate_if): Optimize a bit.
+	Patch by Kaz Kylheku <kaz@ashi.footprints.net>.
+
 	* sysdeps/unix/sysv/linux/i386/bits/posix_opt.h: Remove
 	_POSIX_MONOTONIC_CLOCK.
 
diff --git a/linuxthreads/spinlock.h b/linuxthreads/spinlock.h
index c194d79bd6..2d3e9bf9f2 100644
--- a/linuxthreads/spinlock.h
+++ b/linuxthreads/spinlock.h
@@ -212,11 +212,22 @@ static inline long atomic_decrement(struct pthread_atomic *pa)
 
 
 static inline void
-__pthread_set_own_extricate_if(pthread_descr self, pthread_extricate_if *peif)
+__pthread_set_own_extricate_if (pthread_descr self, pthread_extricate_if *peif)
 {
-  /* The locks here are not ensuring an atomic update of the p_extricate
-     pointer.  They protect users of the pointer from using stale memory.  */
-  __pthread_lock(THREAD_GETMEM(self, p_lock), self);
-  THREAD_SETMEM(self, p_extricate, peif);
-  __pthread_unlock(THREAD_GETMEM (self, p_lock));
+  /* Only store a non-null peif if the thread has cancellation enabled.
+     Otherwise pthread_cancel will unconditionally call the extricate handler,
+     and restart the thread giving rise to forbidden spurious wakeups. */
+  if (peif == NULL
+      || THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)
+    {
+      /* If we are removing the extricate interface, we need to synchronize
+	 against pthread_cancel so that it does not continue with a pointer
+         to a deallocated pthread_extricate_if struct! The thread lock
+         is (ab)used for this synchronization purpose. */
+      if (peif == NULL)
+	__pthread_lock (THREAD_GETMEM(self, p_lock), self);
+      THREAD_SETMEM(self, p_extricate, peif);
+      if (peif == NULL)
+	__pthread_unlock (THREAD_GETMEM(self, p_lock));
+    }
 }