Program: 75551
Project: 75551
Buggy source:
/** 
 * Obtain permission to read objects in the workspace. This method suspends the calling thread until such permission has been obtained.  Permission is granted unless either another thread has write permission, or there are threads that have requested write permission and not gotten it yet. If this thread already has a read permission, then another permission is granted irrespective of other write requests. It is essential that doneReading() be called after this, or write permission may never again be granted in this workspace. If the workspace is read-only, the calling thread will not suspend, and will just return immediately from the method call. The pairing between the getReadAccess() and doneReading() methods is not checked under this condition.
 */
public final synchronized void getReadAccess(){
  if (_readOnly) {
    return;
  }
  while (true) {
    Thread current=Thread.currentThread();
    if (current instanceof PtolemyThread) {
      PtolemyThread ptThread=(PtolemyThread)current;
      if (ptThread.readDepth != 0) {
        ptThread.readDepth++;
        return;
      }
 else {
        if (current == _writer || _writeReq == 0) {
          ptThread.readDepth++;
          _numPtReaders++;
          return;
        }
      }
    }
 else {
      ReadDepth depth=(ReadDepth)_readers.get(current);
      if (depth != null) {
        depth.incr();
        return;
      }
 else {
        if (current == _writer || _writeReq == 0) {
          if (depth == null) {
            depth=new ReadDepth();
            _readers.put(current,depth);
          }
          depth.incr();
          return;
        }
      }
    }
    wait(this);
  }
}

Fixed version (ground truth):
/** 
 * Obtain permission to read objects in the workspace. This method suspends the calling thread until such permission has been obtained.  Permission is granted unless either another thread has write permission, or there are threads that have requested write permission and not gotten it yet. If this thread already has a read permission, then another permission is granted irrespective of other write requests. It is essential that doneReading() be called after this, or write permission may never again be granted in this workspace. If the workspace is read-only, the calling thread will not suspend, and will just return immediately from the method call. The pairing between the getReadAccess() and doneReading() methods is not checked under this condition.
 */
public final synchronized void getReadAccess(){
  if (_readOnly) {
    return;
  }
  Thread current=Thread.currentThread();
  while (true) {
    if (current instanceof PtolemyThread) {
      PtolemyThread ptThread=(PtolemyThread)current;
      if (ptThread.readDepth != 0) {
        ptThread.readDepth++;
        return;
      }
 else {
        if (current == _writer || _writeReq == 0) {
          ptThread.readDepth++;
          _numPtReaders++;
          return;
        }
      }
    }
 else {
      ReadDepth depth=(ReadDepth)_readers.get(current);
      if (depth != null) {
        depth.incr();
        return;
      }
 else {
        if (current == _writer || _writeReq == 0) {
          depth=new ReadDepth();
          _readers.put(current,depth);
          depth.incr();
          return;
        }
      }
    }
    wait(this);
  }
}