logging-log4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Elias Ross <er...@m-qube.com>
Subject Re: log4j 1.3 prioritized tasks
Date Mon, 09 Jan 2006 23:59:11 GMT
On Mon, 2006-01-09 at 14:47 -0800, Mark Womack wrote:
> 
> 
> My question before was if you were suggesting a different set of "fine
> grain" classes that co-exist with the current set of classes?

That was my preferred approach.  Adding "fine grained" locking to
AppenderSkeleton seems entirely impossible, without requiring users of
it to basically forgo "synchronized" blocks, in favor of a ReadWriteLock
block instead.

I guess you *could* sort of create something like

if (Thread.holdsLock(foo)) { 
  // use write lock
} else {
  // use read lock
}

in the "doAppend" and maintain compatibility, but "holdsLock" seems
little heavy-weight.


As an example of what code changes a user must make, for example, in the
new WriterAppender:

  /**
   * Close the underlying {@link java.io.Writer}.
   */
  protected void closeWriter() {
    getWriteLock();
    try {
      if (this.writer == null)
        return;
      try {
        // before closing we have to output the footer
        writeFooter();
        this.writer.close();
        this.writer = null;
      } catch (IOException e) {
        getLogger().error("Could not close writer for WriterAppener named "+name, e);
      }
    } finally {
      releaseWriteLock();
    }
  }

Original version:

  /**
   * Close the underlying {@link java.io.Writer}.
   * */
  protected /* synchronized */ void closeWriter() {
    if (this.writer != null) {
      try {
        // before closing we have to output out layout's footer
        writeFooter();
        this.writer.close();
        this.writer = null;
      } catch (IOException e) {
        getLogger().error("Could not close writer for WriterAppener named "+name, e);
      }
    }

  }

I also decided that "close", which is a common method for users to
override, and created a separate method.  Not sure what the consensus on
style is for making things safer for API users, but I prefer to make
methods like this "final":

  /**
   * Cleans up this appender.
   * Marked as <code>final</code> to prevent subclasses from accidentally
   * overriding and forgetting to call <code>super.close()</code> or obtain a
   * write lock.
   * Calls {@link #internalClose} when completed.
   * Implementation note:  Obtains a write lock before starting close.
   * Calling this method more than once does nothing.
   */
  public final void close() {
    boolean wasClosed;
    getWriteLock();
    try {
      wasClosed = closed.set(true);
    } finally {
      lock.releaseWriteLock();
    }

    if (!wasClosed)
      internalClose();
  }

  /**
   * Subclasses must implement their own close routines.
   * This method is called by the {@link #close} method.
   * This is guaranteed to be called only once, even if {@link #close} is
   * invoked more than once.
   * Note that further locking is not required, as {@link #append} can no
   * longer be called.
   */
  protected abstract void internalClose();




---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org


Mime
View raw message