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