import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.sql.Timestamp;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.logging.ErrorManager;
import java.util.logging.Filter;
import java.util.logging.Formatter;
* The PrintWriter to which we are currently logging, if any.
*/
private volatile PrintWriter writer = null;
-
+
+
+ /**
+ * Lock used to control access to the writer.
+ */
+ protected ReadWriteLock writerLock = new ReentrantReadWriteLock();
+
+
/**
- * Log buffer size
+ * Log buffer size.
*/
private int bufferSize = -1;
String tsString = ts.toString().substring(0, 19);
String tsDate = tsString.substring(0, 10);
+ writerLock.readLock().lock();
// If the date has changed, switch log files
if (!date.equals(tsDate)) {
- synchronized (this) {
- if (!date.equals(tsDate)) {
- closeWriter();
- date = tsDate;
- openWriter();
- }
- }
+ // Update to writeLock before we switch
+ writerLock.readLock().unlock();
+ writerLock.writeLock().lock();
+ // Make sure another thread hasn't already done this
+ if (!date.equals(tsDate)) {
+ closeWriter();
+ date = tsDate;
+ openWriter();
+ }
+ // Down grade to read-lock. This ensures the writer remains valid
+ // until the log message is written
+ writerLock.readLock().lock();
+ writerLock.writeLock().unlock();
}
String result = null;
result = getFormatter().format(record);
} catch (Exception e) {
reportError(null, e, ErrorManager.FORMAT_FAILURE);
+ writerLock.readLock().unlock();
return;
}
try {
- PrintWriter writer = this.writer;
if (writer!=null) {
writer.write(result);
if (bufferSize < 0) {
} catch (Exception e) {
reportError(null, e, ErrorManager.WRITE_FAILURE);
return;
+ } finally {
+ writerLock.readLock().unlock();
}
-
}
protected void closeWriter() {
try {
- PrintWriter writer = this.writer;
- this.writer = null;
+ writerLock.writeLock().lock();
if (writer == null)
return;
writer.write(getFormatter().getTail(this));
date = "";
} catch (Exception e) {
reportError(null, e, ErrorManager.CLOSE_FAILURE);
+ } finally {
+ writerLock.writeLock().unlock();
}
-
}
public void flush() {
try {
- PrintWriter writer = this.writer;
- if (writer==null)
+ writerLock.readLock().lock();
+ if (writer == null)
return;
writer.flush();
} catch (Exception e) {
reportError(null, e, ErrorManager.FLUSH_FAILURE);
+ } finally {
+ writerLock.readLock().unlock();
}
}
String encoding = getEncoding();
FileOutputStream fos = new FileOutputStream(pathname, true);
OutputStream os = bufferSize>0?new BufferedOutputStream(fos,bufferSize):fos;
+ writerLock.writeLock().lock();
writer = new PrintWriter(
(encoding != null) ? new OutputStreamWriter(os, encoding)
: new OutputStreamWriter(os), false);
} catch (Exception e) {
reportError(null, e, ErrorManager.OPEN_FAILURE);
writer = null;
+ } finally {
+ writerLock.writeLock().unlock();
}
}