Author: dpsenner Date: Sun Nov 1 18:52:25 2015 New Revision: 1711838 URL: http://svn.apache.org/viewvc?rev=1711838&view=rev Log: LOG4NET-485: implemented a mutex that locks rolling across multiple processes on the same computer
However, this does not solve issues where multiple processes from different computers try to roll over files that are located on a network share. Modified: logging/log4net/trunk/src/Appender/RollingFileAppender.cs Modified: logging/log4net/trunk/src/Appender/RollingFileAppender.cs URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Appender/RollingFileAppender.cs?rev=1711838&r1=1711837&r2=1711838&view=diff ============================================================================== --- logging/log4net/trunk/src/Appender/RollingFileAppender.cs (original) +++ logging/log4net/trunk/src/Appender/RollingFileAppender.cs Sun Nov 1 18:52:25 2015 @@ -23,7 +23,8 @@ using System.Globalization; using System.IO; using log4net.Util; -using log4net.Core; +using log4net.Core; +using System.Threading; namespace log4net.Appender { @@ -233,6 +234,18 @@ namespace log4net.Appender /// </remarks> public RollingFileAppender() { + } + + /// <summary> + /// Cleans up all resources used by this appender. + /// </summary> + ~RollingFileAppender() + { + if (m_mutexForRolling != null) + { + m_mutexForRolling.Close(); + m_mutexForRolling = null; + } } #endregion Public Instance Constructors @@ -592,24 +605,41 @@ namespace log4net.Appender /// </remarks> virtual protected void AdjustFileBeforeAppend() { - if (m_rollDate) - { - DateTime n = m_dateTime.Now; - if (n >= m_nextCheck) - { - m_now = n; - m_nextCheck = NextCheckDate(m_now, m_rollPoint); - - RollOverTime(true); - } - } - - if (m_rollSize) - { - if ((File != null) && ((CountingQuietTextWriter)QuietWriter).Count >= m_maxFileSize) - { - RollOverSize(); - } + // reuse the file appenders locking model to lock the rolling + try + { + // if rolling should be locked, acquire the lock + if (m_mutexForRolling != null) + { + m_mutexForRolling.WaitOne(); + } + if (m_rollDate) + { + DateTime n = m_dateTime.Now; + if (n >= m_nextCheck) + { + m_now = n; + m_nextCheck = NextCheckDate(m_now, m_rollPoint); + + RollOverTime(true); + } + } + + if (m_rollSize) + { + if ((File != null) && ((CountingQuietTextWriter)QuietWriter).Count >= m_maxFileSize) + { + RollOverSize(); + } + } + } + finally + { + // if rolling should be locked, release the lock + if (m_mutexForRolling != null) + { + m_mutexForRolling.ReleaseMutex(); + } } } @@ -1115,8 +1145,11 @@ namespace log4net.Appender base.File = ConvertToFullPath(base.File.Trim()); // Store fully qualified base file name - m_baseFileName = base.File; - } + m_baseFileName = base.File; + } + + // initialize the mutex that is used to lock rolling + m_mutexForRolling = new Mutex(false, m_baseFileName.Replace("\\", "_").Replace(":", "_").Replace("/", "_")); if (m_rollDate && File != null && m_scheduledFilename == null) { @@ -1642,7 +1675,12 @@ namespace log4net.Appender /// <summary> /// FileName provided in configuration. Used for rolling properly /// </summary> - private string m_baseFileName; + private string m_baseFileName; + + /// <summary> + /// A mutex that is used to lock rolling of files. + /// </summary> + private Mutex m_mutexForRolling; #endregion Private Instance Fields