package com.mwc.util;

/**
 * Used to synchronize access to the database.
 * @author Matthew W. Coan
 * Dec. 19, 2000
 */
public class ReadWriteLock {
   private int _readersReading;
   private int _writerWriting;
   
   /**
    * Constructor dose the init.
    */
   public ReadWriteLock() {
      _writerWriting = _readersReading = 0;
   }

   /**
    * Get a lock for reading.
    */
   public void readLock() {
      synchronized(this) {
         while(_writerWriting != 0) {
            try {
               wait();
            }
            catch(InterruptedException ie) { 
            }
         }
         _readersReading++;
      }
   }

   /**
    * Get a lock for writing.
    */
   public void writeLock() {
      synchronized(this) {
         while(_writerWriting != 0 || _readersReading != 0) {
            try {
               wait();
            }
            catch(InterruptedException ie) { 
            }
         }
         _writerWriting++;
      }
   }

   /**
    * Give up a lock for reading.
    * @return -1 on error, else zero.
    */
   public int readUnlock() {
      synchronized(this) {
         if(_readersReading == 0)
            return -1;
         else {
            _readersReading--;
            if(_readersReading == 0)
               notify();
         }
      }
      return 0;
   }

   /**
    * Give up a lock for writing.
    * @return -1 on error, else zero.
    */
   public int writeUnlock() {
      synchronized(this) {
         if(_writerWriting == 0)
            return -1;
         else {
            _writerWriting = 0;
            notifyAll();
         }
      }
      return 0;
   }
}