001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.log4j;
019
020import org.apache.log4j.helpers.AppenderAttachableImpl;
021import org.apache.log4j.spi.LoggingEvent;
022
023
024/**
025 * Obsolete AsyncAppender dispatcher provided for compatibility only.
026 *
027 * @deprecated Since 1.3.
028 */
029class Dispatcher extends Thread {
030    /**
031     * @deprecated
032     */
033  private org.apache.log4j.helpers.BoundedFIFO bf;
034  private AppenderAttachableImpl aai;
035  private boolean interrupted = false;
036  AsyncAppender container;
037
038    /**
039     *
040     * @param bf
041     * @param container
042     * @deprecated
043     */
044  Dispatcher(org.apache.log4j.helpers.BoundedFIFO bf, AsyncAppender container) {
045    this.bf = bf;
046    this.container = container;
047    this.aai = container.aai;
048
049    // It is the user's responsibility to close appenders before
050    // exiting.
051    this.setDaemon(true);
052
053    // set the dispatcher priority to lowest possible value
054    this.setPriority(Thread.MIN_PRIORITY);
055    this.setName("Dispatcher-" + getName());
056
057    // set the dispatcher priority to MIN_PRIORITY plus or minus 2
058    // depending on the direction of MIN to MAX_PRIORITY.
059    //+ (Thread.MAX_PRIORITY > Thread.MIN_PRIORITY ? 1 : -1)*2);
060  }
061
062  void close() {
063    synchronized (bf) {
064      interrupted = true;
065
066      // We have a waiting dispacther if and only if bf.length is
067      // zero.  In that case, we need to give it a death kiss.
068      if (bf.length() == 0) {
069        bf.notify();
070      }
071    }
072  }
073
074  /**
075   * The dispatching strategy is to wait until there are events in the buffer
076   * to process. After having processed an event, we release the monitor
077   * (variable bf) so that new events can be placed in the buffer, instead of
078   * keeping the monitor and processing the remaining events in the buffer.
079   *
080   * <p>
081   * Other approaches might yield better results.
082   * </p>
083   */
084  public void run() {
085    //Category cat = Category.getInstance(Dispatcher.class.getName());
086    LoggingEvent event;
087
088    while (true) {
089      synchronized (bf) {
090        if (bf.length() == 0) {
091          // Exit loop if interrupted but only if the the buffer is empty.
092          if (interrupted) {
093            //cat.info("Exiting.");
094            break;
095          }
096
097          try {
098            //LogLog.debug("Waiting for new event to dispatch.");
099            bf.wait();
100          } catch (InterruptedException e) {
101            break;
102          }
103        }
104
105        event = bf.get();
106
107        if (bf.wasFull()) {
108          //LogLog.debug("Notifying AsyncAppender about freed space.");
109          bf.notify();
110        }
111      }
112
113      // synchronized
114      synchronized (container.aai) {
115        if ((aai != null) && (event != null)) {
116          aai.appendLoopOnAppenders(event);
117        }
118      }
119    }
120
121    // while
122    // close and remove all appenders
123    aai.removeAllAppenders();
124  }
125}