private void TryArchiveFile(string fileName, LogEventInfo ev, int upcomingWriteSize)
{
string archiveFile = string.Empty;
try
{
#if !SILVERLIGHT && !__IOS__ && !__ANDROID__
this.fileAppenderCache.InvalidateAppendersForInvalidFiles();
#endif
archiveFile = this.GetArchiveFileName(fileName, ev, upcomingWriteSize);
if (!string.IsNullOrEmpty(archiveFile))
{
// Close possible stale file handles, before doing extra check
if (archiveFile != fileName)
this.fileAppenderCache.InvalidateAppender(fileName);
this.fileAppenderCache.InvalidateAppender(archiveFile);
}
}
catch (Exception exception)
{
InternalLogger.Warn(exception, "Failed to check archive for file '{0}'.", fileName);
if (exception.MustBeRethrown())
{
throw;
}
}
if (!string.IsNullOrEmpty(archiveFile))
{
#if SupportsMutex
Mutex archiveMutex = this.fileAppenderCache.GetArchiveMutex(fileName);
try
{
if (archiveMutex != null)
archiveMutex.WaitOne();
}
catch (AbandonedMutexException)
{
// ignore the exception, another process was killed without properly releasing the mutex
// the mutex has been acquired, so proceed to writing
// See: http://msdn.microsoft.com/en-us/library/system.threading.abandonedmutexexception.aspx
}
#endif
try
{
// Check again if archive is needed. We could have been raced by another process
var validatedArchiveFile = this.GetArchiveFileName(fileName, ev, upcomingWriteSize);
if (string.IsNullOrEmpty(validatedArchiveFile))
{
if (archiveFile != fileName)
this.initializedFiles.Remove(fileName);
this.initializedFiles.Remove(archiveFile);
return;
}
archiveFile = validatedArchiveFile;
this.DoAutoArchive(archiveFile, ev);
}
catch (Exception exception)
{
InternalLogger.Warn(exception, "Failed to archive file '{0}'.", archiveFile);
if (exception.MustBeRethrown())
{
throw;
}
}
finally
{
#if SupportsMutex
if (archiveMutex != null)
archiveMutex.ReleaseMutex();
#endif
}
}
}