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&uuml;lc&uuml;
    *
  - * 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&uuml;lc&uuml;
   *
   */
  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]

Reply via email to