about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--nptl/ChangeLog12
-rw-r--r--nptl/forward.c12
-rw-r--r--nptl/old_pthread_cond_broadcast.c22
-rw-r--r--nptl/old_pthread_cond_destroy.c4
-rw-r--r--nptl/old_pthread_cond_init.c4
-rw-r--r--nptl/old_pthread_cond_signal.c21
-rw-r--r--nptl/old_pthread_cond_timedwait.c27
-rw-r--r--nptl/old_pthread_cond_wait.c21
-rw-r--r--nptl/pthreadP.h30
9 files changed, 97 insertions, 56 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index b9437ab329..f9e3162825 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,5 +1,17 @@
 2003-01-03  Ulrich Drepper  <drepper@redhat.com>
 
+	* pthreadP.h (pthread_cond_2_0_t): New type.
+	(struct pthread_functions): Use new type for 2.0 condvar callbacks.
+	Use new type for the 2.0 condvar function prototypes.
+	* forward.c: Use pthread_cond_2_0_t for 2.0 condvar functions.
+	* old_pthread_cond_init.c: Use pthread_cond_2_0_t for condvar
+	parameter.
+	* old_pthread_cond_destroy.c: Likewise.
+	* old_pthread_cond_broadcast.c: Likewise.  Lock appropriately.
+	* old_pthread_cond_signal.c: Likewise.
+	* old_pthread_cond_timedwait.c: Likewise.
+	* old_pthread_cond_wait.c: Likewise.
+
 	* sysdeps/unix/sysv/linux/i386/i486/lowlevelcond.S
 	(__pthread_cond_wait): Don't save cancellation mode and seq value
 	in same location.
diff --git a/nptl/forward.c b/nptl/forward.c
index 038eae8684..d3f42a3dc6 100644
--- a/nptl/forward.c
+++ b/nptl/forward.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.
 
@@ -86,7 +86,7 @@ FORWARD (pthread_condattr_destroy, (pthread_condattr_t *attr), (attr), 0)
 FORWARD (pthread_condattr_init, (pthread_condattr_t *attr), (attr), 0)
 
 #if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3_2)
-FORWARD (__pthread_cond_broadcast_2_0, (pthread_cond_t *cond), (cond), 0)
+FORWARD (__pthread_cond_broadcast_2_0, (pthread_cond_2_0_t *cond), (cond), 0)
 compat_symbol (libc, __pthread_cond_broadcast_2_0, pthread_cond_broadcast,
 	       GLIBC_2_0);
 #endif
@@ -95,7 +95,7 @@ versioned_symbol (libc, __pthread_cond_broadcast, pthread_cond_broadcast,
 		  GLIBC_2_3_2);
 
 #if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3_2)
-FORWARD (__pthread_cond_destroy_2_0, (pthread_cond_t *cond), (cond), 0)
+FORWARD (__pthread_cond_destroy_2_0, (pthread_cond_2_0_t *cond), (cond), 0)
 compat_symbol (libc, __pthread_cond_destroy_2_0, pthread_cond_destroy,
 	       GLIBC_2_0);
 #endif
