summaryrefslogtreecommitdiff
path: root/test/testlock.c
diff options
context:
space:
mode:
authorJustin Erenkrantz <jerenkrantz@apache.org>2001-05-31 03:30:06 +0000
committerJustin Erenkrantz <jerenkrantz@apache.org>2001-05-31 03:30:06 +0000
commitce9c8d968486d8130da8cb1212b67b6697a796da (patch)
treeaea963f3f8e176fe338ec3eeabb1f7e9f10aa94b /test/testlock.c
parentf99b5e4e4e2a88d049b31eae7fc8f52bfa1e8733 (diff)
downloadapr-ce9c8d968486d8130da8cb1212b67b6697a796da.tar.gz
Implement read write locks. This commit will support POSIX pthread
rw locks on Unix platforms. This is based on earlier patches that I posted to apr-dev, but did not receive feedback from others on. Hence, I'm committing. This will require a buildconf run for those of you who use Unix. This has only really been tested on Solaris, but it should work for those platforms that have POSIX rw locks. Other Unix platforms will simply return APR_ENOTIMPL. Add apr_lock_acquire_rw(). Notice that the Unix implementation will only allow a readwrite lock to be acquired via this function. Technically, apr_lock_acquire could obtain some sort of readwrite lock in this case, but that might lead to confusion. Added test/testlock.c which will attempt to test *both* APR_MUTEX and APR_READWRITE. This was based off of the testthread.c, but has been rewritten to use the new stdin/stdout/stderr code and just make more sense overall. testthread.c should probably be rewritten to test threading more specifically. Added framework that will hopefully still let BeOS, OS/2, and Win32 compile. Any operation relating to an APR_READWRITE lock on these platforms should just return APR_ENOTIMPL until the appropriate people get around to it. Some structure has been added to make what they have to implement fairly obvious. Again, I hope it compiles, but I can't guarantee it. Christian Gross has a Win32 readwrite lock patch floating around, but I can't vouch for Win32 code. The other platforms probably have ways to do it, but I'm not sure what they are. (Sorry, I write long commit messages...) git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@61682 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'test/testlock.c')
-rw-r--r--test/testlock.c250
1 files changed, 250 insertions, 0 deletions
diff --git a/test/testlock.c b/test/testlock.c
new file mode 100644
index 000000000..6da1872d2
--- /dev/null
+++ b/test/testlock.c
@@ -0,0 +1,250 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+#include "apr_thread_proc.h"
+#include "apr_file_io.h"
+#include "apr_lock.h"
+#include "apr_errno.h"
+#include "apr_general.h"
+#include "errno.h"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef BEOS
+#include <unistd.h>
+#endif
+
+#if !APR_HAS_THREADS
+int main(void)
+{
+ fprintf(stderr,
+ "This program won't work on this platform because there is no "
+ "support for threads.\n");
+ return 0;
+}
+#else /* !APR_HAS_THREADS */
+
+#define MAX_ITER 40000
+
+void * APR_THREAD_FUNC thread_rw_func(void *data);
+void * APR_THREAD_FUNC thread_func(void *data);
+
+apr_file_t *in, *out, *err;
+apr_lock_t *thread_rw_lock, *thread_lock;
+apr_pool_t *context;
+int i = 0, x = 0;
+
+void * APR_THREAD_FUNC thread_rw_func(void *data)
+{
+ int exitLoop = 1;
+
+ while (1)
+ {
+ apr_lock_acquire_rw(thread_rw_lock, APR_READER);
+ if (i == MAX_ITER)
+ exitLoop = 0;
+ apr_lock_release(thread_rw_lock);
+
+ if (!exitLoop)
+ break;
+
+ apr_lock_acquire_rw(thread_rw_lock, APR_WRITER);
+ if (i != MAX_ITER)
+ {
+ i++;
+ x++;
+ }
+ apr_lock_release(thread_rw_lock);
+ }
+ return NULL;
+}
+
+void * APR_THREAD_FUNC thread_func(void *data)
+{
+ int exitLoop = 1;
+
+ while (1)
+ {
+ apr_lock_acquire(thread_lock);
+ if (i == MAX_ITER)
+ exitLoop = 0;
+ else
+ {
+ i++;
+ x++;
+ }
+ apr_lock_release(thread_lock);
+
+ if (!exitLoop)
+ break;
+ }
+ return NULL;
+}
+
+int test_rw(void)
+{
+ apr_thread_t *t1, *t2, *t3, *t4;
+ apr_status_t s1, s2, s3, s4;
+
+ apr_file_printf(out, "Initializing the rw lock.");
+ s1 = apr_lock_create(&thread_rw_lock, APR_READWRITE, APR_INTRAPROCESS,
+ "lock.file", context);
+ if (s1 != APR_SUCCESS) {
+ apr_file_printf(err, "Could not create lock\n");
+ return s1;
+ }
+ apr_file_printf(out, " OK\n");
+
+ i = 0;
+ x = 0;
+
+ apr_file_printf(out, "Starting all the threads.......");
+ s1 = apr_thread_create(&t1, NULL, thread_rw_func, NULL, context);
+ s2 = apr_thread_create(&t2, NULL, thread_rw_func, NULL, context);
+ s3 = apr_thread_create(&t3, NULL, thread_rw_func, NULL, context);
+ s4 = apr_thread_create(&t4, NULL, thread_rw_func, NULL, context);
+ if (s1 != APR_SUCCESS || s2 != APR_SUCCESS ||
+ s3 != APR_SUCCESS || s4 != APR_SUCCESS) {
+ apr_file_printf(err, "Error starting threads\n");
+ return s1;
+ }
+ apr_file_printf(out, "OK\n");
+
+ apr_file_printf(out, "Waiting for threads to exit.......");
+ apr_thread_join(&s1, t1);
+ apr_thread_join(&s2, t2);
+ apr_thread_join(&s3, t3);
+ apr_thread_join(&s4, t4);
+ apr_file_printf(out, "OK\n");
+
+ apr_file_printf(out, "OK\n");
+ if (x != MAX_ITER) {
+ apr_file_printf(err, "The locks didn't work???? %d\n", x);
+ }
+ else {
+ apr_file_printf(out, "Everything is working!\n");
+ }
+ return APR_SUCCESS;
+}
+
+int test_exclusive(void)
+{
+ apr_thread_t *t1, *t2, *t3, *t4;
+ apr_status_t s1, s2, s3, s4;
+
+ apr_file_printf(out, "Initializing the lock.");
+ s1 = apr_lock_create(&thread_lock, APR_MUTEX, APR_INTRAPROCESS,
+ "lock.file", context);
+
+ if (s1 != APR_SUCCESS) {
+ apr_file_printf(err, "Could not create lock\n");
+ return s1;
+ }
+ apr_file_printf(out, " OK\n");
+
+ i = 0;
+ x = 0;
+
+ apr_file_printf(out, "Starting all the threads.......");
+ s1 = apr_thread_create(&t1, NULL, thread_func, NULL, context);
+ s2 = apr_thread_create(&t2, NULL, thread_func, NULL, context);
+ s3 = apr_thread_create(&t3, NULL, thread_func, NULL, context);
+ s4 = apr_thread_create(&t4, NULL, thread_func, NULL, context);
+ if (s1 != APR_SUCCESS || s2 != APR_SUCCESS ||
+ s3 != APR_SUCCESS || s4 != APR_SUCCESS) {
+ apr_file_printf(err, "Error starting threads\n");
+ return s1;
+ }
+ apr_file_printf(out, "OK\n");
+
+ apr_file_printf(out, "Waiting for threads to exit.......");
+ apr_thread_join(&s1, t1);
+ apr_thread_join(&s2, t2);
+ apr_thread_join(&s3, t3);
+ apr_thread_join(&s4, t4);
+ apr_file_printf(out, "OK\n");
+
+ apr_file_printf(out, "OK\n");
+ if (x != MAX_ITER) {
+ apr_file_printf(err, "The locks didn't work???? %d\n", x);
+ }
+ else {
+ apr_file_printf(out, "Everything is working!\n");
+ }
+ return APR_SUCCESS;
+}
+
+int main(void)
+{
+ apr_initialize();
+ atexit(apr_terminate);
+
+ if (apr_pool_create(&context, NULL) != APR_SUCCESS)
+ exit(-1);
+
+ apr_file_open_stdin(&in, context);
+ apr_file_open_stdout(&out, context);
+ apr_file_open_stderr(&err, context);
+
+ apr_file_printf(out, "OK\n");
+
+ if (test_rw() != APR_SUCCESS)
+ exit(-2);
+
+ if (test_exclusive() != APR_SUCCESS)
+ exit(-3);
+
+ return 1;
+}
+
+#endif /* !APR_HAS_THREADS */