History

Renamed folders and separated GSF.Media and GSF.Net into separate projects.

StephenCWills committed 14 years ago

Commit ac1ef661 parent 45bce55628 files · +733 −461Browse files

Showing the changes to Source/Libraries/GSF.Core/Threading/InterprocessReaderWriterLock.cs (1 of 628 files). Show all

Unified · Split

Source/Libraries/GSF.Core/Threading/InterprocessReaderWriterLock.cs+532−0
@@ -0,0 +1,532 @@
1+//*******************************************************************************************************
2+// InterprocessReaderWriterLock.cs - Gbtc
3+//
4+// Tennessee Valley Authority, 2011
5+// No copyright is claimed pursuant to 17 USC § 105. All Other Rights Reserved.
6+//
7+// This software is made freely available under the TVA Open Source Agreement (see below).
8+// Code in this file licensed to GSF under one or more contributor license agreements listed below.
9+//
10+// Code Modification History:
11+// -----------------------------------------------------------------------------------------------------
12+// 03/21/2011 - Ritchie
13+// Generated original version of source code.
14+//
15+//*******************************************************************************************************
16+
17+#region [ TVA Open Source Agreement ]
18+/*
19+
20+ THIS OPEN SOURCE AGREEMENT ("AGREEMENT") DEFINES THE RIGHTS OF USE,REPRODUCTION, DISTRIBUTION,
21+ MODIFICATION AND REDISTRIBUTION OF CERTAIN COMPUTER SOFTWARE ORIGINALLY RELEASED BY THE
22+ TENNESSEE VALLEY AUTHORITY, A CORPORATE AGENCY AND INSTRUMENTALITY OF THE UNITED STATES GOVERNMENT
23+ ("GOVERNMENT AGENCY"). GOVERNMENT AGENCY IS AN INTENDED THIRD-PARTY BENEFICIARY OF ALL SUBSEQUENT
24+ DISTRIBUTIONS OR REDISTRIBUTIONS OF THE SUBJECT SOFTWARE. ANYONE WHO USES, REPRODUCES, DISTRIBUTES,
25+ MODIFIES OR REDISTRIBUTES THE SUBJECT SOFTWARE, AS DEFINED HEREIN, OR ANY PART THEREOF, IS, BY THAT
26+ ACTION, ACCEPTING IN FULL THE RESPONSIBILITIES AND OBLIGATIONS CONTAINED IN THIS AGREEMENT.
27+
28+ Original Software Designation: openPDC
29+ Original Software Title: The GSF Open Source Phasor Data Concentrator
30+ User Registration Requested. Please Visit https://naspi.tva.com/Registration/
31+ Point of Contact for Original Software: J. Ritchie Carroll <mailto:jrcarrol@tva.gov>
32+
33+ 1. DEFINITIONS
34+
35+ A. "Contributor" means Government Agency, as the developer of the Original Software, and any entity
36+ that makes a Modification.
37+
38+ B. "Covered Patents" mean patent claims licensable by a Contributor that are necessarily infringed by
39+ the use or sale of its Modification alone or when combined with the Subject Software.
40+
41+ C. "Display" means the showing of a copy of the Subject Software, either directly or by means of an
42+ image, or any other device.
43+
44+ D. "Distribution" means conveyance or transfer of the Subject Software, regardless of means, to
45+ another.
46+
47+ E. "Larger Work" means computer software that combines Subject Software, or portions thereof, with
48+ software separate from the Subject Software that is not governed by the terms of this Agreement.
49+
50+ F. "Modification" means any alteration of, including addition to or deletion from, the substance or
51+ structure of either the Original Software or Subject Software, and includes derivative works, as that
52+ term is defined in the Copyright Statute, 17 USC § 101. However, the act of including Subject Software
53+ as part of a Larger Work does not in and of itself constitute a Modification.
54+
55+ G. "Original Software" means the computer software first released under this Agreement by Government
56+ Agency entitled openPDC, including source code, object code and accompanying documentation, if any.
57+
58+ H. "Recipient" means anyone who acquires the Subject Software under this Agreement, including all
59+ Contributors.
60+
61+ I. "Redistribution" means Distribution of the Subject Software after a Modification has been made.
62+
63+ J. "Reproduction" means the making of a counterpart, image or copy of the Subject Software.
64+
65+ K. "Sale" means the exchange of the Subject Software for money or equivalent value.
66+
67+ L. "Subject Software" means the Original Software, Modifications, or any respective parts thereof.
68+
69+ M. "Use" means the application or employment of the Subject Software for any purpose.
70+
71+ 2. GRANT OF RIGHTS
72+
73+ A. Under Non-Patent Rights: Subject to the terms and conditions of this Agreement, each Contributor,
74+ with respect to its own contribution to the Subject Software, hereby grants to each Recipient a
75+ non-exclusive, world-wide, royalty-free license to engage in the following activities pertaining to
76+ the Subject Software:
77+
78+ 1. Use
79+
80+ 2. Distribution
81+
82+ 3. Reproduction
83+
84+ 4. Modification
85+
86+ 5. Redistribution
87+
88+ 6. Display
89+
90+ B. Under Patent Rights: Subject to the terms and conditions of this Agreement, each Contributor, with
91+ respect to its own contribution to the Subject Software, hereby grants to each Recipient under Covered
92+ Patents a non-exclusive, world-wide, royalty-free license to engage in the following activities
93+ pertaining to the Subject Software:
94+
95+ 1. Use
96+
97+ 2. Distribution
98+
99+ 3. Reproduction
100+
101+ 4. Sale
102+
103+ 5. Offer for Sale
104+
105+ C. The rights granted under Paragraph B. also apply to the combination of a Contributor's Modification
106+ and the Subject Software if, at the time the Modification is added by the Contributor, the addition of
107+ such Modification causes the combination to be covered by the Covered Patents. It does not apply to
108+ any other combinations that include a Modification.
109+
110+ D. The rights granted in Paragraphs A. and B. allow the Recipient to sublicense those same rights.
111+ Such sublicense must be under the same terms and conditions of this Agreement.
112+
113+ 3. OBLIGATIONS OF RECIPIENT
114+
115+ A. Distribution or Redistribution of the Subject Software must be made under this Agreement except for
116+ additions covered under paragraph 3H.
117+
118+ 1. Whenever a Recipient distributes or redistributes the Subject Software, a copy of this Agreement
119+ must be included with each copy of the Subject Software; and
120+
121+ 2. If Recipient distributes or redistributes the Subject Software in any form other than source code,
122+ Recipient must also make the source code freely available, and must provide with each copy of the
123+ Subject Software information on how to obtain the source code in a reasonable manner on or through a
124+ medium customarily used for software exchange.
125+
126+ B. Each Recipient must ensure that the following copyright notice appears prominently in the Subject
127+ Software:
128+
129+ No copyright is claimed pursuant to 17 USC § 105. All Other Rights Reserved.
130+
131+ C. Each Contributor must characterize its alteration of the Subject Software as a Modification and
132+ must identify itself as the originator of its Modification in a manner that reasonably allows
133+ subsequent Recipients to identify the originator of the Modification. In fulfillment of these
134+ requirements, Contributor must include a file (e.g., a change log file) that describes the alterations
135+ made and the date of the alterations, identifies Contributor as originator of the alterations, and
136+ consents to characterization of the alterations as a Modification, for example, by including a
137+ statement that the Modification is derived, directly or indirectly, from Original Software provided by
138+ Government Agency. Once consent is granted, it may not thereafter be revoked.
139+
140+ D. A Contributor may add its own copyright notice to the Subject Software. Once a copyright notice has
141+ been added to the Subject Software, a Recipient may not remove it without the express permission of
142+ the Contributor who added the notice.
143+
144+ E. A Recipient may not make any representation in the Subject Software or in any promotional,
145+ advertising or other material that may be construed as an endorsement by Government Agency or by any
146+ prior Recipient of any product or service provided by Recipient, or that may seek to obtain commercial
147+ advantage by the fact of Government Agency's or a prior Recipient's participation in this Agreement.
148+
149+ F. In an effort to track usage and maintain accurate records of the Subject Software, each Recipient,
150+ upon receipt of the Subject Software, is requested to register with Government Agency by visiting the
151+ following website: https://naspi.tva.com/Registration/. Recipient's name and personal information
152+ shall be used for statistical purposes only. Once a Recipient makes a Modification available, it is
153+ requested that the Recipient inform Government Agency at the web site provided above how to access the
154+ Modification.
155+
156+ G. Each Contributor represents that that its Modification does not violate any existing agreements,
157+ regulations, statutes or rules, and further that Contributor has sufficient rights to grant the rights
158+ conveyed by this Agreement.
159+
160+ H. A Recipient may choose to offer, and to charge a fee for, warranty, support, indemnity and/or
161+ liability obligations to one or more other Recipients of the Subject Software. A Recipient may do so,
162+ however, only on its own behalf and not on behalf of Government Agency or any other Recipient. Such a
163+ Recipient must make it absolutely clear that any such warranty, support, indemnity and/or liability
164+ obligation is offered by that Recipient alone. Further, such Recipient agrees to indemnify Government
165+ Agency and every other Recipient for any liability incurred by them as a result of warranty, support,
166+ indemnity and/or liability offered by such Recipient.
167+
168+ I. A Recipient may create a Larger Work by combining Subject Software with separate software not
169+ governed by the terms of this agreement and distribute the Larger Work as a single product. In such
170+ case, the Recipient must make sure Subject Software, or portions thereof, included in the Larger Work
171+ is subject to this Agreement.
172+
173+ J. Notwithstanding any provisions contained herein, Recipient is hereby put on notice that export of
174+ any goods or technical data from the United States may require some form of export license from the
175+ U.S. Government. Failure to obtain necessary export licenses may result in criminal liability under
176+ U.S. laws. Government Agency neither represents that a license shall not be required nor that, if
177+ required, it shall be issued. Nothing granted herein provides any such export license.
178+
179+ 4. DISCLAIMER OF WARRANTIES AND LIABILITIES; WAIVER AND INDEMNIFICATION
180+
181+ A. No Warranty: THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY KIND, EITHER
182+ EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SUBJECT
183+ SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
184+ PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL BE ERROR
185+ FREE, OR ANY WARRANTY THAT DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. THIS
186+ AGREEMENT DOES NOT, IN ANY MANNER, CONSTITUTE AN ENDORSEMENT BY GOVERNMENT AGENCY OR ANY PRIOR
187+ RECIPIENT OF ANY RESULTS, RESULTING DESIGNS, HARDWARE, SOFTWARE PRODUCTS OR ANY OTHER APPLICATIONS
188+ RESULTING FROM USE OF THE SUBJECT SOFTWARE. FURTHER, GOVERNMENT AGENCY DISCLAIMS ALL WARRANTIES AND
189+ LIABILITIES REGARDING THIRD-PARTY SOFTWARE, IF PRESENT IN THE ORIGINAL SOFTWARE, AND DISTRIBUTES IT
190+ "AS IS."
191+
192+ B. Waiver and Indemnity: RECIPIENT AGREES TO WAIVE ANY AND ALL CLAIMS AGAINST GOVERNMENT AGENCY, ITS
193+ AGENTS, EMPLOYEES, CONTRACTORS AND SUBCONTRACTORS, AS WELL AS ANY PRIOR RECIPIENT. IF RECIPIENT'S USE
194+ OF THE SUBJECT SOFTWARE RESULTS IN ANY LIABILITIES, DEMANDS, DAMAGES, EXPENSES OR LOSSES ARISING FROM
195+ SUCH USE, INCLUDING ANY DAMAGES FROM PRODUCTS BASED ON, OR RESULTING FROM, RECIPIENT'S USE OF THE
196+ SUBJECT SOFTWARE, RECIPIENT SHALL INDEMNIFY AND HOLD HARMLESS GOVERNMENT AGENCY, ITS AGENTS,
197+ EMPLOYEES, CONTRACTORS AND SUBCONTRACTORS, AS WELL AS ANY PRIOR RECIPIENT, TO THE EXTENT PERMITTED BY
198+ LAW. THE FOREGOING RELEASE AND INDEMNIFICATION SHALL APPLY EVEN IF THE LIABILITIES, DEMANDS, DAMAGES,
199+ EXPENSES OR LOSSES ARE CAUSED, OCCASIONED, OR CONTRIBUTED TO BY THE NEGLIGENCE, SOLE OR CONCURRENT, OF
200+ GOVERNMENT AGENCY OR ANY PRIOR RECIPIENT. RECIPIENT'S SOLE REMEDY FOR ANY SUCH MATTER SHALL BE THE
201+ IMMEDIATE, UNILATERAL TERMINATION OF THIS AGREEMENT.
202+
203+ 5. GENERAL TERMS
204+
205+ A. Termination: This Agreement and the rights granted hereunder will terminate automatically if a
206+ Recipient fails to comply with these terms and conditions, and fails to cure such noncompliance within
207+ thirty (30) days of becoming aware of such noncompliance. Upon termination, a Recipient agrees to
208+ immediately cease use and distribution of the Subject Software. All sublicenses to the Subject
209+ Software properly granted by the breaching Recipient shall survive any such termination of this
210+ Agreement.
211+
212+ B. Severability: If any provision of this Agreement is invalid or unenforceable under applicable law,
213+ it shall not affect the validity or enforceability of the remainder of the terms of this Agreement.
214+
215+ C. Applicable Law: This Agreement shall be subject to United States federal law only for all purposes,
216+ including, but not limited to, determining the validity of this Agreement, the meaning of its
217+ provisions and the rights, obligations and remedies of the parties.
218+
219+ D. Entire Understanding: This Agreement constitutes the entire understanding and agreement of the
220+ parties relating to release of the Subject Software and may not be superseded, modified or amended
221+ except by further written agreement duly executed by the parties.
222+
223+ E. Binding Authority: By accepting and using the Subject Software under this Agreement, a Recipient
224+ affirms its authority to bind the Recipient to all terms and conditions of this Agreement and that
225+ Recipient hereby agrees to all terms and conditions herein.
226+
227+ F. Point of Contact: Any Recipient contact with Government Agency is to be directed to the designated
228+ representative as follows: J. Ritchie Carroll <mailto:jrcarrol@tva.gov>.
229+
230+*/
231+#endregion
232+
233+#region [ Contributor License Agreements ]
234+
235+//******************************************************************************************************
236+//
237+// Copyright © 2011, Grid Protection Alliance. All Rights Reserved.
238+//
239+// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
240+// not use this file except in compliance with the License. You may obtain a copy of the License at:
241+//
242+// http://www.opensource.org/licenses/eclipse-1.0.php
243+//
244+// Unless agreed to in writing, the subject software distributed under the License is distributed on an
245+// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
246+// License for the specific language governing permissions and limitations.
247+//
248+//******************************************************************************************************
249+
250+#endregion
251+
252+using System;
253+using System.Threading;
254+
255+namespace GSF.Threading
256+{
257+ /// <summary>
258+ /// Represents an interprocess reader/writer lock using <see cref="Semaphore"/> and <see cref="Mutex"/> native locking mechanisms.
259+ /// </summary>
260+ public class InterprocessReaderWriterLock : IDisposable
261+ {
262+ #region [ Members ]
263+
264+ // Constants
265+
266+ /// <summary>
267+ /// Default maximum concurrent locks allowed for <see cref="InterprocessReaderWriterLock"/>.
268+ /// </summary>
269+ public const int DefaultMaximumConcurrentLocks = 10;
270+
271+ // Fields
272+ private Mutex m_semaphoreLock; // Mutex used to synchronize access to Semaphore
273+ private Semaphore m_concurrencyLock; // Semaphore used for reader/writer lock on consumer object
274+ private int m_maximumConcurrentLocks;
275+ private bool m_disposed;
276+
277+ #endregion
278+
279+ #region [ Constructors ]
280+
281+ /// <summary>
282+ /// Creates a new instance of the <see cref="InterprocessReaderWriterLock"/> associated with the specified
283+ /// <paramref name="name"/> that identifies a source object needing concurrency locking.
284+ /// </summary>
285+ /// <param name="name">Identifiying name of source object needing concurrency locking (e.g., a path and file name).</param>
286+ public InterprocessReaderWriterLock(string name)
287+ : this(name, DefaultMaximumConcurrentLocks)
288+ {
289+ }
290+
291+ /// <summary>
292+ /// Creates a new instance of the <see cref="InterprocessReaderWriterLock"/> associated with the specified
293+ /// <paramref name="name"/> that identifies a source object needing concurrency locking.
294+ /// </summary>
295+ /// <param name="name">Identifiying name of source object needing concurrency locking (e.g., a path and file name).</param>
296+ /// <param name="maximumConcurrentLocks">Maximum concurrent reader locks to allow.</param>
297+ /// <remarks>
298+ /// If more reader locks are requested than the <paramref name="maximumConcurrentLocks"/>, excess reader locks will simply
299+ /// wait until a lock is available (i.e., one of the existing reads completes).
300+ /// </remarks>
301+ public InterprocessReaderWriterLock(string name, int maximumConcurrentLocks)
302+ {
303+ m_maximumConcurrentLocks = maximumConcurrentLocks;
304+ m_semaphoreLock = InterprocessLock.GetNamedMutex(name);
305+ m_concurrencyLock = InterprocessLock.GetNamedSemaphore(name, m_maximumConcurrentLocks);
306+ }
307+
308+ /// <summary>
309+ /// Releases the unmanaged resources before the <see cref="InterprocessReaderWriterLock"/> object is reclaimed by <see cref="GC"/>.
310+ /// </summary>
311+ ~InterprocessReaderWriterLock()
312+ {
313+ Dispose(false);
314+ }
315+
316+ #endregion
317+
318+ #region [ Properties ]
319+
320+ /// <summary>
321+ /// Gets the maximum concurrent reader locks allowed.
322+ /// </summary>
323+ public int MaximumConcurrentLocks
324+ {
325+ get
326+ {
327+ return m_maximumConcurrentLocks;
328+ }
329+ }
330+
331+ #endregion
332+
333+ #region [ Methods ]
334+
335+ /// <summary>
336+ /// Releases all the resources used by the <see cref="InterprocessReaderWriterLock"/> object.
337+ /// </summary>
338+ public void Dispose()
339+ {
340+ Dispose(true);
341+ GC.SuppressFinalize(this);
342+ }
343+
344+ /// <summary>
345+ /// Releases the unmanaged resources used by the <see cref="InterprocessReaderWriterLock"/> object and optionally releases the managed resources.
346+ /// </summary>
347+ /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
348+ protected virtual void Dispose(bool disposing)
349+ {
350+ if (!m_disposed)
351+ {
352+ try
353+ {
354+ if (disposing)
355+ {
356+ if ((object)m_concurrencyLock != null)
357+ m_concurrencyLock.Close();
358+ m_concurrencyLock = null;
359+
360+ if ((object)m_semaphoreLock != null)
361+ m_semaphoreLock.Close();
362+ m_semaphoreLock = null;
363+ }
364+ }
365+ finally
366+ {
367+ m_disposed = true; // Prevent duplicate dispose.
368+ }
369+ }
370+ }
371+
372+ /// <summary>
373+ /// Tries to enter the lock in read mode.
374+ /// </summary>
375+ /// <remarks>
376+ /// 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"/>.
377+ /// One <see cref="ExitReadLock"/> should be called for each <see cref="EnterReadLock"/> or <see cref="TryEnterReadLock"/>.
378+ /// </remarks>
379+ public void EnterReadLock()
380+ {
381+ TryEnterReadLock(Timeout.Infinite);
382+ }
383+
384+ /// <summary>
385+ /// Tries to enter the lock in write mode.
386+ /// </summary>
387+ /// <remarks>
388+ /// 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"/>.
389+ /// One <see cref="ExitWriteLock"/> should be called for each <see cref="EnterWriteLock"/> or <see cref="TryEnterWriteLock"/>.
390+ /// </remarks>
391+ public void EnterWriteLock()
392+ {
393+ TryEnterWriteLock(Timeout.Infinite);
394+ }
395+
396+ /// <summary>
397+ /// Exits read mode and returns the prior read lock count.
398+ /// </summary>
399+ /// <remarks>
400+ /// 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"/>.
401+ /// One <see cref="ExitReadLock"/> should be called for each <see cref="EnterReadLock"/> or <see cref="TryEnterReadLock"/>.
402+ /// </remarks>
403+ public int ExitReadLock()
404+ {
405+ // Release the semaphore lock and restore the slot
406+ return m_concurrencyLock.Release();
407+ }
408+
409+ /// <summary>
410+ /// Exits write mode.
411+ /// </summary>
412+ /// <remarks>
413+ /// 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"/>.
414+ /// One <see cref="ExitWriteLock"/> should be called for each <see cref="EnterWriteLock"/> or <see cref="TryEnterWriteLock"/>.
415+ /// </remarks>
416+ public void ExitWriteLock()
417+ {
418+ // Release semaphore synchronization mutex lock
419+ m_semaphoreLock.ReleaseMutex();
420+ }
421+
422+ /// <summary>
423+ /// Tries to enter the lock in read mode, with an optional time-out.
424+ /// </summary>
425+ /// <param name="millisecondsTimeout">The number of milliseconds to wait, or -1 (<see cref="Timeout.Infinite"/>) to wait indefinitely.</param>
426+ /// <returns><c>true</c> if the calling thread entered read mode, otherwise, <c>false</c>.</returns>
427+ /// <remarks>
428+ /// 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"/>.
429+ /// One <see cref="ExitReadLock"/> should be called for each <see cref="EnterReadLock"/> or <see cref="TryEnterReadLock"/>.
430+ /// </remarks>
431+ public bool TryEnterReadLock(int millisecondsTimeout)
432+ {
433+ bool success = false;
434+
435+ try
436+ {
437+ // Wait for system level mutex lock to synchronize access to semaphore
438+ m_semaphoreLock.WaitOne();
439+ }
440+ catch (AbandonedMutexException)
441+ {
442+ // Abnormal application terminations can leave a mutex abandoned, in
443+ // this case we now own the mutex so we just ignore the exception
444+ }
445+
446+ try
447+ {
448+ // Wait for a semaphore slot to become available
449+ success = m_concurrencyLock.WaitOne(millisecondsTimeout);
450+ }
451+ finally
452+ {
453+ // Release mutex so others can access the semaphore
454+ m_semaphoreLock.ReleaseMutex();
455+ }
456+
457+ return success;
458+ }
459+
460+ /// <summary>
461+ /// Tries to enter the lock in write mode, with an optional time-out.
462+ /// </summary>
463+ /// <param name="millisecondsTimeout">The number of milliseconds to wait, or -1 (<see cref="Timeout.Infinite"/>) to wait indefinitely.</param>
464+ /// <returns><c>true</c> if the calling thread entered write mode, otherwise, <c>false</c>.</returns>
465+ /// <remarks>
466+ /// 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"/>.
467+ /// One <see cref="ExitWriteLock"/> should be called for each <see cref="EnterWriteLock"/> or <see cref="TryEnterWriteLock"/>.
468+ /// </remarks>
469+ public bool TryEnterWriteLock(int millisecondsTimeout)
470+ {
471+ bool success = false;
472+ long startTime;
473+
474+ try
475+ {
476+ // Wait for system level mutex lock to synchronize access to semaphore
477+ m_semaphoreLock.WaitOne();
478+ }
479+ catch (AbandonedMutexException)
480+ {
481+ // Abnormal application terminations can leave a mutex abandoned, in
482+ // this case we now own the mutex so we just ignore the exception
483+ }
484+
485+ try
486+ {
487+ // At this point no other threads can aquire read or write access since we own the mutex.
488+ // Other threads may be busy reading, so we wait until all semaphore slots become available.
489+ // The only way to get a semaphore slot count is to execute a successful wait and release.
490+ startTime = DateTime.UtcNow.Ticks;
491+
492+ if (success = m_concurrencyLock.WaitOne(millisecondsTimeout))
493+ {
494+ int count = m_concurrencyLock.Release();
495+ int adjustedTimeout = millisecondsTimeout;
496+
497+ // After a successful wait and release the returned semaphore slot count will be -1 of the
498+ // actual count since we owned one slot after a successful wait.
499+ while (success && count != m_maximumConcurrentLocks - 1)
500+ {
501+ // Sleep to allow any remaining reads to complete
502+ Thread.Sleep(1);
503+
504+ // Continue to adjust remaining time to accomodate user specified millisecond timeout
505+ if (millisecondsTimeout > 0)
506+ adjustedTimeout = millisecondsTimeout - (int)Ticks.ToMilliseconds(DateTime.UtcNow.Ticks - startTime);
507+
508+ if (adjustedTimeout < 0)
509+ adjustedTimeout = 0;
510+
511+ if (success = m_concurrencyLock.WaitOne(adjustedTimeout))
512+ count = m_concurrencyLock.Release();
513+ }
514+ }
515+ }
516+ finally
517+ {
518+ // If lock failed, release mutex so others can access the semaphore
519+ if (!success)
520+ m_semaphoreLock.ReleaseMutex();
521+ }
522+
523+ // Successfully entering write lock leaves state of semphore locking mutex "owned", it is critical that
524+ // consumer call ExitWriteLock upon completion of write action to release mutex regardless of whether
525+ // their code succeeds or fails, that is, consumer should use the finally clause of a "try/finally"
526+ // expression to ExitWriteLock.
527+ return success;
528+ }
529+
530+ #endregion
531+ }
532+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t