@@ -105,7 +105,7 @@ versioned_symbol (libc, __pthread_cond_destroy, pthread_cond_destroy,
 
 #if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3_2)
 FORWARD (__pthread_cond_init_2_0,
-	 (pthread_cond_t *cond, const pthread_condattr_t *cond_attr),
+	 (pthread_cond_2_0_t *cond, const pthread_condattr_t *cond_attr),
 	 (cond, cond_attr), 0)
 compat_symbol (libc, __pthread_cond_init_2_0, pthread_cond_init, GLIBC_2_0);
 #endif
@@ -115,7 +115,7 @@ FORWARD (__pthread_cond_init,
 versioned_symbol (libc, __pthread_cond_init, pthread_cond_init, GLIBC_2_3_2);
 
 #if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3_2)
-FORWARD (__pthread_cond_signal_2_0, (pthread_cond_t *cond), (cond), 0)
+FORWARD (__pthread_cond_signal_2_0, (pthread_cond_2_0_t *cond), (cond), 0)
 compat_symbol (libc, __pthread_cond_signal_2_0, pthread_cond_signal,
 	       GLIBC_2_0);
 #endif
@@ -125,7 +125,7 @@ versioned_symbol (libc, __pthread_cond_signal, pthread_cond_signal,
 
 #if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3_2)
 FORWARD (__pthread_cond_wait_2_0,
-	 (pthread_cond_t *cond, pthread_mutex_t *mutex), (cond, mutex), 0)
+	 (pthread_cond_2_0_t *cond, pthread_mutex_t *mutex), (cond, mutex), 0)
 compat_symbol (libc, __pthread_cond_wait_2_0, pthread_cond_wait,
 	       GLIBC_2_0);
 #endif
diff --git a/nptl/old_pthread_cond_broadcast.c b/nptl/old_pthread_cond_broadcast.c
index 86f8d5d4b7..a9713f5e1b 100644
--- a/nptl/old_pthread_cond_broadcast.c
+++ b/nptl/old_pthread_cond_broadcast.c
@@ -20,26 +20,32 @@
 #include <errno.h>
 #include <stdlib.h>
 #include "pthreadP.h"
+#include <lowlevellock.h>
 #include <shlib-compat.h>
 
 
 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
 int
 __pthread_cond_broadcast_2_0 (cond)
-     pthread_cond_t *cond;
+     pthread_cond_2_0_t *cond;
 {
-  pthread_cond_t **realp = (pthread_cond_t **) cond;
-
-  if (*realp == NULL)
+  if (cond->cond == NULL)
     {
-      *realp = (pthread_cond_t *) malloc (sizeof (pthread_cond_t));
-      if (*realp == NULL)
+      lll_mutex_lock (cond->lock);
+
+      /* Check whether the condvar is still not allocated.  */
+      if (cond->cond == NULL)
+	cond->cond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t));
+
+      lll_mutex_unlock (cond->lock);
+
+      if (cond->cond == NULL)
 	return ENOMEM;
 
-      **realp = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER;
+      *cond->cond = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER;
     }
 
-  return __pthread_cond_broadcast (*realp);
+  return __pthread_cond_broadcast (cond->cond);
 }
 compat_symbol (libpthread, __pthread_cond_broadcast_2_0,
 	       pthread_cond_broadcast, GLIBC_2_0);
diff --git a/nptl/old_pthread_cond_destroy.c b/nptl/old_pthread_cond_destroy.c
index 6f73f7cc57..f6dba11883 100644
--- a/nptl/old_pthread_cond_destroy.c
+++ b/nptl/old_pthread_cond_destroy.c
@@ -25,10 +25,10 @@
 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
 int
 __pthread_cond_destroy_2_0 (cond)
-     pthread_cond_t *cond;
+     pthread_cond_2_0_t *cond;
 {
   /* Free the memory which was eventually allocated.  */
-  free (*(void **) cond);
+  free (cond->cond);
 
   return 0;
 }
diff --git a/nptl/old_pthread_cond_init.c b/nptl/old_pthread_cond_init.c
index 309136eaab..21bc856a02 100644
--- a/nptl/old_pthread_cond_init.c
+++ b/nptl/old_pthread_cond_init.c
@@ -24,7 +24,7 @@
 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
 int
 __pthread_cond_init_2_0 (cond, cond_attr)
-     pthread_cond_t *cond;
+     pthread_cond_2_0_t *cond;
      const pthread_condattr_t *cond_attr;
 {
   /* Note that we don't need the COND-ATTR.  It contains only the
@@ -34,7 +34,7 @@ __pthread_cond_init_2_0 (cond, cond_attr)
   /* The type of the first argument is actually that of the old, too
      small pthread_cond_t.  We use only the first word of it, as a
      pointer.  */
-  *((void **) cond) = NULL;
+  cond->cond = NULL;
 
   return 0;
 }
