about summary refs log tree commit diff
path: root/nptl/cancellation.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-03-11 23:26:35 +0000
committerUlrich Drepper <drepper@redhat.com>2003-03-11 23:26:35 +0000
commit32a589b1ea1365c8651b0692d0350403fde7b6ff (patch)
tree77b94275bcf321370496c19d29267e8c66a8606d /nptl/cancellation.c
parent3e976b962a84255b70bcf6d9751a9a35d3e987ab (diff)
downloadglibc-32a589b1ea1365c8651b0692d0350403fde7b6ff.tar.gz
glibc-32a589b1ea1365c8651b0692d0350403fde7b6ff.tar.xz
glibc-32a589b1ea1365c8651b0692d0350403fde7b6ff.zip
Update.
	* cancellation.c (__pthread_enable_asynccancel_2): New function.
	* pthreadP.h: Declare __pthread_enable_asynccancel_2.
	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
	(__pthread_cond_timedwait): Use __pthread_enable_asynccancel_2
	instead of __pthread_enable_asynccancel.
	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
	(__pthread_cond_wait): Likewise.
	* sysdeps/pthread/pthread_cond_timedwait.c
	(__pthread_cond_timedwait): Likewise.
	* sysdeps/pthread/pthread_cond_wait.c (__pthread_cond_wait): Likewise.
Diffstat (limited to 'nptl/cancellation.c')
-rw-r--r--nptl/cancellation.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/nptl/cancellation.c b/nptl/cancellation.c
index f136bbb4c4..1dfbe4baca 100644
--- a/nptl/cancellation.c
+++ b/nptl/cancellation.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -57,6 +57,35 @@ __pthread_enable_asynccancel (void)
   return oldval;
 }
 
+/* XXX Ideally we have only one version.  But this needs preparation.  */
+void
+internal_function attribute_hidden
+__pthread_enable_asynccancel_2 (int *oldvalp)
+{
+  struct pthread *self = THREAD_SELF;
+
+  while (1)
+    {
+      int oldval = *oldvalp = THREAD_GETMEM (self, cancelhandling);
+      int newval = oldval | CANCELTYPE_BITMASK;
+
+      if (newval == oldval)
+	break;
+
+      if (atomic_compare_and_exchange_acq (&self->cancelhandling, newval,
+					   oldval) == 0)
+	{
+	  if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
+	    {
+	      THREAD_SETMEM (self, result, PTHREAD_CANCELED);
+	      __do_cancel ();
+	    }
+
+	  break;
+	}
+    }
+}
+
 
 void
 internal_function attribute_hidden