Showing the changes to Source/Libraries/GSF.Core/Threading/InterprocessReaderWriterLock.cs (1 of 2 files). Show all
Unified · Split
| @@ -16,7 +16,7 @@ · 15 unmodified lines | |||
| 16 | // | 16 | // |
| 17 | // Code Modification History: | 17 | // Code Modification History: |
| 18 | // ---------------------------------------------------------------------------------------------------- | 18 | // ---------------------------------------------------------------------------------------------------- |
| 19 | // 03/21/2011 - Ritchie | 19 | // 03/21/2011 - J. Ritchie Carroll |
| 20 | // Generated original version of source code. | 20 | // Generated original version of source code. |
| 21 | // 12/14/2012 - Starlynn Danyelle Gilliam | 21 | // 12/14/2012 - Starlynn Danyelle Gilliam |
| 22 | // Modified Header. | 22 | // Modified Header. |
| @@ -203,8 +203,14 @@ namespace GSF.Threading · 180 unmodified lines | |||
| 203 | /// <param name="millisecondsTimeout">The number of milliseconds to wait, or -1 (<see cref="Timeout.Infinite"/>) to wait indefinitely.</param> | 203 | /// <param name="millisecondsTimeout">The number of milliseconds to wait, or -1 (<see cref="Timeout.Infinite"/>) to wait indefinitely.</param> |
| 204 | /// <returns><c>true</c> if the calling thread entered read mode, otherwise, <c>false</c>.</returns> | 204 | /// <returns><c>true</c> if the calling thread entered read mode, otherwise, <c>false</c>.</returns> |
| 205 | /// <remarks> | 205 | /// <remarks> |
| 206 | /// <para> | ||
| 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"/>. | 207 | /// 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"/>. |
| 207 | /// One <see cref="ExitReadLock"/> should be called for each <see cref="EnterReadLock"/> or <see cref="TryEnterReadLock"/>. | 208 | /// One <see cref="ExitReadLock"/> should be called for each <see cref="EnterReadLock"/> or <see cref="TryEnterReadLock"/>. |
| 209 | /// </para> | ||
| 210 | /// <para> | ||
| 211 | /// Note that this function may wait as long as 2 * <paramref name="millisecondsTimeout"/> since the function first waits for synchronous access | ||
| 212 | /// to the semaphore, then waits again on an available semaphore slot. | ||
| 213 | /// </para> | ||
| 208 | /// </remarks> | 214 | /// </remarks> |
| 209 | public bool TryEnterReadLock(int millisecondsTimeout) | 215 | public bool TryEnterReadLock(int millisecondsTimeout) |
| 210 | { | 216 | { |
| @@ -213,7 +219,8 @@ namespace GSF.Threading · 2 unmodified lines | |||
| 213 | try | 219 | try |
| 214 | { | 220 | { |
| 215 | // Wait for system level mutex lock to synchronize access to semaphore | 221 | // Wait for system level mutex lock to synchronize access to semaphore |
| 216 | m_semaphoreLock.WaitOne(); | 222 | if (!m_semaphoreLock.WaitOne(millisecondsTimeout)) |
| 223 | return false; | ||
| 217 | } | 224 | } |
| 218 | catch (AbandonedMutexException) | 225 | catch (AbandonedMutexException) |
| 219 | { | 226 | { |
| @@ -241,8 +248,14 @@ namespace GSF.Threading · 21 unmodified lines | |||
| 241 | /// <param name="millisecondsTimeout">The number of milliseconds to wait, or -1 (<see cref="Timeout.Infinite"/>) to wait indefinitely.</param> | 248 | /// <param name="millisecondsTimeout">The number of milliseconds to wait, or -1 (<see cref="Timeout.Infinite"/>) to wait indefinitely.</param> |
| 242 | /// <returns><c>true</c> if the calling thread entered write mode, otherwise, <c>false</c>.</returns> | 249 | /// <returns><c>true</c> if the calling thread entered write mode, otherwise, <c>false</c>.</returns> |
| 243 | /// <remarks> | 250 | /// <remarks> |
| 244 | /// 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"/>. | 251 | /// <para> |
| 252 | /// 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"/>. | ||
| 245 | /// One <see cref="ExitWriteLock"/> should be called for each <see cref="EnterWriteLock"/> or <see cref="TryEnterWriteLock"/>. | 253 | /// One <see cref="ExitWriteLock"/> should be called for each <see cref="EnterWriteLock"/> or <see cref="TryEnterWriteLock"/>. |
| 254 | /// </para> | ||
| 255 | /// <para> | ||
| 256 | /// Note that this function may wait as long as 2 * <paramref name="millisecondsTimeout"/> since the function first waits for synchronous access | ||
| 257 | /// to the semaphore, then waits again on an available semaphore slot. | ||
| 258 | /// </para> | ||
| 246 | /// </remarks> | 259 | /// </remarks> |
| 247 | public bool TryEnterWriteLock(int millisecondsTimeout) | 260 | public bool TryEnterWriteLock(int millisecondsTimeout) |
| 248 | { | 261 | { |
| @@ -252,7 +265,8 @@ namespace GSF.Threading · 3 unmodified lines | |||
| 252 | try | 265 | try |
| 253 | { | 266 | { |
| 254 | // Wait for system level mutex lock to synchronize access to semaphore | 267 | // Wait for system level mutex lock to synchronize access to semaphore |
| 255 | m_semaphoreLock.WaitOne(); | 268 | if (!m_semaphoreLock.WaitOne(millisecondsTimeout)) |
| 269 | return false; | ||
| 256 | } | 270 | } |
| 257 | catch (AbandonedMutexException) | 271 | catch (AbandonedMutexException) |
| 258 | { | 272 | { |
| @@ -262,7 +276,7 @@ namespace GSF.Threading · 3 unmodified lines | |||
| 262 | 276 | ||
| 263 | try | 277 | try |
| 264 | { | 278 | { |
| 265 | // At this point no other threads can aquire read or write access since we own the mutex. | 279 | // At this point no other threads can acquire read or write access since we own the mutex. |
| 266 | // Other threads may be busy reading, so we wait until all semaphore slots become available. | 280 | // Other threads may be busy reading, so we wait until all semaphore slots become available. |
| 267 | // The only way to get a semaphore slot count is to execute a successful wait and release. | 281 | // The only way to get a semaphore slot count is to execute a successful wait and release. |
| 268 | startTime = DateTime.UtcNow.Ticks; | 282 | startTime = DateTime.UtcNow.Ticks; |
| @@ -281,7 +295,7 @@ namespace GSF.Threading · 12 unmodified lines | |||
| 281 | // Sleep to allow any remaining reads to complete | 295 | // Sleep to allow any remaining reads to complete |
| 282 | Thread.Sleep(1); | 296 | Thread.Sleep(1); |
| 283 | 297 | ||
| 284 | // Continue to adjust remaining time to accomodate user specified millisecond timeout | 298 | // Continue to adjust remaining time to accommodate user specified millisecond timeout |
| 285 | if (millisecondsTimeout > 0) | 299 | if (millisecondsTimeout > 0) |
| 286 | adjustedTimeout = millisecondsTimeout - (int)Ticks.ToMilliseconds(DateTime.UtcNow.Ticks - startTime); | 300 | adjustedTimeout = millisecondsTimeout - (int)Ticks.ToMilliseconds(DateTime.UtcNow.Ticks - startTime); |
| 287 | 301 | ||
| @@ -302,7 +316,7 @@ namespace GSF.Threading · 14 unmodified lines | |||
| 302 | m_semaphoreLock.ReleaseMutex(); | 316 | m_semaphoreLock.ReleaseMutex(); |
| 303 | } | 317 | } |
| 304 | 318 | ||
| 305 | // Successfully entering write lock leaves state of semphore locking mutex "owned", it is critical that | 319 | // Successfully entering write lock leaves state of semaphore locking mutex "owned", it is critical that |
| 306 | // consumer call ExitWriteLock upon completion of write action to release mutex regardless of whether | 320 | // consumer call ExitWriteLock upon completion of write action to release mutex regardless of whether |
| 307 | // their code succeeds or fails, that is, consumer should use the finally clause of a "try/finally" | 321 | // their code succeeds or fails, that is, consumer should use the finally clause of a "try/finally" |
| 308 | // expression to ExitWriteLock. | 322 | // expression to ExitWriteLock. |