Esempio n. 1
0
  // Obtain permissions to read objects in the workspace. This obtains
  // many permissions on the read access and should be called in
  // conjunction with _releaseAllReadPermissions.
  // 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.
  // @param count This is the number of read permissions desired on the
  //  workspace.
  // @exception InternalErrorException If the calling thread is interrupted
  //  while waiting to re-acquire read permissions.
  private synchronized void _reacquireReadPermissions(int count) {
    // If the count argument is equal to zero, which means we would like
    // the current thread to has read depth equal to 0, i.e. not a reader,
    // then it's already trivially done, since this method call is always
    // preceded by _releaseAllReadPermissions.
    if (count == 0) {
      return;
    }

    Thread current = Thread.currentThread();
    AccessRecord record = null;

    if (current == _lastReader) {
      record = _lastReaderRecord;
    } else {
      record = _getAccessRecord(current, false);
    }

    if ((record == null) || (count > record.failedReadAttempts)) {
      throw new InvalidStateException(
          this, "Trying to reacquire " + "read permission not in record.");
    }

    // Go into an infinite 'while (true)' loop, and each time through
    // the loop, check if the condition is satisfied to have the current
    // thread as a writer. If not, then wait on the workspace. Upon
    // re-awakening, iterate in the loop again to check if the condition
    // is now satisfied.
    while (true) {
      // If the current thread has write permission, or if there
      // are no pending write requests, then grant read permission.
      if ((current == _writer) || ((_waitingWriteRequests == 0) && (_writer == null))) {
        _numReaders++;
        record.failedReadAttempts -= count;
        record.readDepth = count;
        return;
      }

      try {
        wait();
      } catch (InterruptedException ex) {
        throw new InternalErrorException(
            "Thread interrupted while waiting for read access!" + ex.getMessage());
      }
    }
  }
Esempio n. 2
0
  /**
   * Frees the thread of all the readAccesses on the workspace. The method _reacquireAllReadAccesses
   * should be called after this method is called.
   *
   * @return The number of readAccess that the thread possessed on the workspace
   */
  private synchronized int _releaseAllReadPermissions() {
    // Find the current thread.
    Thread current = Thread.currentThread();
    AccessRecord record = null;

    if (current == _lastReader) {
      record = _lastReaderRecord;
    } else {
      record = _getAccessRecord(current, false);
    }

    if ((record == null) || (record.readDepth == 0)) {
      // current thread is not a reader
      return 0;
    } else {
      _numReaders--;
      notifyAll();

      int result = record.readDepth;
      record.failedReadAttempts += result;
      record.readDepth = 0;
      return result;
    }
  }