Dispatcher.java
1 /* 2 * Copyright 1999,2005 The Apache Software Foundation. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.apache.log4j; 18 19 import org.apache.log4j.helpers.AppenderAttachableImpl; 20 import org.apache.log4j.spi.LoggingEvent; 21 22 23 /** 24 * Obsolete AsyncAppender dispatcher provided for compatibility only. 25 * 26 * @deprecated Since 1.3. 27 */ 28 class Dispatcher extends Thread { 29 /** 30 * @deprecated 31 */ 32 private org.apache.log4j.helpers.BoundedFIFO bf; 33 private AppenderAttachableImpl aai; 34 private boolean interrupted = false; 35 AsyncAppender container; 36 37 /** 38 * 39 * @param bf 40 * @param container 41 * @deprecated 42 */ 43 Dispatcher(org.apache.log4j.helpers.BoundedFIFO bf, AsyncAppender container) { 44 this.bf = bf; 45 this.container = container; 46 this.aai = container.aai; 47 48 // It is the user's responsibility to close appenders before 49 // exiting. 50 this.setDaemon(true); 51 52 // set the dispatcher priority to lowest possible value 53 this.setPriority(Thread.MIN_PRIORITY); 54 this.setName("Dispatcher-" + getName()); 55 56 // set the dispatcher priority to MIN_PRIORITY plus or minus 2 57 // depending on the direction of MIN to MAX_PRIORITY. 58 //+ (Thread.MAX_PRIORITY > Thread.MIN_PRIORITY ? 1 : -1)*2); 59 } 60 61 void close() { 62 synchronized (bf) { 63 interrupted = true; 64 65 // We have a waiting dispacther if and only if bf.length is 66 // zero. In that case, we need to give it a death kiss. 67 if (bf.length() == 0) { 68 bf.notify(); 69 } 70 } 71 } 72 73 /** 74 * The dispatching strategy is to wait until there are events in the buffer 75 * to process. After having processed an event, we release the monitor 76 * (variable bf) so that new events can be placed in the buffer, instead of 77 * keeping the monitor and processing the remaining events in the buffer. 78 * 79 * <p> 80 * Other approaches might yield better results. 81 * </p> 82 */ 83 public void run() { 84 //Category cat = Category.getInstance(Dispatcher.class.getName()); 85 LoggingEvent event; 86 87 while (true) { 88 synchronized (bf) { 89 if (bf.length() == 0) { 90 // Exit loop if interrupted but only if the the buffer is empty. 91 if (interrupted) { 92 //cat.info("Exiting."); 93 break; 94 } 95 96 try { 97 //LogLog.debug("Waiting for new event to dispatch."); 98 bf.wait(); 99 } catch (InterruptedException e) { 100 break; 101 } 102 } 103 104 event = bf.get(); 105 106 if (bf.wasFull()) { 107 //LogLog.debug("Notifying AsyncAppender about freed space."); 108 bf.notify(); 109 } 110 } 111 112 // synchronized 113 synchronized (container.aai) { 114 if ((aai != null) && (event != null)) { 115 aai.appendLoopOnAppenders(event); 116 } 117 } 118 } 119 120 // while 121 // close and remove all appenders 122 aai.removeAllAppenders(); 123 } 124 }