aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Common/Logging/ThreadedLogger.cs
blob: f53b3d4260a89a175c24168a5b42115b883f490d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using System;
using System.Collections.Generic;
using System.Threading;

namespace MediaBrowser.Common.Logging
{
    public abstract class ThreadedLogger : BaseLogger
    {
        Thread loggingThread;
        Queue<Action> queue = new Queue<Action>();
        AutoResetEvent hasNewItems = new AutoResetEvent(false);
        volatile bool terminate = false;
        bool waiting = false;

        public ThreadedLogger()
            : base()
        {
            loggingThread = new Thread(new ThreadStart(ProcessQueue));
            loggingThread.IsBackground = true;
            loggingThread.Start();
        }


        void ProcessQueue()
        {
            while (!terminate)
            {
                waiting = true;
                hasNewItems.WaitOne(10000, true);
                waiting = false;

                Queue<Action> queueCopy;
                lock (queue)
                {
                    queueCopy = new Queue<Action>(queue);
                    queue.Clear();
                }

                foreach (var log in queueCopy)
                {
                    log();
                }
            }
        }

        protected override void LogEntry(LogRow row)
        {
            lock (queue)
            {
                queue.Enqueue(() => AsyncLogMessage(row));
            }
            hasNewItems.Set();
        }

        protected abstract void AsyncLogMessage(LogRow row);

        protected override void Flush()
        {
            while (!waiting)
            {
                Thread.Sleep(1);
            }
        }

        public override void Dispose()
        {
            Flush();
            terminate = true;
            hasNewItems.Set();
            base.Dispose();
        }
    }
}