Showing the changes to Source/Libraries/GSF.Core/Threading/InterprocessReaderWriterLock.cs (1 of 2 files). Show all
Unified · Split
| @@ -82,10 +82,8 @@ namespace GSF.Threading · 81 unmodified lines | |||
| 82 | /// <summary> | 82 | /// <summary> |
| 83 | /// Releases the unmanaged resources before the <see cref="InterprocessReaderWriterLock"/> object is reclaimed by <see cref="GC"/>. | 83 | /// Releases the unmanaged resources before the <see cref="InterprocessReaderWriterLock"/> object is reclaimed by <see cref="GC"/>. |
| 84 | /// </summary> | 84 | /// </summary> |
| 85 | ~InterprocessReaderWriterLock() | 85 | ~InterprocessReaderWriterLock() => |
| 86 | { | ||
| 87 | Dispose(false); | 86 | Dispose(false); |
| 88 | } | ||
| 89 | 87 | ||
| 90 | #endregion | 88 | #endregion |
| 91 | 89 | ||
| @@ -94,13 +92,7 @@ namespace GSF.Threading · 2 unmodified lines | |||
| 94 | /// <summary> | 92 | /// <summary> |
| 95 | /// Gets the maximum concurrent reader locks allowed. | 93 | /// Gets the maximum concurrent reader locks allowed. |
| 96 | /// </summary> | 94 | /// </summary> |
| 97 | public int MaximumConcurrentLocks | 95 | public int MaximumConcurrentLocks => m_maximumConcurrentLocks; |
| 98 | { | ||
| 99 | get | ||
| 100 | { | ||
| 101 | return m_maximumConcurrentLocks; | ||
| 102 | } | ||
| 103 | } | ||
| 104 | 96 | ||
| 105 | #endregion | 97 | #endregion |
| 106 | 98 | ||
| @@ -121,30 +113,30 @@ namespace GSF.Threading · 14 unmodified lines | |||
| 121 | /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> | 113 | /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> |
| 122 | protected virtual void Dispose(bool disposing) | 114 | protected virtual void Dispose(bool disposing) |
| 123 | { | 115 | { |
| 124 | if (!m_disposed) | 116 | if (m_disposed) |
| 117 | return; | ||
| 118 | |||
| 119 | try | ||
| 125 | { | 120 | { |
| 126 | try | 121 | if (!disposing) |
| 122 | return; | ||
| 123 | |||
| 124 | if (!(m_concurrencyLock is null)) | ||
| 127 | { | 125 | { |
| 128 | if (disposing) | 126 | m_concurrencyLock.Close(); |
| 129 | { | 127 | m_concurrencyLock = null; |
| 130 | if ((object)m_concurrencyLock != null) | ||
| 131 | { | ||
| 132 | m_concurrencyLock.Close(); | ||
| 133 | m_concurrencyLock = null; | ||
| 134 | } | ||
| 135 | |||
| 136 | if ((object)m_semaphoreLock != null) | ||
| 137 | { | ||
| 138 | m_semaphoreLock.Close(); | ||
| 139 | m_semaphoreLock = null; | ||
| 140 | } | ||
| 141 | } | ||
| 142 | } | 128 | } |
| 143 | finally | 129 | |
| 130 | if (!(m_semaphoreLock is null)) | ||
| 144 | { | 131 | { |
| 145 | m_disposed = true; // Prevent duplicate dispose. | 132 | m_semaphoreLock.Close(); |
| 133 | m_semaphoreLock = null; | ||
| 146 | } | 134 | } |
| 147 | } | 135 | } |
| 136 | finally | ||
| 137 | { | ||
| 138 | m_disposed = true; // Prevent duplicate dispose. | ||
| 139 | } | ||
| 148 | } | 140 | } |
| 149 | 141 | ||
| 150 | /// <summary> | 142 | /// <summary> |
| @@ -154,10 +146,8 @@ namespace GSF.Threading · 3 unmodified lines | |||
| 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"/>. | 146 | /// 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"/>. |
| 155 | /// One <see cref="ExitReadLock"/> should be called for each <see cref="EnterReadLock"/> or <see cref="TryEnterReadLock"/>. | 147 | /// One <see cref="ExitReadLock"/> should be called for each <see cref="EnterReadLock"/> or <see cref="TryEnterReadLock"/>. |
| 156 | /// </remarks> | 148 | /// </remarks> |
| 157 | public void EnterReadLock() | 149 | public void EnterReadLock() => |
| 158 | { | ||
| 159 | TryEnterReadLock(Timeout.Infinite); | 150 | TryEnterReadLock(Timeout.Infinite); |
| 160 | } | ||
| 161 | 151 | ||
| 162 | /// <summary> | 152 | /// <summary> |
| 163 | /// Tries to enter the lock in write mode. | 153 | /// Tries to enter the lock in write mode. |
| @@ -166,10 +156,8 @@ namespace GSF.Threading · 2 unmodified lines | |||
| 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"/>. | 156 | /// 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"/>. |
| 167 | /// One <see cref="ExitWriteLock"/> should be called for each <see cref="EnterWriteLock"/> or <see cref="TryEnterWriteLock"/>. | 157 | /// One <see cref="ExitWriteLock"/> should be called for each <see cref="EnterWriteLock"/> or <see cref="TryEnterWriteLock"/>. |
| 168 | /// </remarks> | 158 | /// </remarks> |
| 169 | public void EnterWriteLock() | 159 | public void EnterWriteLock() => |
| 170 | { | ||
| 171 | TryEnterWriteLock(Timeout.Infinite); | 160 | TryEnterWriteLock(Timeout.Infinite); |
| 172 | } | ||
| 173 | 161 | ||
| 174 | /// <summary> | 162 | /// <summary> |
| 175 | /// Exits read mode and returns the prior read lock count. | 163 | /// Exits read mode and returns the prior read lock count. |
| @@ -178,11 +166,8 @@ namespace GSF.Threading · 2 unmodified lines | |||
| 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"/>. | 166 | /// 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"/>. |
| 179 | /// One <see cref="ExitReadLock"/> should be called for each <see cref="EnterReadLock"/> or <see cref="TryEnterReadLock"/>. | 167 | /// One <see cref="ExitReadLock"/> should be called for each <see cref="EnterReadLock"/> or <see cref="TryEnterReadLock"/>. |
| 180 | /// </remarks> | 168 | /// </remarks> |
| 181 | public int ExitReadLock() | 169 | public int ExitReadLock() => |
| 182 | { | 170 | m_concurrencyLock.Release(); // Release the semaphore lock and restore the slot |
| 183 | // Release the semaphore lock and restore the slot | ||
| 184 | return m_concurrencyLock.Release(); | ||
| 185 | } | ||
| 186 | 171 | ||
| 187 | /// <summary> | 172 | /// <summary> |
| 188 | /// Exits write mode. | 173 | /// Exits write mode. |
| @@ -191,11 +176,8 @@ namespace GSF.Threading · 2 unmodified lines | |||
| 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"/>. | 176 | /// 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"/>. |
| 192 | /// One <see cref="ExitWriteLock"/> should be called for each <see cref="EnterWriteLock"/> or <see cref="TryEnterWriteLock"/>. | 177 | /// One <see cref="ExitWriteLock"/> should be called for each <see cref="EnterWriteLock"/> or <see cref="TryEnterWriteLock"/>. |
| 193 | /// </remarks> | 178 | /// </remarks> |
| 194 | public void ExitWriteLock() | 179 | public void ExitWriteLock() => |
| 195 | { | 180 | m_semaphoreLock.ReleaseMutex(); // Release semaphore synchronization mutex lock |
| 196 | // Release semaphore synchronization mutex lock | ||
| 197 | m_semaphoreLock.ReleaseMutex(); | ||
| 198 | } | ||
| 199 | 181 | ||
| 200 | /// <summary> | 182 | /// <summary> |
| 201 | /// Tries to enter the lock in read mode, with an optional time-out. | 183 | /// Tries to enter the lock in read mode, with an optional time-out. |
| @@ -260,7 +242,6 @@ namespace GSF.Threading · 58 unmodified lines | |||
| 260 | public bool TryEnterWriteLock(int millisecondsTimeout) | 242 | public bool TryEnterWriteLock(int millisecondsTimeout) |
| 261 | { | 243 | { |
| 262 | bool success = false; | 244 | bool success = false; |
| 263 | long startTime; | ||
| 264 | 245 | ||
| 265 | try | 246 | try |
| 266 | { | 247 | { |
| @@ -279,7 +260,7 @@ namespace GSF.Threading · 12 unmodified lines | |||
| 279 | // At this point no other threads can acquire read or write access since we own the mutex. | 260 | // At this point no other threads can acquire read or write access since we own the mutex. |
| 280 | // Other threads may be busy reading, so we wait until all semaphore slots become available. | 261 | // Other threads may be busy reading, so we wait until all semaphore slots become available. |
| 281 | // The only way to get a semaphore slot count is to execute a successful wait and release. | 262 | // The only way to get a semaphore slot count is to execute a successful wait and release. |
| 282 | startTime = DateTime.UtcNow.Ticks; | 263 | long startTime = DateTime.UtcNow.Ticks; |
| 283 | 264 | ||
| 284 | success = m_concurrencyLock.WaitOne(millisecondsTimeout); | 265 | success = m_concurrencyLock.WaitOne(millisecondsTimeout); |
| 285 | 266 | ||