You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by dp...@apache.org on 2017/06/22 20:47:55 UTC

[07/10] logging-log4net git commit: Fixed worker thread logic and optimized code.

Fixed worker thread logic and optimized code.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4net/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4net/commit/a847990c
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4net/tree/a847990c
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4net/diff/a847990c

Branch: refs/heads/pr/old/40
Commit: a847990ce9a71a4168cddaca8a47b23f5e7c77d2
Parents: 897ef68
Author: Harry Martyrossian <HM...@users.noreply.github.com>
Authored: Sun Mar 26 22:25:56 2017 -0700
Committer: Dominik Psenner <dp...@apache.org>
Committed: Thu Jun 22 22:37:28 2017 +0200

----------------------------------------------------------------------
 src/Util/ParallelIAppender.cs | 78 +++++++++++++++++++++++++-------------
 1 file changed, 52 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/a847990c/src/Util/ParallelIAppender.cs
----------------------------------------------------------------------
diff --git a/src/Util/ParallelIAppender.cs b/src/Util/ParallelIAppender.cs
index 81b3860..e43ef4f 100644
--- a/src/Util/ParallelIAppender.cs
+++ b/src/Util/ParallelIAppender.cs
@@ -1,4 +1,4 @@
-#region Apache License
+#region Apache License
 //
 // Licensed to the Apache Software Foundation (ASF) under one or more 
 // contributor license agreements. See the NOTICE file distributed with
@@ -19,15 +19,15 @@
 
 #if (NET_4_5 && PARALLEL_APPENDERS)
 
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
-using log4net.Appender;
-using log4net.Core;
-
 namespace log4net.Util
 {
+	using System;
+	using System.Collections.Generic;
+	using System.Threading;
+
+	using log4net.Appender;
+	using log4net.Core;
+
 	/// <summary>
 	/// This class allows AppenderAttachedImpl class to call appenders in "parallel".
 	/// </summary>
@@ -43,14 +43,20 @@ namespace log4net.Util
 	public class ParallelIAppender : IAppender
 	{
 		private static readonly Type declaringType = typeof(ParallelIAppender);
+
 		private IAppender appender;
+
 		private object synchObject = new object();
+		private AutoResetEvent synchEvent = new AutoResetEvent(false);
 		private PulseCode pulseCode = PulseCode.NotSignaled;
+
 		private Queue<LoggingEvent> events = new Queue<LoggingEvent>();
 		private LoggingEvent[] arrayOfEvents;
-		private Task appenderTask;
+
+		private Thread appenderThread;
 
 		#region Public Instance Constructors
+
 		/// <summary>
 		/// Constructor
 		/// </summary>
@@ -59,22 +65,29 @@ namespace log4net.Util
 		/// Initializes a new instance of the <see cref="ParallelIAppender"/> class.
 		/// </para>
 		/// </remarks>
+
 		public ParallelIAppender(IAppender appender)
 		{
 			this.appender = appender;
-			this.appenderTask = Task.Run(() => this.Append());
+
+			this.appenderThread = new Thread(this.Append);
+			this.appenderThread.IsBackground = false;
+			this.appenderThread.Name = string.Format("{0}-{1}", appender.Name, Guid.NewGuid().ToString("N"));
+
+			this.appenderThread.Start();
 		}
+
 		#endregion Public Instance Constructors
 
 		[Flags]
 		internal enum PulseCode : int
 		{
-			NotSignaled,
-			QueueIsNotEmpty,
+			NotSignaled = 0,
 			ExitThread
 		}
 
 		#region Override implementation of Object
+
 		/// <summary>
 		/// Determines whether two <see cref="ParallelIAppender" /> instances 
 		/// are equal.
@@ -111,6 +124,7 @@ namespace log4net.Util
 			{
 				return false;
 			}
+
 			return this.appender.Equals(obj);
 		}
 
@@ -131,15 +145,18 @@ namespace log4net.Util
 		{
 			return this.appender.GetHashCode();
 		}
+
 		#endregion Override implementation of Object
 
 		#region Implementation of IAppender
+
 		string IAppender.Name
 		{
 			get
 			{
 				return this.appender.Name;
 			}
+
 			set
 			{
 				this.appender.Name = value;
@@ -151,9 +168,13 @@ namespace log4net.Util
 			lock (this.synchObject)
 			{
 				this.pulseCode |= PulseCode.ExitThread;
-				Monitor.Pulse(this.synchObject);
+
+				// This call will put Append() thread to the scheduling state:
+				this.synchEvent.Set();
 			}
-			this.appenderTask.Wait();
+
+			this.appenderThread.Join();
+
 			this.appender.Close();
 		}
 
@@ -162,34 +183,38 @@ namespace log4net.Util
 			lock (this.synchObject)
 			{
 				this.events.Enqueue(loggingEvent);
-				this.pulseCode |= PulseCode.QueueIsNotEmpty;
-				Monitor.Pulse(this.synchObject);
+
+				// This call will put Append() thread to the scheduling state:
+				this.synchEvent.Set();
 			}
 		}
+
 		#endregion Implementation of IAppender
 
 		private void Append()
 		{
+			// Have to keep this thread running till log4net shutdown:
 			bool keepRunning = true;
+
 			do
 			{
+				// Have to wait for the data to be queued by log4net:
+				this.synchEvent.WaitOne();
+
 				lock (this.synchObject)
 				{
-					if (this.pulseCode == PulseCode.NotSignaled)
-					{
-						Monitor.Wait(this.synchObject);
-					}
-					if ((this.pulseCode & PulseCode.QueueIsNotEmpty) == PulseCode.QueueIsNotEmpty)
-					{
-						this.pulseCode ^= PulseCode.QueueIsNotEmpty;
-					}
+					this.CopyEvents();
+
 					if ((this.pulseCode & PulseCode.ExitThread) == PulseCode.ExitThread)
 					{
-						this.pulseCode ^= PulseCode.ExitThread;
+						// Setting keepRunning to <false> will exit the thread function:
 						keepRunning = false;
+
+						// Clean up:
+						this.pulseCode ^= PulseCode.ExitThread;
 					}
-					this.CopyEvents();
 				}
+
 				this.CallDoAppend();
 			}
 			while (keepRunning);
@@ -211,4 +236,5 @@ namespace log4net.Util
 		}
 	}
 }
+
 #endif