diff --git a/nptl/old_pthread_cond_signal.c b/nptl/old_pthread_cond_signal.c
index 869ac4d235..952ee6de41 100644
--- a/nptl/old_pthread_cond_signal.c
+++ b/nptl/old_pthread_cond_signal.c
@@ -26,20 +26,25 @@
 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
 int
 __pthread_cond_signal_2_0 (cond)
-     pthread_cond_t *cond;
+     pthread_cond_2_0_t *cond;
 {
-  pthread_cond_t **realp = (pthread_cond_t **) cond;
-
-  if (*realp == NULL)
+  if (cond->cond == NULL)
     {
-      *realp = (pthread_cond_t *) malloc (sizeof (pthread_cond_t));
-      if (*realp == NULL)
+      lll_mutex_lock (cond->lock);
+
+      /* Check whether the condvar is still not allocated.  */
+      if (cond->cond == NULL)
+	cond->cond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t));
+
+      lll_mutex_unlock (cond->lock);
+
+      if (cond->cond == NULL)
 	return ENOMEM;
 
-      **realp = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER;
+      *cond->cond = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER;
     }
 
-  return __pthread_cond_signal (*realp);
+  return __pthread_cond_signal (cond->cond);
 }
 compat_symbol (libpthread, __pthread_cond_signal_2_0, pthread_cond_signal,
 	       GLIBC_2_0);
diff --git a/nptl/old_pthread_cond_timedwait.c b/nptl/old_pthread_cond_timedwait.c
index 6f844346fd..7b0faa78d2 100644
--- a/nptl/old_pthread_cond_timedwait.c
+++ b/nptl/old_pthread_cond_timedwait.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.
 
@@ -25,24 +25,29 @@
 
 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
 int
-__old_pthread_cond_timedwait (cond, mutex, abstime)
-     pthread_cond_t *cond;
+__pthread_cond_timedwait_2_0 (cond, mutex, abstime)
+     pthread_cond_2_0_t *cond;
      pthread_mutex_t *mutex;
      const struct timespec *abstime;
 {
-  pthread_cond_t **realp = (pthread_cond_t **) cond;
-
-  if (*realp == NULL)
+  if (cond->cond == NULL)
     {
-      *realp = (pthread_cond_t *) malloc (sizeof (pthread_cond_t));
-      if (*realp == NULL)
+      lll_mutex_lock (cond->lock);
+
+      /* Check whether the condvar is still not allocated.  */
+      if (cond->cond == NULL)
+	cond->cond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t));
+
+      lll_mutex_unlock (cond->lock);
+
+      if (cond->cond == NULL)
 	return ENOMEM;
 
-      **realp = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER;
+      *cond->cond = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER;
     }
 
-  return __pthread_cond_timedwait (*realp, mutex, abstime);
+  return __pthread_cond_timedwait (cond->cond, mutex, abstime);
 }
-compat_symbol (libpthread, __old_pthread_cond_timedwait,
+compat_symbol (libpthread, __pthread_cond_timedwait_2_0,
 	       pthread_cond_timedwait, GLIBC_2_0);
 #endif
diff --git a/nptl/old_pthread_cond_wait.c b/nptl/old_pthread_cond_wait.c
index 4d4f9431d5..493f00a3eb 100644
--- a/nptl/old_pthread_cond_wait.c
+++ b/nptl/old_pthread_cond_wait.c
@@ -26,21 +26,26 @@
 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
 int
 __pthread_cond_wait_2_0 (cond, mutex)
-     pthread_cond_t *cond;
+     pthread_cond_2_0_t *cond;
      pthread_mutex_t *mutex;
 {
-  pthread_cond_t **realp = (pthread_cond_t **) cond;
-
-  if (*realp == NULL)
+  if (cond->cond == NULL)
     {
-      *realp = (pthread_cond_t *) malloc (sizeof (pthread_cond_t));
-      if (*realp == NULL)
+      lll_mutex_lock (cond->lock);
+
+      /* Check whether the condvar is still not allocated.  */
+      if (cond->cond == NULL)
+	cond->cond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t));
+
+      lll_mutex_unlock (cond->lock);
+
+      if (cond->cond == NULL)
 	return ENOMEM;
 
-      **realp = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER;
+      *cond->cond = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER;
     }
 
