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}