jt
2021-06-10 5d0d028456874576560552f5a5c4e8b801786f11
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#region Apache License
//
// Licensed to the Apache Software Foundation (ASF) under one or more 
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership. 
// The ASF licenses this file to you under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with 
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion
 
#if (!NETCF)
#define HAS_READERWRITERLOCK
#endif
 
using System;
 
namespace log4net.Util
{
    /// <summary>
    /// Defines a lock that supports single writers and multiple readers
    /// </summary>
    /// <remarks>
    /// <para>
    /// <c>ReaderWriterLock</c> is used to synchronize access to a resource. 
    /// At any given time, it allows either concurrent read access for 
    /// multiple threads, or write access for a single thread. In a 
    /// situation where a resource is changed infrequently, a 
    /// <c>ReaderWriterLock</c> provides better throughput than a simple 
    /// one-at-a-time lock, such as <see cref="System.Threading.Monitor"/>.
    /// </para>
    /// <para>
    /// If a platform does not support a <c>System.Threading.ReaderWriterLock</c> 
    /// implementation then all readers and writers are serialized. Therefore 
    /// the caller must not rely on multiple simultaneous readers.
    /// </para>
    /// </remarks>
    /// <author>Nicko Cadell</author>
    public sealed class ReaderWriterLock
    {
        #region Instance Constructors
 
        /// <summary>
        /// Constructor
        /// </summary>
        /// <remarks>
        /// <para>
        /// Initializes a new instance of the <see cref="ReaderWriterLock" /> class.
        /// </para>
        /// </remarks>
        public ReaderWriterLock()
        {
#if HAS_READERWRITERLOCK
            m_lock = new System.Threading.ReaderWriterLock();
#endif
        }
 
        #endregion Private Instance Constructors
  
        #region Public Methods
 
        /// <summary>
        /// Acquires a reader lock
        /// </summary>
        /// <remarks>
        /// <para>
        /// <see cref="AcquireReaderLock"/> blocks if a different thread has the writer 
        /// lock, or if at least one thread is waiting for the writer lock.
        /// </para>
        /// </remarks>
        public void AcquireReaderLock()
        {
#if HAS_READERWRITERLOCK
            m_lock.AcquireReaderLock(-1);
#else
            System.Threading.Monitor.Enter(this);
#endif
        }
 
        /// <summary>
        /// Decrements the lock count
        /// </summary>
        /// <remarks>
        /// <para>
        /// <see cref="ReleaseReaderLock"/> decrements the lock count. When the count 
        /// reaches zero, the lock is released.
        /// </para>
        /// </remarks>
        public void ReleaseReaderLock()
        {
#if HAS_READERWRITERLOCK
            m_lock.ReleaseReaderLock();
#else
            System.Threading.Monitor.Exit(this);
#endif
        }
 
        /// <summary>
        /// Acquires the writer lock
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method blocks if another thread has a reader lock or writer lock.
        /// </para>
        /// </remarks>
        public void AcquireWriterLock()
        {
#if HAS_READERWRITERLOCK
            m_lock.AcquireWriterLock(-1);
#else
            System.Threading.Monitor.Enter(this);
#endif
        }
 
        /// <summary>
        /// Decrements the lock count on the writer lock
        /// </summary>
        /// <remarks>
        /// <para>
        /// ReleaseWriterLock decrements the writer lock count. 
        /// When the count reaches zero, the writer lock is released.
        /// </para>
        /// </remarks>
        public void ReleaseWriterLock()
        {
#if HAS_READERWRITERLOCK
            m_lock.ReleaseWriterLock();
#else
            System.Threading.Monitor.Exit(this);
#endif
        }
 
        #endregion Public Methods
 
        #region Private Members
 
#if HAS_READERWRITERLOCK
        private System.Threading.ReaderWriterLock m_lock;
#endif
 
        #endregion
    }
}