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 <[email protected]>
Authored: Sun Mar 26 22:25:56 2017 -0700
Committer: Dominik Psenner <[email protected]>
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

Reply via email to