drd/tests/pth_cond_destroy_busy: Add

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13199 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/drd/tests/Makefile.am b/drd/tests/Makefile.am
index 820ef2b..1095b95 100644
--- a/drd/tests/Makefile.am
+++ b/drd/tests/Makefile.am
@@ -156,6 +156,8 @@
 	pth_cancel_locked.vgtest		    \
 	pth_cleanup_handler.stderr.exp		    \
 	pth_cleanup_handler.vgtest		    \
+	pth_cond_destroy_busy.stderr.exp            \
+	pth_cond_destroy_busy.vgtest                \
 	pth_cond_race.stderr.exp                    \
 	pth_cond_race.vgtest                        \
 	pth_cond_race2.stderr.exp                   \
@@ -315,6 +317,7 @@
   pth_broadcast       \
   pth_cancel_locked   \
   pth_cleanup_handler \
+  pth_cond_destroy_busy \
   pth_cond_race       \
   pth_create_chain    \
   pth_detached        \
diff --git a/drd/tests/pth_cond_destroy_busy.c b/drd/tests/pth_cond_destroy_busy.c
new file mode 100644
index 0000000..469e45f
--- /dev/null
+++ b/drd/tests/pth_cond_destroy_busy.c
@@ -0,0 +1,69 @@
+/*
+ * Invoke pthread_cond_destroy() on a condition variable that is being waited
+ * upon.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>     // printf()
+#include <pthread.h>
+
+static pthread_mutex_t s_mutex;
+static pthread_cond_t  s_cond;
+static int             s_i;
+
+static const char* err_to_str(int errnum)
+{
+  switch (errnum) {
+  case 0:      return "success";
+  case EBUSY:  return "EBUSY";
+  case EINVAL: return "EINVAL";
+  default:     return "?";
+  }
+}
+
+static void* thread_func(void* thread_arg)
+{
+  pthread_mutex_lock(&s_mutex);
+  s_i = 1;
+  pthread_cond_signal(&s_cond);
+  while (s_i == 1)
+    pthread_cond_wait(&s_cond, &s_mutex);
+  pthread_mutex_unlock(&s_mutex);
+
+  return 0;
+}
+
+int main(int argc, char** argv)
+{
+  pthread_t threadid;
+  int ret;
+
+  pthread_mutex_init(&s_mutex, 0);
+  pthread_cond_init(&s_cond, 0);
+
+  pthread_create(&threadid, 0, thread_func, 0);
+
+  pthread_mutex_lock(&s_mutex);
+  while (s_i == 0)
+    pthread_cond_wait(&s_cond, &s_mutex);
+  pthread_mutex_unlock(&s_mutex);
+
+  ret = pthread_cond_destroy(&s_cond);
+  fprintf(stderr, "First pthread_cond_destroy() call returned %s.\n",
+          err_to_str(ret));
+
+  pthread_mutex_lock(&s_mutex);
+  s_i = 2;
+  pthread_cond_signal(&s_cond);
+  pthread_mutex_unlock(&s_mutex);
+
+  pthread_join(threadid, 0);
+
+  ret = pthread_cond_destroy(&s_cond);
+  fprintf(stderr, "Second pthread_cond_destroy() call returned %s.\n",
+          err_to_str(ret));
+  pthread_mutex_destroy(&s_mutex);
+
+  return 0;
+}
diff --git a/drd/tests/pth_cond_destroy_busy.stderr.exp b/drd/tests/pth_cond_destroy_busy.stderr.exp
new file mode 100644
index 0000000..c1284ab
--- /dev/null
+++ b/drd/tests/pth_cond_destroy_busy.stderr.exp
@@ -0,0 +1,12 @@
+
+destruction of condition variable being waited upon: cond 0x........
+   at 0x........: pthread_cond_destroy (drd_pthread_intercepts.c:?)
+   by 0x........: main (pth_cond_destroy_busy.c:?)
+cond 0x........ was first observed at:
+   at 0x........: pthread_cond_init (drd_pthread_intercepts.c:?)
+   by 0x........: main (pth_cond_destroy_busy.c:?)
+
+First pthread_cond_destroy() call returned EBUSY
+Second pthread_cond_destroy() call returned success
+
+ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
diff --git a/drd/tests/pth_cond_destroy_busy.vgtest b/drd/tests/pth_cond_destroy_busy.vgtest
new file mode 100644
index 0000000..eafbd74
--- /dev/null
+++ b/drd/tests/pth_cond_destroy_busy.vgtest
@@ -0,0 +1,2 @@
+prereq: ./supported_libpthread
+prog: pth_cond_destroy_busy