ceki        2003/06/03 13:30:56

  Modified:    src/java/org/apache/log4j Category.java
  Log:
  
  Modified the Category implementation to use ReaderWrtierLock.
  
  Revision  Changes    Path
  1.74      +110 -74   jakarta-log4j/src/java/org/apache/log4j/Category.java
  
  Index: Category.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/Category.java,v
  retrieving revision 1.73
  retrieving revision 1.74
  diff -u -r1.73 -r1.74
  --- Category.java     22 May 2003 21:26:24 -0000      1.73
  +++ Category.java     3 Jun 2003 20:30:56 -0000       1.74
  @@ -65,6 +65,7 @@
   
   import org.apache.log4j.helpers.AppenderAttachableImpl;
   import org.apache.log4j.helpers.NullEnumeration;
  +import org.apache.log4j.helpers.ReaderWriterLock;
   import org.apache.log4j.spi.AppenderAttachable;
   import org.apache.log4j.spi.LoggerRepository;
   import org.apache.log4j.spi.LoggingEvent;
  @@ -78,7 +79,7 @@
    * <font color="#AA2222"><b>This class has been deprecated and replaced by the
    * [EMAIL PROTECTED] Logger}<em>subclass</em>.</b></font> It will be kept around to
    * preserve backward compatibility until mid 2003.
  - * 
  + *
    * <p>
    * <code>Logger</code> is a subclass of Category, i.e. it extends Category. In
    * other words, a logger <em>is</em> a category. Thus, all operations that
  @@ -87,7 +88,7 @@
    * Logger object. However, methods that previously accepted category objects
    * still continue to accept category objects.
    * </p>
  - * 
  + *
    * <p>
    * For example, the following are all legal and will work as expected.
    * <pre>
  @@ -97,17 +98,17 @@
    *  &nbsp;&nbsp;&nbsp;Logger logger = Logger.getLogger("foo.bar")
    *  </pre>
    * </p>
  - * 
  + *
    * <p>
    * The first form is deprecated and should be avoided.
    * </p>
  - * 
  + *
    * <p>
    * <b>There is absolutely no need for new client code to use or refer to the
    * <code>Category</code> class.</b> Whenever possible, please avoid referring
    * to it or using it.
    * </p>
  - * 
  + *
    * <p>
    * See the <a href="../../../../manual.html">short manual</a> for an
    * introduction on this class.
  @@ -150,6 +151,7 @@
      */
     protected volatile Category parent;
     protected ResourceBundle resourceBundle;
  +  protected ReaderWriterLock lock;
   
     // Categories need to know what Hierarchy they are in
     protected LoggerRepository repository;
  @@ -168,7 +170,7 @@
     /**
      * This constructor created a new <code>Category</code> instance and sets
      * its name.
  -   * 
  +   *
      * <p>
      * It is intended to be used by sub-classes only. You should not create
      * categories directly.
  @@ -178,30 +180,37 @@
      */
     protected Category(String name) {
       this.name = name;
  +    lock = new ReaderWriterLock();
     }
   
     /**
      * Add <code>newAppender</code> to the list of appenders of this Category
      * instance.
  -   * 
  +   *
      * <p>
      * If <code>newAppender</code> is already in the list of appenders, then it
      * won't be added again.
      * </p>
      */
  -  public synchronized void addAppender(Appender newAppender) {
  +  public void addAppender(Appender newAppender) {
  +    // BEGIN - WRITE LOCK
  +    lock.getWriteLock();
  +
       if (aai == null) {
         aai = new AppenderAttachableImpl();
       }
   
       aai.addAppender(newAppender);
  +    lock.releaseWriteLock();
  +
  +    //       END - WRITE LOCK
       repository.fireAddAppenderEvent((Logger) this, newAppender);
     }
   
     /**
      * If <code>assertion</code> parameter is <code>false</code>, then logs
      * <code>msg</code> as an [EMAIL PROTECTED] #error(Object) error} statement.
  -   * 
  +   *
      * <p>
      * The <code>assert</code> method has been renamed to <code>assertLog</code>
      * because <code>assert</code> is a language reserved word in JDK 1.4.
  @@ -221,7 +230,7 @@
     /**
      * Call the appenders in the hierrachy starting at <code>this</code>.  If no
      * appenders could be found, emit a warning.
  -   * 
  +   *
      * <p>
      * This method calls all the appenders inherited from the hierarchy
      * circumventing any evaluation of whether to log or not to log the
  @@ -234,16 +243,20 @@
       int writes = 0;
   
       for (Category c = this; c != null; c = c.parent) {
  -      // Protected against simultaneous call to addAppender, removeAppender,...
  -      synchronized (c) {
  +      try {
  +             // Protect against simultaneous writes operations such as 
  +               // addAppender, removeAppender,...
  +        c.lock.getReadLock();
  +
           if (c.aai != null) {
             writes += c.aai.appendLoopOnAppenders(event);
           }
  -
  -        if (!c.additive) {
  -          break;
  -        }
  -      }
  +          } finally {
  +                        c.lock.releaseReadLock();
  +                      }
  +       if (!c.additive) {
  +         break;
  +       }      
       }
   
       if (writes == 0) {
  @@ -257,7 +270,7 @@
      *
      * @since 1.0
      */
  -  synchronized void closeNestedAppenders() {
  +  void closeNestedAppenders() {
       Enumeration enum = this.getAllAppenders();
   
       if (enum != null) {
  @@ -273,7 +286,7 @@
   
     /**
      * Log a message object with the [EMAIL PROTECTED] Level#DEBUG DEBUG} level.
  -   * 
  +   *
      * <p>
      * This method first checks if this category is <code>DEBUG</code> enabled
      * by comparing the level of this category with the [EMAIL PROTECTED] Level#DEBUG
  @@ -284,7 +297,7 @@
      * also higher in the hierarchy depending on the value of the additivity
      * flag.
      * </p>
  -   * 
  +   *
      * <p>
      * <b>WARNING</b> Note that passing a [EMAIL PROTECTED] Throwable} to this method 
will
      * print the name of the <code>Throwable</code> but no stack trace. To
  @@ -307,7 +320,7 @@
     /**
      * Log a message object with the <code>DEBUG</code> level including the
      * stack trace of the [EMAIL PROTECTED] Throwable}<code>t</code> passed as 
parameter.
  -   * 
  +   *
      * <p>
      * See [EMAIL PROTECTED] #debug(Object)} form for more detailed information.
      * </p>
  @@ -327,7 +340,7 @@
   
     /**
      * Log a message object with the [EMAIL PROTECTED] Level#ERROR ERROR} Level.
  -   * 
  +   *
      * <p>
      * This method first checks if this category is <code>ERROR</code> enabled
      * by comparing the level of this category with [EMAIL PROTECTED] Level#ERROR 
ERROR}
  @@ -337,7 +350,7 @@
      * call all the registered appenders in this category and also higher in
      * the hierarchy depending on the value of the additivity flag.
      * </p>
  -   * 
  +   *
      * <p>
      * <b>WARNING</b> Note that passing a [EMAIL PROTECTED] Throwable} to this method 
will
      * print the name of the <code>Throwable</code> but no stack trace. To
  @@ -360,7 +373,7 @@
     /**
      * Log a message object with the <code>ERROR</code> level including the
      * stack trace of the [EMAIL PROTECTED] Throwable}<code>t</code> passed as 
parameter.
  -   * 
  +   *
      * <p>
      * See [EMAIL PROTECTED] #error(Object)} form for more detailed information.
      * </p>
  @@ -391,7 +404,7 @@
   
     /**
      * Log a message object with the [EMAIL PROTECTED] Level#FATAL FATAL} Level.
  -   * 
  +   *
      * <p>
      * This method first checks if this category is <code>FATAL</code> enabled
      * by comparing the level of this category with [EMAIL PROTECTED] Level#FATAL 
FATAL}
  @@ -401,7 +414,7 @@
      * call all the registered appenders in this category and also higher in
      * the hierarchy depending on the value of the additivity flag.
      * </p>
  -   * 
  +   *
      * <p>
      * <b>WARNING</b> Note that passing a [EMAIL PROTECTED] Throwable} to this method 
will
      * print the name of the Throwable but no stack trace. To print a stack
  @@ -423,7 +436,7 @@
     /**
      * Log a message object with the <code>FATAL</code> level including the
      * stack trace of the [EMAIL PROTECTED] Throwable}<code>t</code> passed as 
parameter.
  -   * 
  +   *
      * <p>
      * See [EMAIL PROTECTED] #fatal(Object)} for more detailed information.
      * </p>
  @@ -464,34 +477,41 @@
      *
      * @return Enumeration An enumeration of the appenders in this category.
      */
  -  public synchronized Enumeration getAllAppenders() {
  +  public Enumeration getAllAppenders() {
  +       Enumeration result;
  +     lock.getReadLock();
       if (aai == null) {
  -      return NullEnumeration.getInstance();
  +      result = NullEnumeration.getInstance();
       } else {
  -      return aai.getAllAppenders();
  +      result = aai.getAllAppenders();
       }
  +    return result;
     }
   
     /**
      * Look for the appender named as <code>name</code>.
  -   * 
  +   *
      * <p>
      * Return the appender with that name if in the list. Return
      * <code>null</code> otherwise.
      * </p>
      */
  -  public synchronized Appender getAppender(String name) {
  +  public Appender getAppender(String name) {
  +     lock.getReadLock();
       if ((aai == null) || (name == null)) {
         return null;
       }
  -
  -    return aai.getAppender(name);
  +     
  +       Appender appender = aai.getAppender(name);
  +       lock.releaseReadLock();
  +     
  +    return appender;
     }
   
     /**
      * Starting from this category, search the category hierarchy for a non-null
      * level and return it. Otherwise, return the level of the root category.
  -   * 
  +   *
      * <p>
      * The Category class is designed so that this method executes as quickly as
      * possible.
  @@ -523,7 +543,7 @@
     /**
      * Returns all the currently defined categories in the default hierarchy as
      * an [EMAIL PROTECTED] java.util.Enumeration Enumeration}.
  -   * 
  +   *
      * <p>
      * The root category is <em>not</em> included in the returned [EMAIL PROTECTED]
      * Enumeration}.
  @@ -604,7 +624,7 @@
     /**
      * Returns the parent of this category. Note that the parent of a given
      * category may change during the lifetime of the category.
  -   * 
  +   *
      * <p>
      * The root category will return <code>null</code>.
      * </p>
  @@ -633,12 +653,12 @@
   
     /**
      * Return the root of the default category hierrachy.
  -   * 
  +   *
      * <p>
      * The root category is always instantiated and available. It's name is
      * "root".
      * </p>
  -   * 
  +   *
      * <p>
      * Nevertheless, calling [EMAIL PROTECTED] #getInstance 
Category.getInstance("root")}
      * does not retrieve the root category but a category just under root named
  @@ -651,7 +671,7 @@
   
     /**
      * Return the <em>inherited</em>[EMAIL PROTECTED] ResourceBundle} for this 
category.
  -   * 
  +   *
      * <p>
      * This method walks the hierarchy to find the appropriate resource bundle.
      * It will return the resource bundle attached to the closest ancestor of
  @@ -676,7 +696,7 @@
      * Returns the string resource coresponding to <code>key</code> in this
      * category's inherited resource bundle. See also [EMAIL PROTECTED]
      * #getResourceBundle}.
  -   * 
  +   *
      * <p>
      * If the resource cannot be found, then an [EMAIL PROTECTED] #error error} 
message
      * will be logged complaining about the missing resource.
  @@ -706,7 +726,7 @@
   
     /**
      * Log a message object with the [EMAIL PROTECTED] Level#INFO INFO} Level.
  -   * 
  +   *
      * <p>
      * This method first checks if this category is <code>INFO</code> enabled by
      * comparing the level of this category with [EMAIL PROTECTED] Level#INFO INFO} 
Level.
  @@ -716,7 +736,7 @@
      * call all the registered appenders in this category and also higher in
      * the hierarchy depending on the value of the additivity flag.
      * </p>
  -   * 
  +   *
      * <p>
      * <b>WARNING</b> Note that passing a [EMAIL PROTECTED] Throwable} to this method 
will
      * print the name of the Throwable but no stack trace. To print a stack
  @@ -738,7 +758,7 @@
     /**
      * Log a message object with the <code>INFO</code> level including the stack
      * trace of the [EMAIL PROTECTED] Throwable}<code>t</code> passed as parameter.
  -   * 
  +   *
      * <p>
      * See [EMAIL PROTECTED] #info(Object)} for more detailed information.
      * </p>
  @@ -760,42 +780,49 @@
      * Is the appender passed as parameter attached to this category?
      */
     public boolean isAttached(Appender appender) {
  +     boolean result;
  +
  +    lock.getReadLock();
  +    
       if ((appender == null) || (aai == null)) {
  -      return false;
  +      result = false;
       } else {
  -      return aai.isAttached(appender);
  +      result = aai.isAttached(appender);
       }
  +    
  +    lock.releaseReadLock();
  +    return result;
     }
   
     /**
      * Check whether this category is enabled for the <code>DEBUG</code> Level.
  -   * 
  +   *
      * <p>
      * This function is intended to lessen the computational cost of disabled
      * log debug statements.
      * </p>
  -   * 
  +   *
      * <p>
      * For some <code>cat</code> Category object, when you write,
      * <pre>
      *      cat.debug("This is entry number: " + i );
      *  </pre>
      * </p>
  -   * 
  +   *
      * <p>
      * You incur the cost constructing the message, concatenatiion in this case,
      * regardless of whether the message is logged or not.
      * </p>
  -   * 
  +   *
      * <p>
      * If you are worried about speed, then you should write
      * <pre>
  -   *          if(cat.isDebugEnabled()) {
  -   *            cat.debug("This is entry number: " + i );
  -   *          }
  +   *          if(cat.isDebugEnabled()) {
  +   *            cat.debug("This is entry number: " + i );
  +   *          }
      *  </pre>
      * </p>
  -   * 
  +   *
      * <p>
      * This way you will not incur the cost of parameter construction if
      * debugging is disabled for <code>cat</code>. On the other hand, if the
  @@ -951,26 +978,32 @@
      * <p>Removed appenders are closed.</p>
      * <p>This is useful when re-reading configuration information.</p>
      */
  -  public synchronized void removeAllAppenders() {
  +  public void removeAllAppenders() {
  +    lock.getWriteLock();
  +    
       if (aai != null) {
         aai.removeAllAppenders();
         aai = null;
       }
  +    lock.releaseWriteLock();
     }
   
     /**
      * Remove the appender passed as parameter form the list of appenders.
  -   * 
  +   *
      * <p>Does <em>not</em> close the appender.</p>
  -   * 
  +   *
      * @since 0.8.2
      */
  -  public synchronized void removeAppender(Appender appender) {
  +  public void removeAppender(Appender appender) {
  +       lock.getWriteLock();
  +    
       if ((appender == null) || (aai == null)) {
  -      return;
  +      // Nothing to do
  +    } else {
  +             aai.removeAppender(appender);
       }
  -
  -    aai.removeAppender(appender);
  +    lock.releaseWriteLock();
     }
   
     /**
  @@ -981,12 +1014,15 @@
      *
      * @since 0.8.2
      */
  -  public synchronized void removeAppender(String name) {
  +  public void removeAppender(String name) {
  +       lock.getWriteLock();
  +       
       if ((name == null) || (aai == null)) {
  -      return;
  +      // nothing to do
  +    } else {
  +      aai.removeAppender(name);
       }
  -
  -    aai.removeAppender(name);
  +    lock.releaseWriteLock();
     }
   
     /**
  @@ -1011,12 +1047,12 @@
      * <code>Level.DEBUG</code>, <code>Level.INFO</code>,
      * <code>Level.WARN</code>, <code>Level.ERROR</code>,
      * <code>Level.FATAL</code> as a parameter, you need to case them as Level.
  -   * 
  +   *
      * <p>
      * As in
      * <pre> &nbsp;&nbsp;&nbsp;logger.setLevel((Level) Level.DEBUG); </pre>
      * </p>
  -   * 
  +   *
      * <p>
      * Null values are admitted.
      * </p>
  @@ -1027,7 +1063,7 @@
   
     /**
      * Set the level of this Category.
  -   * 
  +   *
      * <p>
      * Null values are admitted.
      * </p>
  @@ -1052,13 +1088,13 @@
     /**
      * Calling this method will <em>safely</em> close and remove all appenders
      * in all the categories including root contained in the default hierachy.
  -   * 
  +   *
      * <p>
      * Some appenders such as [EMAIL PROTECTED] org.apache.log4j.net.SocketAppender} 
and
      * [EMAIL PROTECTED] AsyncAppender} need to be closed before the application 
exists.
      * Otherwise, pending logging events might be lost.
      * </p>
  -   * 
  +   *
      * <p>
      * The <code>shutdown</code> method is careful to close nested appenders
      * before closing regular appenders. This is allows configurations where a
  @@ -1075,7 +1111,7 @@
   
     /**
      * Log a message object with the [EMAIL PROTECTED] Level#WARN WARN} Level.
  -   * 
  +   *
      * <p>
      * This method first checks if this category is <code>WARN</code> enabled by
      * comparing the level of this category with [EMAIL PROTECTED] Level#WARN WARN} 
Level.
  @@ -1085,13 +1121,13 @@
      * call all the registered appenders in this category and also higher in
      * the hieararchy depending on the value of the additivity flag.
      * </p>
  -   * 
  +   *
      * <p>
      * <b>WARNING</b> Note that passing a [EMAIL PROTECTED] Throwable} to this method 
will
      * print the name of the Throwable but no stack trace. To print a stack
      * trace use the [EMAIL PROTECTED] #warn(Object, Throwable)} form instead.
      * </p>
  -   * 
  +   *
      * <p></p>
      *
      * @param message the message object to log.
  @@ -1109,7 +1145,7 @@
     /**
      * Log a message with the <code>WARN</code> level including the stack trace
      * of the [EMAIL PROTECTED] Throwable}<code>t</code> passed as parameter.
  -   * 
  +   *
      * <p>
      * See [EMAIL PROTECTED] #warn(Object)} for more detailed information.
      * </p>
  
  
  

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

Reply via email to