-  return __pthread_cond_wait (*realp, mutex);
+  return __pthread_cond_wait (cond->cond, mutex);
 }
 compat_symbol (libpthread, __pthread_cond_wait_2_0, pthread_cond_wait,
 	       GLIBC_2_0);
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 0a0e332f1c..51b34f49ef 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -67,6 +67,14 @@ extern int __pthread_debug attribute_hidden;
 #define DEBUGGING_P __builtin_expect (__pthread_debug, 0)
 
 
+/* Compatibility type for old conditional variable interfaces.  */
+typedef struct
+{
+  pthread_cond_t *cond;
+  lll_lock_t lock;
+} pthread_cond_2_0_t;
+
+
 /* Data type shared with libc.  The libc uses it to pass on calls to
    the thread functions.  */
 struct pthread_functions
@@ -94,12 +102,12 @@ struct pthread_functions
 				  const pthread_condattr_t *);
   int (*ptr___pthread_cond_signal) (pthread_cond_t *);
   int (*ptr___pthread_cond_wait) (pthread_cond_t *, pthread_mutex_t *);
-  int (*ptr___pthread_cond_broadcast_2_0) (pthread_cond_t *);
-  int (*ptr___pthread_cond_destroy_2_0) (pthread_cond_t *);
-  int (*ptr___pthread_cond_init_2_0) (pthread_cond_t *,
+  int (*ptr___pthread_cond_broadcast_2_0) (pthread_cond_2_0_t *);
+  int (*ptr___pthread_cond_destroy_2_0) (pthread_cond_2_0_t *);
+  int (*ptr___pthread_cond_init_2_0) (pthread_cond_2_0_t *,
 				      const pthread_condattr_t *);
-  int (*ptr___pthread_cond_signal_2_0) (pthread_cond_t *);
-  int (*ptr___pthread_cond_wait_2_0) (pthread_cond_t *, pthread_mutex_t *);
+  int (*ptr___pthread_cond_signal_2_0) (pthread_cond_2_0_t *);
+  int (*ptr___pthread_cond_wait_2_0) (pthread_cond_2_0_t *, pthread_mutex_t *);
   int (*ptr_pthread_equal) (pthread_t, pthread_t);
   void (*ptr___pthread_exit) (void *);
   int (*ptr_pthread_getschedparam) (pthread_t, int *, struct sched_param *);
@@ -322,15 +330,15 @@ extern int __pthread_enable_asynccancel (void) attribute_hidden;
 extern void __pthread_disable_asynccancel (int oldtype)
      internal_function attribute_hidden;
 
-extern int __pthread_cond_broadcast_2_0 (pthread_cond_t *cond);
-extern int __pthread_cond_destroy_2_0 (pthread_cond_t *cond);
-extern int __pthread_cond_init_2_0 (pthread_cond_t *cond,
+extern int __pthread_cond_broadcast_2_0 (pthread_cond_2_0_t *cond);
+extern int __pthread_cond_destroy_2_0 (pthread_cond_2_0_t *cond);
+extern int __pthread_cond_init_2_0 (pthread_cond_2_0_t *cond,
 				    const pthread_condattr_t *cond_attr);
-extern int __pthread_cond_signal_2_0 (pthread_cond_t *cond);
-extern int __old_pthread_cond_timedwait (pthread_cond_t *cond,
+extern int __pthread_cond_signal_2_0 (pthread_cond_2_0_t *cond);
+extern int __pthread_cond_timedwait_2_0 (pthread_cond_2_0_t *cond,
 					 pthread_mutex_t *mutex,
 					 const struct timespec *abstime);
-extern int __pthread_cond_wait_2_0 (pthread_cond_t *cond,
+extern int __pthread_cond_wait_2_0 (pthread_cond_2_0_t *cond,
 				    pthread_mutex_t *mutex);
 
 /* The two functions are in libc.so and not exported.  */