Showing the changes to Source/Libraries/GSF.Core/Threading/InterprocessReaderWriterLock.cs (1 of 14 files). Show all
Unified · Split
| @@ -29,7 +29,7 @@ using System.Threading; · 28 unmodified lines | ||
| 29 | 29 | namespace GSF.Threading |
| 30 | 30 | { |
| 31 | 31 | /// <summary> |
| 32 | − /// Represents an interprocess reader/writer lock using <see cref="Semaphore"/> and <see cref="Mutex"/> native locking mechanisms. | |
| 32 | + /// Represents an inter-process reader/writer lock using <see cref="Semaphore"/> and <see cref="Mutex"/> native locking mechanisms. | |
| 33 | 33 | /// </summary> |
| 34 | 34 | public class InterprocessReaderWriterLock : IDisposable |
| 35 | 35 | { |
| @@ -43,9 +43,9 @@ namespace GSF.Threading · 7 unmodified lines | ||
| 43 | 43 | public const int DefaultMaximumConcurrentLocks = 10; |
| 44 | 44 | |
| 45 | 45 | // Fields |
| 46 | − private Mutex m_semaphoreLock; // Mutex used to synchronize access to Semaphore | |
| 47 | − private Semaphore m_concurrencyLock; // Semaphore used for reader/writer lock on consumer object | |
| 48 | − private readonly int m_maximumConcurrentLocks; | |
| 46 | + private Mutex m_semaphoreLock; // Mutex used to synchronize access to Semaphore | |
| 47 | + private Semaphore m_concurrencyLock; // Semaphore used for reader/writer lock on consumer object | |
| 48 | + private readonly int m_maximumConcurrentLocks; // Maximum number of concurrent locks before waiting | |
| 49 | 49 | private bool m_disposed; |
| 50 | 50 | |
| 51 | 51 | #endregion |
| @@ -56,7 +56,7 @@ namespace GSF.Threading · 4 unmodified lines | ||
| 56 | 56 | /// Creates a new instance of the <see cref="InterprocessReaderWriterLock"/> associated with the specified |
| 57 | 57 | /// <paramref name="name"/> that identifies a source object needing concurrency locking. |
| 58 | 58 | /// </summary> |
| 59 | − /// <param name="name">Identifiying name of source object needing concurrency locking (e.g., a path and file name).</param> | |
| 59 | + /// <param name="name">Identifying name of source object needing concurrency locking (e.g., a path and file name).</param> | |
| 60 | 60 | public InterprocessReaderWriterLock(string name) |
| 61 | 61 | : this(name, DefaultMaximumConcurrentLocks) |
| 62 | 62 | { |
| @@ -66,7 +66,7 @@ namespace GSF.Threading · 3 unmodified lines | ||
| 66 | 66 | /// Creates a new instance of the <see cref="InterprocessReaderWriterLock"/> associated with the specified |
| 67 | 67 | /// <paramref name="name"/> that identifies a source object needing concurrency locking. |
| 68 | 68 | /// </summary> |
| 69 | − /// <param name="name">Identifiying name of source object needing concurrency locking (e.g., a path and file name).</param> | |
| 69 | + /// <param name="name">Identifying name of source object needing concurrency locking (e.g., a path and file name).</param> | |
| 70 | 70 | /// <param name="maximumConcurrentLocks">Maximum concurrent reader locks to allow.</param> |
| 71 | 71 | /// <remarks> |
| 72 | 72 | /// If more reader locks are requested than the <paramref name="maximumConcurrentLocks"/>, excess reader locks will simply |
| @@ -128,12 +128,16 @@ namespace GSF.Threading · 55 unmodified lines | ||
| 128 | 128 | if (disposing) |
| 129 | 129 | { |
| 130 | 130 | if ((object)m_concurrencyLock != null) |
| 131 | + { | |
| 131 | 132 | m_concurrencyLock.Close(); |
| 132 | − m_concurrencyLock = null; | |
| 133 | + m_concurrencyLock = null; | |
| 134 | + } | |
| 133 | 135 | |
| 134 | 136 | if ((object)m_semaphoreLock != null) |
| 137 | + { | |
| 135 | 138 | m_semaphoreLock.Close(); |
| 136 | − m_semaphoreLock = null; | |
| 139 | + m_semaphoreLock = null; | |
| 140 | + } | |
| 137 | 141 | } |
| 138 | 142 | } |
| 139 | 143 | finally |
| @@ -147,7 +151,7 @@ namespace GSF.Threading · 7 unmodified lines | ||
| 147 | 151 | /// Tries to enter the lock in read mode. |
| 148 | 152 | /// </summary> |
| 149 | 153 | /// <remarks> |
| 150 | − /// Upon successful aquistion of a read lock, use the <c>finally</c> block of a <c>try/finally</c> statement to call <see cref="ExitReadLock"/>. | |
| 154 | + /// Upon successful acquisition of a read lock, use the <c>finally</c> block of a <c>try/finally</c> statement to call <see cref="ExitReadLock"/>. | |
| 151 | 155 | /// One <see cref="ExitReadLock"/> should be called for each <see cref="EnterReadLock"/> or <see cref="TryEnterReadLock"/>. |
| 152 | 156 | /// </remarks> |
| 153 | 157 | public void EnterReadLock() |
| @@ -159,7 +163,7 @@ namespace GSF.Threading · 5 unmodified lines | ||
| 159 | 163 | /// Tries to enter the lock in write mode. |
| 160 | 164 | /// </summary> |
| 161 | 165 | /// <remarks> |
| 162 | − /// Upon successful aquistion of a write lock, use the <c>finally</c> block of a <c>try/finally</c> statement to call <see cref="ExitWriteLock"/>. | |
| 166 | + /// Upon successful acquisition of a write lock, use the <c>finally</c> block of a <c>try/finally</c> statement to call <see cref="ExitWriteLock"/>. | |
| 163 | 167 | /// One <see cref="ExitWriteLock"/> should be called for each <see cref="EnterWriteLock"/> or <see cref="TryEnterWriteLock"/>. |
| 164 | 168 | /// </remarks> |
| 165 | 169 | public void EnterWriteLock() |
| @@ -171,7 +175,7 @@ namespace GSF.Threading · 5 unmodified lines | ||
| 171 | 175 | /// Exits read mode and returns the prior read lock count. |
| 172 | 176 | /// </summary> |
| 173 | 177 | /// <remarks> |
| 174 | − /// Upon successful aquistion of a read lock, use the <c>finally</c> block of a <c>try/finally</c> statement to call <see cref="ExitReadLock"/>. | |
| 178 | + /// Upon successful acquisition of a read lock, use the <c>finally</c> block of a <c>try/finally</c> statement to call <see cref="ExitReadLock"/>. | |
| 175 | 179 | /// One <see cref="ExitReadLock"/> should be called for each <see cref="EnterReadLock"/> or <see cref="TryEnterReadLock"/>. |
| 176 | 180 | /// </remarks> |
| 177 | 181 | public int ExitReadLock() |
| @@ -184,7 +188,7 @@ namespace GSF.Threading · 6 unmodified lines | ||
| 184 | 188 | /// Exits write mode. |
| 185 | 189 | /// </summary> |
| 186 | 190 | /// <remarks> |
| 187 | − /// Upon successful aquistion of a write lock, use the <c>finally</c> block of a <c>try/finally</c> statement to call <see cref="ExitWriteLock"/>. | |
| 191 | + /// Upon successful acquisition of a write lock, use the <c>finally</c> block of a <c>try/finally</c> statement to call <see cref="ExitWriteLock"/>. | |
| 188 | 192 | /// One <see cref="ExitWriteLock"/> should be called for each <see cref="EnterWriteLock"/> or <see cref="TryEnterWriteLock"/>. |
| 189 | 193 | /// </remarks> |
| 190 | 194 | public void ExitWriteLock() |
| @@ -199,12 +203,12 @@ namespace GSF.Threading · 8 unmodified lines | ||
| 199 | 203 | /// <param name="millisecondsTimeout">The number of milliseconds to wait, or -1 (<see cref="Timeout.Infinite"/>) to wait indefinitely.</param> |
| 200 | 204 | /// <returns><c>true</c> if the calling thread entered read mode, otherwise, <c>false</c>.</returns> |
| 201 | 205 | /// <remarks> |
| 202 | − /// Upon successful aquistion of a read lock, use the <c>finally</c> block of a <c>try/finally</c> statement to call <see cref="ExitReadLock"/>. | |
| 206 | + /// Upon successful acquisition of a read lock, use the <c>finally</c> block of a <c>try/finally</c> statement to call <see cref="ExitReadLock"/>. | |
| 203 | 207 | /// One <see cref="ExitReadLock"/> should be called for each <see cref="EnterReadLock"/> or <see cref="TryEnterReadLock"/>. |
| 204 | 208 | /// </remarks> |
| 205 | 209 | public bool TryEnterReadLock(int millisecondsTimeout) |
| 206 | 210 | { |
| 207 | − bool success = false; | |
| 211 | + bool success; | |
| 208 | 212 | |
| 209 | 213 | try |
| 210 | 214 | { |
| @@ -263,7 +267,9 @@ namespace GSF.Threading · 52 unmodified lines | ||
| 263 | 267 | // The only way to get a semaphore slot count is to execute a successful wait and release. |
| 264 | 268 | startTime = DateTime.UtcNow.Ticks; |
| 265 | 269 | |
| 266 | − if (success = m_concurrencyLock.WaitOne(millisecondsTimeout)) | |
| 270 | + success = m_concurrencyLock.WaitOne(millisecondsTimeout); | |
| 271 | + | |
| 272 | + if (success) | |
| 267 | 273 | { |
| 268 | 274 | int count = m_concurrencyLock.Release(); |
| 269 | 275 | int adjustedTimeout = millisecondsTimeout; |
| @@ -282,7 +288,9 @@ namespace GSF.Threading · 12 unmodified lines | ||
| 282 | 288 | if (adjustedTimeout < 0) |
| 283 | 289 | adjustedTimeout = 0; |
| 284 | 290 | |
| 285 | − if (success = m_concurrencyLock.WaitOne(adjustedTimeout)) | |
| 291 | + success = m_concurrencyLock.WaitOne(adjustedTimeout); | |
| 292 | + | |
| 293 | + if (success) | |
| 286 | 294 | count = m_concurrencyLock.Release(); |
| 287 | 295 | } |
| 288 | 296 | } |