Date: Thu, 28 May 2009 02:39:07 +0000 (UTC) From: Zachary Loafman <zml@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r192949 - head/tools/regression/file/flock Message-ID: <200905280239.n4S2d748019904@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: zml Date: Thu May 28 02:39:07 2009 New Revision: 192949 URL: http://svn.freebsd.org/changeset/base/192949 Log: Add a regression test for multiple threads of the same process acquiring the same fcntl lock. Approved by: dfr (mentor) Modified: head/tools/regression/file/flock/Makefile head/tools/regression/file/flock/flock.c Modified: head/tools/regression/file/flock/Makefile ============================================================================== --- head/tools/regression/file/flock/Makefile Thu May 28 02:17:58 2009 (r192948) +++ head/tools/regression/file/flock/Makefile Thu May 28 02:39:07 2009 (r192949) @@ -4,4 +4,6 @@ PROG= flock NO_MAN= WARNS?= 6 +LDADD+= -lpthread + .include <bsd.prog.mk> Modified: head/tools/regression/file/flock/flock.c ============================================================================== --- head/tools/regression/file/flock/flock.c Thu May 28 02:17:58 2009 (r192948) +++ head/tools/regression/file/flock/flock.c Thu May 28 02:39:07 2009 (r192949) @@ -37,6 +37,7 @@ #include <err.h> #include <errno.h> #include <fcntl.h> +#include <pthread.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> @@ -1401,6 +1402,112 @@ test15(int fd, __unused int argc, const #endif } +struct test_ctx { + struct flock tc_fl; + int tc_fd; +}; + +static void * +test16_func(void *tc_in) +{ + uintptr_t error; + struct test_ctx *tc = tc_in; + + error = fcntl(tc->tc_fd, F_SETLKW, &tc->tc_fl); + + pthread_exit((void *)error); +} + +#define THREADS 10 + +/* + * Test 16 - F_SETLKW from two threads + * + * If two threads within a process are blocked on a lock and the lock + * is granted, make sure things are sane. + */ +static int +test16(int fd, __unused int argc, const __unused char **argv) +{ + /* + * We create a child process to hold the lock which we will + * test. We use a pipe to communicate with the child. + */ + int pid; + int pfd[2]; + struct test_ctx tc = { .tc_fd = fd }; + char ch; + int i; + int error; + pthread_t thr[THREADS]; + + if (pipe(pfd) < 0) + err(1, "pipe"); + + tc.tc_fl.l_start = 0; + tc.tc_fl.l_len = 0; + tc.tc_fl.l_type = F_WRLCK; + tc.tc_fl.l_whence = SEEK_SET; + + pid = fork(); + if (pid < 0) + err(1, "fork"); + + if (pid == 0) { + /* + * We are the child. We set a write lock and then + * write one byte back to the parent to tell it. The + * parent will kill us when its done. + */ + if (fcntl(fd, F_SETLK, &tc.tc_fl) < 0) + err(1, "F_SETLK (child)"); + if (write(pfd[1], "a", 1) < 0) + err(1, "writing to pipe (child)"); + pause(); + exit(0); + } + + /* + * Wait until the child has set its lock and then perform the + * test. + */ + if (read(pfd[0], &ch, 1) != 1) + err(1, "reading from pipe (child)"); + + /* + * fcntl should wait until the alarm and then return -1 with + * errno set to EINTR. + */ + printf("16 - F_SETLKW on locked region by two threads: "); + + for (i = 0; i < THREADS; i++) { + error = pthread_create(&thr[i], NULL, test16_func, &tc); + if (error) + err(1, "pthread_create"); + } + + /* + * Sleep, then kill the child. This makes me a little sad, but it's + * tricky to tell whether the threads are all really blocked by this + * point. + */ + sleep(1); + kill(pid, SIGTERM); + safe_waitpid(pid); + close(pfd[0]); + close(pfd[1]); + + for (i = 0; i < THREADS; i++) { + void *res; + error = pthread_join(thr[i], &res); + if (error) + err(1, "pthread_join"); + FAIL((uintptr_t)res != 0); + } + + SUCCEED; +} + struct test { int (*testfn)(int, int, const char **); /* function to perform the test */ int num; /* test number */ @@ -1423,6 +1530,7 @@ struct test tests[] = { { test13, 13, 1 }, { test14, 14, 0 }, { test15, 15, 1 }, + { test16, 16, 1 }, }; int test_count = sizeof(tests) / sizeof(tests[0]);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905280239.n4S2d748019904>