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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] #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 [EMAIL PROTECTED] #close} method.
   * This is guaranteed to be called only once, even if [EMAIL PROTECTED] 
#close} is
   * invoked more than once.
   * Note that further locking is not required, as [EMAIL PROTECTED] #append} 
can no
   * longer be called.
   */
  protected abstract void internalClose();




---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to