summaryrefslogtreecommitdiff
path: root/regress/lib/libpthread
diff options
context:
space:
mode:
authorFederico G. Schwindt <fgsch@cvs.openbsd.org>2005-10-31 01:01:30 +0000
committerFederico G. Schwindt <fgsch@cvs.openbsd.org>2005-10-31 01:01:30 +0000
commit6ff500419ef9c2cf0ee2538c680ec6ac0cf41419 (patch)
tree79af2ea8a429d596b8a002dad2d67d8083aef3c0 /regress/lib/libpthread
parent51e3e528880937879a7b1ddf9442fc95c4a6c515 (diff)
pthread_atfork(3) regression.
Diffstat (limited to 'regress/lib/libpthread')
-rw-r--r--regress/lib/libpthread/pthread_atfork/Makefile5
-rw-r--r--regress/lib/libpthread/pthread_atfork/pthread_atfork.c118
2 files changed, 123 insertions, 0 deletions
diff --git a/regress/lib/libpthread/pthread_atfork/Makefile b/regress/lib/libpthread/pthread_atfork/Makefile
new file mode 100644
index 00000000000..2bc578924f4
--- /dev/null
+++ b/regress/lib/libpthread/pthread_atfork/Makefile
@@ -0,0 +1,5 @@
+# $OpenBSD: Makefile,v 1.1 2005/10/31 01:01:29 fgsch Exp $
+
+PROG= pthread_atfork
+
+.include <bsd.regress.mk>
diff --git a/regress/lib/libpthread/pthread_atfork/pthread_atfork.c b/regress/lib/libpthread/pthread_atfork/pthread_atfork.c
new file mode 100644
index 00000000000..ccf69105836
--- /dev/null
+++ b/regress/lib/libpthread/pthread_atfork/pthread_atfork.c
@@ -0,0 +1,118 @@
+/* $OpenBSD: pthread_atfork.c,v 1.1 2005/10/31 01:01:29 fgsch Exp $ */
+
+/*
+ * Federico Schwindt <fgsch@openbsd.org>, 2005. Public Domain.
+ */
+
+#include <sys/types.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#include "test.h"
+
+pthread_mutex_t atfork_mutex;
+int cnt;
+
+void
+prepare1(void)
+{
+ ASSERT(cnt == 1);
+ cnt--;
+}
+
+void
+prepare2(void)
+{
+ ASSERT(cnt == 2);
+ cnt--;
+}
+
+void
+parent1(void)
+{
+ ASSERT(cnt == 0);
+ cnt += 2;
+}
+
+void
+parent2(void)
+{
+ ASSERT(cnt == 2);
+ cnt -= 2;
+}
+
+void
+child1(void)
+{
+ ASSERT(cnt == 0);
+ cnt += 3;
+}
+
+void
+child2(void)
+{
+ ASSERT(cnt == 3);
+ cnt++;
+}
+
+void *
+forker1(void *arg)
+{
+ CHECKr(pthread_atfork(prepare1, parent1, child1));
+
+ cnt = 1;
+ switch (fork()) {
+ case -1:
+ break;
+
+ case 0:
+ ASSERT(cnt == 3);
+ _exit(0);
+
+ default:
+ ASSERT(cnt == 2);
+ break;
+ }
+
+ cnt = 1;
+
+ return (NULL);
+}
+
+void *
+forker2(void *arg)
+{
+ CHECKr(pthread_atfork(prepare2, parent2, child2));
+
+ cnt = 2;
+ switch (fork()) {
+ case -1:
+ break;
+
+ case 0:
+ ASSERT(cnt == 4);
+ _exit(0);
+
+ default:
+ ASSERT(cnt == 0);
+ break;
+ }
+
+ cnt = 0;
+
+ return (NULL);
+}
+
+int
+main(int argc, char **argv)
+{
+ pthread_t tid;
+
+ CHECKr(pthread_create(&tid, NULL, forker1, NULL));
+ CHECKr(pthread_join(tid, NULL));
+ ASSERT(cnt == 1);
+ CHECKr(pthread_create(&tid, NULL, forker2, NULL));
+ CHECKr(pthread_join(tid, NULL));
+ ASSERT(cnt == 0);
+ SUCCEED;
+}