ceki 2003/05/27 13:18:57
Modified: tests/src/java/org/apache/log4j/helpers
ReaderWriterLockTestCase.java
Added: tests/src/java/org/apache/log4j/helpers VerifierThread.java
Log:
Developed a test case for the ReaderWriterLock which seems to work correctly.
The lock is not reeantrant for writers but that should not be a big problem.
Code was developed on my new portable PC!
Revision Changes Path
1.2 +75 -35
jakarta-log4j/tests/src/java/org/apache/log4j/helpers/ReaderWriterLockTestCase.java
Index: ReaderWriterLockTestCase.java
===================================================================
RCS file:
/home/cvs/jakarta-log4j/tests/src/java/org/apache/log4j/helpers/ReaderWriterLockTestCase.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ReaderWriterLockTestCase.java 24 May 2003 21:04:00 -0000 1.1
+++ ReaderWriterLockTestCase.java 27 May 2003 20:18:57 -0000 1.2
@@ -53,22 +53,36 @@
import junit.framework.TestCase;
import junit.framework.TestSuite;
-import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.LogManager;
-import org.apache.log4j.Logger;
-import org.apache.log4j.PatternLayout;
+
+import org.apache.oro.text.perl.Perl5Util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.PipedReader;
+import java.io.PipedWriter;
+import java.io.PrintWriter;
/**
- * @author Ceki
+ * This test checks the correctness of ReaderWriterLock.
+ *
+ * <b>Warning</b> This test should not use log4j loggers.
+ *
+ * There is not much point in having a test depend on the component being tested.
+ *
+ * @author Ceki Gülcü
*
- * To change the template for this generated type comment go to
- * Window>Preferences>Java>Code Generation>Code and Comments
*/
public class ReaderWriterLockTestCase extends TestCase {
double value1 = 0;
double value2 = 0;
ReaderWriterLock lock = new ReaderWriterLock();
+ BufferedReader bufferedReader;
+ PrintWriter printWriter;
+
+ static int WLOOP = 30000;
+ static int RLOOP = WLOOP*2;
/**
* Constructor for ReaderWriterLockTestCasae.
@@ -79,21 +93,26 @@
}
protected void setUp() throws Exception {
- System.out.println("=====================");
- Logger root = Logger.getRootLogger();
- root.addAppender(new ConsoleAppender(new PatternLayout("%4r [%t] - %m%n")));
+ PipedWriter pipedWriter = new PipedWriter();
+ PipedReader pipedReader = new PipedReader();
+ bufferedReader = new BufferedReader(pipedReader);
+ pipedReader.connect(pipedWriter);
+
+ //pipedWriter.connect(pipedReader);
+ printWriter = new PrintWriter(pipedWriter);
}
protected void tearDown() throws Exception {
- System.out.println("------------------------");
- LogManager.shutdown();
}
public void test1() {
- int maxReaders = 3;
- int maxWriters = 2;
+ int maxReaders = 30;
+ int maxWriters = 20;
Thread[] threads = new Thread[maxReaders + maxWriters];
+ VerifierThread vt = new VerifierThread(bufferedReader, maxReaders, maxWriters);
+ vt.start();
+
for (int i = 0; i < maxReaders; i++) {
threads[i] = new ReaderThread(i);
}
@@ -114,6 +133,15 @@
}
}
+ void printMessage(String msg) {
+ synchronized (printWriter) {
+ //printWriter.print("[");
+ printWriter.print(Thread.currentThread().getName());
+ printWriter.print(" ");
+ printWriter.println(msg);
+ }
+ }
+
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTest(new ReaderWriterLockTestCase("test1"));
@@ -123,48 +151,60 @@
class ReaderThread extends Thread {
ReaderThread(int i) {
- super("Reader-" + i);
+ super("R-" + i);
}
public void run() {
- Logger root = Logger.getRootLogger();
- root.debug("In run()");
+ printMessage("In run()");
- for (int l = 0; l < 150; l++) {
- root.debug("Asking for read lock.");
+ for (int l = 0; l < RLOOP; l++) {
+ printMessage("Asking for read lock.");
lock.getReadLock();
- root.debug("Got read lock.");
- root.debug("Value1 is " + value1);
- root.debug("Value2 is " + value2);
- try {sleep(10);} catch (InterruptedException e) {}
- root.debug("About to release read lock.");
+ printMessage("Got read lock.");
+ printMessage("Value1 is " + value1);
+ printMessage("Value2 is " + value2);
+
+ try {
+ sleep(10);
+ } catch (InterruptedException e) {
+ }
+
+ printMessage("About to release read lock.");
lock.releaseReadLock();
}
}
}
-
+
class WriterThread extends Thread {
WriterThread(int i) {
- super("WRITER-" + i);
+ super("W-" + i);
}
public void run() {
- Logger root = Logger.getRootLogger();
- root.debug("In run()");
+ printMessage("In run");
+
+ for (int i = 0; i < WLOOP; i++) {
+ try {
+ sleep(30);
+ } catch (InterruptedException e) {
+ }
- for (int l = 0; l < 50; l++) {
- try {sleep(30);} catch (InterruptedException e) {}
- root.debug("Asking for write lock.");
+ printMessage("Asking for write lock.");
lock.getWriteLock();
- root.debug("Got write lock.");
- root.debug("About to increment values.");
+ printMessage("Got write lock.");
+ printMessage("About to increment values.");
value1 += 1;
value2 += 10;
- try {sleep(10);} catch (InterruptedException e) {}
- root.debug("About to release write lock.");
- lock.releaseWriteLock();
+ try {
+ sleep(10);
+ } catch (InterruptedException e) {
+ }
+
+ printMessage("About to release write lock.");
+ lock.releaseWriteLock();
}
}
}
+
}
1.1
jakarta-log4j/tests/src/java/org/apache/log4j/helpers/VerifierThread.java
Index: VerifierThread.java
===================================================================
/*
* ============================================================================
* The Apache Software License, Version 1.1
* ============================================================================
*
* Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, 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 "log4j" 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
* [EMAIL PROTECTED]
*
* 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 (INCLU-
* DING, 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/>.
*
*/
package org.apache.log4j.helpers;
import org.apache.oro.text.perl.Perl5Util;
import java.io.BufferedReader;
import java.io.IOException;
/**
*
* @author Ceki Gülcü
*
*/
class VerifierThread extends Thread {
int writeLockHolder = -1;
boolean[] readLockHolders;
boolean[] readLockWaiters;
boolean[] writerLockWaiters;
BufferedReader bufferedReader;
VerifierThread(BufferedReader br, int numberOfReaders, int numberOfWriters) {
bufferedReader = br;
readLockHolders = new boolean[numberOfReaders];
readLockWaiters = new boolean[numberOfReaders];
writerLockWaiters = new boolean[numberOfWriters];
}
public void run() {
System.out.println("In run of VerifThread");
Perl5Util regex = new Perl5Util();
while (true) {
try {
String line = bufferedReader.readLine();
System.out.println(line);
if (regex.match("/([RW])-(\\d{1,2}) (.*)/", line)) {
String type = regex.group(1);
int num = Integer.parseInt(regex.group(2));
String msg = regex.group(3);
if (type.equals("R")) {
readerMsg(num, msg);
} else if (type.equals("W")) {
}
} else {
System.out.println(
"[" + line + "] does not match expected pattern.");
}
//System.out.println("."+type+"-"+num+" "+msg);
} catch (IOException e) {
}
}
}
void readerMsg(int num, String msg) {
if (msg.equals("Asking for read lock.")) {
askReadLock(num);
} else if (msg.equals("Got read lock.")) {
gotReadLock(num);
} else if (msg.startsWith("Value")) {
//releaseReadLock(num);
} else if (msg.equals("About to release read lock.")) {
releaseReadLock(num);
}
}
void writerMsg(int num, String msg) {
if (msg.equals("Asking for write lock.")) {
askWriterLock(num);
} else if (msg.equals("Got write lock.")) {
gotWriteLock(num);
} else if (msg.startsWith("Value")) {
//releaseReadLock(num);
} else if (msg.equals("About to release write lock.")) {
releaseWriteLock(num);
}
}
boolean writerHoldsLock() {
return writeLockHolder != -1;
}
boolean writerIsWaiting() {
for (int i = 0; i < writerLockWaiters.length; i++) {
if (writerLockWaiters[i]) {
return true;
}
}
return false;
}
void askReadLock(int num) {
readLockWaiters[num] = true;
}
void askWriterLock(int num) {
writerLockWaiters[num] = true;
}
void gotReadLock(int num) {
if (!readLockWaiters[num]) {
throw new IllegalStateException(
"Reader " + num + " got a lock without asking.");
}
if (writerHoldsLock()) {
throw new IllegalStateException(
"Reader " + num + " got a lock while a writer had it.");
}
if (writerIsWaiting()) {
throw new IllegalStateException(
"Reader " + num + " got a lock while a writers were waiting.");
}
readLockWaiters[num] = false;
readLockHolders[num] = true;
}
void gotWriteLock(int num) {
if (!writerLockWaiters[num]) {
throw new IllegalStateException(
"Writer " + num + " got a lock without asking.");
}
if (writerHoldsLock()) {
throw new IllegalStateException(
"Writer " + num + " got a lock while a writer had it.");
}
writerLockWaiters[num] = false;
writeLockHolder = num;
}
void releaseReadLock(int num) {
if (readLockWaiters[num]) {
throw new IllegalStateException(
"Reader " + num + " released a lock while waiting for it.");
}
if (writerHoldsLock()) {
throw new IllegalStateException(
"Reader " + num + " released a lock while a writer had it.");
}
readLockHolders[num] = false;
}
void releaseWriteLock(int num) {
if (writerLockWaiters[num]) {
throw new IllegalStateException(
"Writer " + num + " released a lock while waiting for it.");
}
writeLockHolder = -1;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]