History

GSF.Core: Improved null handling for InterprocessReaderWriterLock and InterprocessCache; and general code cleanup.

J. Ritchie Carroll committed 5 years ago

Commit 5ffac611 parent 30e79942 files · +104 −183Browse files

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

Unified · Split

Source/Libraries/GSF.Core/Threading/InterprocessReaderWriterLock.cs+27−46
@@ -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 #endregion88 #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 MaximumConcurrentLocks95 public int MaximumConcurrentLocks => m_maximumConcurrentLocks;
98 {
99 get
100 {
101 return m_maximumConcurrentLocks;
102 }
103 }
104 96
105 #endregion97 #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 try121 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 finally129
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 try246 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

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