Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
ReaderWriterLockSlim.cs
Go to the documentation of this file.
3
4namespace System.Threading;
5
7{
8 private struct TimeoutTracker
9 {
10 private readonly int _total;
11
12 private readonly int _start;
13
15 {
16 get
17 {
18 if (_total == -1 || _total == 0)
19 {
20 return _total;
21 }
22 int num = Environment.TickCount - _start;
23 if (num < 0 || num >= _total)
24 {
25 return 0;
26 }
27 return _total - num;
28 }
29 }
30
31 public bool IsExpired => RemainingMilliseconds == 0;
32
34 {
35 long num = (long)timeout.TotalMilliseconds;
36 if (num < -1 || num > int.MaxValue)
37 {
38 throw new ArgumentOutOfRangeException("timeout");
39 }
40 _total = (int)num;
41 if (_total != -1 && _total != 0)
42 {
44 }
45 else
46 {
47 _start = 0;
48 }
49 }
50
52 {
53 if (millisecondsTimeout < -1)
54 {
55 throw new ArgumentOutOfRangeException("millisecondsTimeout");
56 }
58 if (_total != -1 && _total != 0)
59 {
61 }
62 else
63 {
64 _start = 0;
65 }
66 }
67 }
68
69 private struct SpinLock
70 {
71 private int _isLocked;
72
74
76
78
80 {
81 return (reason & EnterSpinLockReason.OperationMask) switch
82 {
83 EnterSpinLockReason.EnterAnyRead => 0,
84 EnterSpinLockReason.ExitAnyRead => 1,
85 EnterSpinLockReason.EnterWrite => 65536,
86 _ => 65537,
87 };
88 }
89
91 {
92 return reason switch
93 {
94 EnterSpinLockReason.EnterAnyRead => EnterForEnterAnyReadDeprioritizedCount != 0,
95 EnterSpinLockReason.EnterWrite => EnterForEnterAnyWriteDeprioritizedCount != 0,
96 EnterSpinLockReason.UpgradeToWrite => EnterForEnterAnyWriteDeprioritizedCount > 1,
97 _ => false,
98 };
99 }
100
101 [MethodImpl(MethodImplOptions.AggressiveInlining)]
102 private bool TryEnter()
103 {
104 return Interlocked.CompareExchange(ref _isLocked, 1, 0) == 0;
105 }
106
107 [MethodImpl(MethodImplOptions.AggressiveInlining)]
108 public void Enter(EnterSpinLockReason reason)
109 {
110 if (!TryEnter())
111 {
112 EnterSpin(reason);
113 }
114 }
115
116 private void EnterSpin(EnterSpinLockReason reason)
117 {
118 int enterDeprioritizationStateChange = GetEnterDeprioritizationStateChange(reason);
119 if (enterDeprioritizationStateChange != 0)
120 {
121 Interlocked.Add(ref _enterDeprioritizationState, enterDeprioritizationStateChange);
122 }
123 int processorCount = Environment.ProcessorCount;
124 int num = 0;
125 while (true)
126 {
127 if (num < 10 && processorCount > 1)
128 {
129 Thread.SpinWait(20 * (num + 1));
130 }
131 else if (num < 15)
132 {
133 Thread.Sleep(0);
134 }
135 else
136 {
137 Thread.Sleep(1);
138 }
139 if (!IsEnterDeprioritized(reason))
140 {
141 if (_isLocked == 0 && TryEnter())
142 {
143 break;
144 }
145 }
146 else if (num >= 20)
147 {
148 reason |= EnterSpinLockReason.Wait;
149 num = -1;
150 }
151 num++;
152 }
153 if (enterDeprioritizationStateChange != 0)
154 {
155 Interlocked.Add(ref _enterDeprioritizationState, -enterDeprioritizationStateChange);
156 }
157 }
158
159 public void Exit()
160 {
161 Volatile.Write(ref _isLocked, 0);
162 }
163 }
164
165 [Flags]
166 private enum WaiterStates : byte
167 {
168 None = 0,
169 NoWaiters = 1,
172 }
173
175 {
176 EnterAnyRead = 0,
177 ExitAnyRead = 1,
178 EnterWrite = 2,
179 UpgradeToWrite = 3,
181 ExitAnyWrite = 5,
182 OperationMask = 7,
183 Wait = 8
184 }
185
186 private enum EnterLockType
187 {
188 Read,
190 Write,
192 }
193
194 private readonly bool _fIsReentrant;
195
197
198 private uint _numWriteWaiters;
199
200 private uint _numReadWaiters;
201
203
204 private uint _numUpgradeWaiters;
205
207
209
210 private int _writeLockOwnerId;
211
213
215
217
219
220 private static long s_nextLockID;
221
222 private readonly long _lockID;
223
224 [ThreadStatic]
225 private static ReaderWriterCount t_rwc;
226
228
229 private uint _owners;
230
231 private bool _fDisposed;
232
233 private bool HasNoWaiters
234 {
235 get
236 {
237 return (_waiterStates & WaiterStates.NoWaiters) != 0;
238 }
239 set
240 {
241 if (value)
242 {
243 _waiterStates |= WaiterStates.NoWaiters;
244 }
245 else
246 {
247 _waiterStates &= ~WaiterStates.NoWaiters;
248 }
249 }
250 }
251
252 public bool IsReadLockHeld
253 {
254 get
255 {
256 if (RecursiveReadCount > 0)
257 {
258 return true;
259 }
260 return false;
261 }
262 }
263
265 {
266 get
267 {
268 if (RecursiveUpgradeCount > 0)
269 {
270 return true;
271 }
272 return false;
273 }
274 }
275
276 public bool IsWriteLockHeld
277 {
278 get
279 {
280 if (RecursiveWriteCount > 0)
281 {
282 return true;
283 }
284 return false;
285 }
286 }
287
289 {
290 get
291 {
292 if (_fIsReentrant)
293 {
294 return LockRecursionPolicy.SupportsRecursion;
295 }
296 return LockRecursionPolicy.NoRecursion;
297 }
298 }
299
301 {
302 get
303 {
304 int numReaders = (int)GetNumReaders();
305 if (_upgradeLockOwnerId != -1)
306 {
307 return numReaders - 1;
308 }
309 return numReaders;
310 }
311 }
312
314 {
315 get
316 {
317 int result = 0;
318 ReaderWriterCount threadRWCount = GetThreadRWCount(dontAllocate: true);
319 if (threadRWCount != null)
320 {
321 result = threadRWCount.readercount;
322 }
323 return result;
324 }
325 }
326
328 {
329 get
330 {
331 if (_fIsReentrant)
332 {
333 int result = 0;
334 ReaderWriterCount threadRWCount = GetThreadRWCount(dontAllocate: true);
335 if (threadRWCount != null)
336 {
337 result = threadRWCount.upgradecount;
338 }
339 return result;
340 }
342 {
343 return 1;
344 }
345 return 0;
346 }
347 }
348
350 {
351 get
352 {
353 if (_fIsReentrant)
354 {
355 int result = 0;
356 ReaderWriterCount threadRWCount = GetThreadRWCount(dontAllocate: true);
357 if (threadRWCount != null)
358 {
359 result = threadRWCount.writercount;
360 }
361 return result;
362 }
364 {
365 return 1;
366 }
367 return 0;
368 }
369 }
370
372
374
376
378 {
381 }
382
385 {
386 }
387
389 {
390 if (recursionPolicy == LockRecursionPolicy.SupportsRecursion)
391 {
392 _fIsReentrant = true;
393 }
395 _waiterStates = WaiterStates.NoWaiters;
397 }
398
399 [MethodImpl(MethodImplOptions.AggressiveInlining)]
400 private static bool IsRWEntryEmpty(ReaderWriterCount rwc)
401 {
402 if (rwc.lockID == 0L)
403 {
404 return true;
405 }
406 if (rwc.readercount == 0 && rwc.writercount == 0 && rwc.upgradecount == 0)
407 {
408 return true;
409 }
410 return false;
411 }
412
414 {
415 return lrwc.lockID != _lockID;
416 }
417
418 [MethodImpl(MethodImplOptions.AggressiveInlining)]
419 private ReaderWriterCount GetThreadRWCount(bool dontAllocate)
420 {
422 ReaderWriterCount readerWriterCount = null;
423 while (next != null)
424 {
425 if (next.lockID == _lockID)
426 {
427 return next;
428 }
429 if (!dontAllocate && readerWriterCount == null && IsRWEntryEmpty(next))
430 {
431 readerWriterCount = next;
432 }
433 next = next.next;
434 }
435 if (dontAllocate)
436 {
437 return null;
438 }
439 if (readerWriterCount == null)
440 {
441 readerWriterCount = new ReaderWriterCount();
442 readerWriterCount.next = t_rwc;
443 t_rwc = readerWriterCount;
444 }
445 readerWriterCount.lockID = _lockID;
446 return readerWriterCount;
447 }
448
449 public void EnterReadLock()
450 {
452 }
453
455 {
457 }
458
463
468
470 {
471 if (_fDisposed)
472 {
473 throw new ObjectDisposedException(null);
474 }
475 int currentManagedThreadId = Environment.CurrentManagedThreadId;
476 ReaderWriterCount threadRWCount;
477 if (!_fIsReentrant)
478 {
479 if (currentManagedThreadId == _writeLockOwnerId)
480 {
482 }
483 _spinLock.Enter(EnterSpinLockReason.EnterAnyRead);
484 threadRWCount = GetThreadRWCount(dontAllocate: false);
485 if (threadRWCount.readercount > 0)
486 {
487 _spinLock.Exit();
489 }
490 if (currentManagedThreadId == _upgradeLockOwnerId)
491 {
492 threadRWCount.readercount++;
493 _owners++;
494 _spinLock.Exit();
495 return true;
496 }
497 }
498 else
499 {
500 _spinLock.Enter(EnterSpinLockReason.EnterAnyRead);
501 threadRWCount = GetThreadRWCount(dontAllocate: false);
502 if (threadRWCount.readercount > 0)
503 {
504 threadRWCount.readercount++;
505 _spinLock.Exit();
506 return true;
507 }
508 if (currentManagedThreadId == _upgradeLockOwnerId)
509 {
510 threadRWCount.readercount++;
511 _owners++;
512 _spinLock.Exit();
514 return true;
515 }
516 if (currentManagedThreadId == _writeLockOwnerId)
517 {
518 threadRWCount.readercount++;
519 _owners++;
520 _spinLock.Exit();
521 return true;
522 }
523 }
524 bool flag = true;
525 int num = 0;
526 while (true)
527 {
528 if (_owners < 268435454)
529 {
530 _owners++;
531 threadRWCount.readercount++;
532 _spinLock.Exit();
533 return flag;
534 }
535 if (timeout.IsExpired)
536 {
537 _spinLock.Exit();
538 return false;
539 }
540 if (num < 20 && ShouldSpinForEnterAnyRead())
541 {
542 _spinLock.Exit();
543 num++;
544 SpinWait(num);
545 _spinLock.Enter(EnterSpinLockReason.EnterAnyRead);
546 if (IsRwHashEntryChanged(threadRWCount))
547 {
548 threadRWCount = GetThreadRWCount(dontAllocate: false);
549 }
550 }
551 else if (_readEvent == null)
552 {
554 if (IsRwHashEntryChanged(threadRWCount))
555 {
556 threadRWCount = GetThreadRWCount(dontAllocate: false);
557 }
558 }
559 else
560 {
562 if (!flag)
563 {
564 break;
565 }
566 if (IsRwHashEntryChanged(threadRWCount))
567 {
568 threadRWCount = GetThreadRWCount(dontAllocate: false);
569 }
570 }
571 }
572 return false;
573 }
574
575 public void EnterWriteLock()
576 {
578 }
579
581 {
583 }
584
589
594
596 {
597 if (_fDisposed)
598 {
599 throw new ObjectDisposedException(null);
600 }
601 int currentManagedThreadId = Environment.CurrentManagedThreadId;
602 bool flag = false;
603 ReaderWriterCount threadRWCount;
604 if (!_fIsReentrant)
605 {
606 if (currentManagedThreadId == _writeLockOwnerId)
607 {
609 }
610 EnterSpinLockReason reason;
611 if (currentManagedThreadId == _upgradeLockOwnerId)
612 {
613 flag = true;
614 reason = EnterSpinLockReason.UpgradeToWrite;
615 }
616 else
617 {
618 reason = EnterSpinLockReason.EnterWrite;
619 }
620 _spinLock.Enter(reason);
621 threadRWCount = GetThreadRWCount(dontAllocate: true);
622 if (threadRWCount != null && threadRWCount.readercount > 0)
623 {
624 _spinLock.Exit();
626 }
627 }
628 else
629 {
630 EnterSpinLockReason reason2 = ((currentManagedThreadId == _writeLockOwnerId) ? EnterSpinLockReason.EnterRecursiveWrite : ((currentManagedThreadId != _upgradeLockOwnerId) ? EnterSpinLockReason.EnterWrite : EnterSpinLockReason.UpgradeToWrite));
631 _spinLock.Enter(reason2);
632 threadRWCount = GetThreadRWCount(dontAllocate: false);
633 if (currentManagedThreadId == _writeLockOwnerId)
634 {
635 threadRWCount.writercount++;
636 _spinLock.Exit();
637 return true;
638 }
639 if (currentManagedThreadId == _upgradeLockOwnerId)
640 {
641 flag = true;
642 }
643 else if (threadRWCount.readercount > 0)
644 {
645 _spinLock.Exit();
647 }
648 }
649 bool flag2 = true;
650 int num = 0;
651 while (true)
652 {
653 if (IsWriterAcquired())
654 {
656 break;
657 }
658 if (flag)
659 {
660 uint numReaders = GetNumReaders();
661 if (numReaders == 1)
662 {
664 break;
665 }
666 if (numReaders == 2 && threadRWCount != null)
667 {
668 if (IsRwHashEntryChanged(threadRWCount))
669 {
670 threadRWCount = GetThreadRWCount(dontAllocate: false);
671 }
672 if (threadRWCount.readercount > 0)
673 {
675 break;
676 }
677 }
678 }
679 if (timeout.IsExpired)
680 {
681 _spinLock.Exit();
682 return false;
683 }
684 if (num < 20 && ShouldSpinForEnterAnyWrite(flag))
685 {
686 _spinLock.Exit();
687 num++;
688 SpinWait(num);
689 _spinLock.Enter(flag ? EnterSpinLockReason.UpgradeToWrite : EnterSpinLockReason.EnterWrite);
690 }
691 else if (flag)
692 {
693 if (_waitUpgradeEvent == null)
694 {
696 }
698 {
699 return false;
700 }
701 }
702 else if (_writeEvent == null)
703 {
705 }
707 {
708 return false;
709 }
710 }
711 if (_fIsReentrant)
712 {
713 if (IsRwHashEntryChanged(threadRWCount))
714 {
715 threadRWCount = GetThreadRWCount(dontAllocate: false);
716 }
717 threadRWCount.writercount++;
718 }
719 _spinLock.Exit();
720 _writeLockOwnerId = currentManagedThreadId;
721 return true;
722 }
723
725 {
727 }
728
733
738
743
745 {
746 if (_fDisposed)
747 {
748 throw new ObjectDisposedException(null);
749 }
750 int currentManagedThreadId = Environment.CurrentManagedThreadId;
751 ReaderWriterCount threadRWCount;
752 if (!_fIsReentrant)
753 {
754 if (currentManagedThreadId == _upgradeLockOwnerId)
755 {
757 }
758 if (currentManagedThreadId == _writeLockOwnerId)
759 {
761 }
762 _spinLock.Enter(EnterSpinLockReason.EnterAnyRead);
763 threadRWCount = GetThreadRWCount(dontAllocate: true);
764 if (threadRWCount != null && threadRWCount.readercount > 0)
765 {
766 _spinLock.Exit();
768 }
769 }
770 else
771 {
772 _spinLock.Enter(EnterSpinLockReason.EnterAnyRead);
773 threadRWCount = GetThreadRWCount(dontAllocate: false);
774 if (currentManagedThreadId == _upgradeLockOwnerId)
775 {
776 threadRWCount.upgradecount++;
777 _spinLock.Exit();
778 return true;
779 }
780 if (currentManagedThreadId == _writeLockOwnerId)
781 {
782 _owners++;
783 _upgradeLockOwnerId = currentManagedThreadId;
784 threadRWCount.upgradecount++;
785 if (threadRWCount.readercount > 0)
786 {
788 }
789 _spinLock.Exit();
790 return true;
791 }
792 if (threadRWCount.readercount > 0)
793 {
794 _spinLock.Exit();
796 }
797 }
798 bool flag = true;
799 int num = 0;
800 while (true)
801 {
802 if (_upgradeLockOwnerId == -1 && _owners < 268435454)
803 {
804 _owners++;
805 _upgradeLockOwnerId = currentManagedThreadId;
806 if (_fIsReentrant)
807 {
808 if (IsRwHashEntryChanged(threadRWCount))
809 {
810 threadRWCount = GetThreadRWCount(dontAllocate: false);
811 }
812 threadRWCount.upgradecount++;
813 }
814 break;
815 }
816 if (timeout.IsExpired)
817 {
818 _spinLock.Exit();
819 return false;
820 }
821 if (num < 20 && ShouldSpinForEnterAnyRead())
822 {
823 _spinLock.Exit();
824 num++;
825 SpinWait(num);
826 _spinLock.Enter(EnterSpinLockReason.EnterAnyRead);
827 }
828 else if (_upgradeEvent == null)
829 {
830 LazyCreateEvent(ref _upgradeEvent, EnterLockType.UpgradeableRead);
831 }
832 else if (!WaitOnEvent(_upgradeEvent, ref _numUpgradeWaiters, timeout, EnterLockType.UpgradeableRead))
833 {
834 return false;
835 }
836 }
837 _spinLock.Exit();
838 return true;
839 }
840
841 public void ExitReadLock()
842 {
844 ReaderWriterCount threadRWCount = GetThreadRWCount(dontAllocate: true);
845 if (threadRWCount == null || threadRWCount.readercount < 1)
846 {
847 _spinLock.Exit();
849 }
850 if (_fIsReentrant)
851 {
852 if (threadRWCount.readercount > 1)
853 {
854 threadRWCount.readercount--;
855 _spinLock.Exit();
856 return;
857 }
859 {
861 }
862 }
863 _owners--;
864 threadRWCount.readercount--;
866 }
867
868 public void ExitWriteLock()
869 {
870 if (!_fIsReentrant)
871 {
873 {
875 }
876 _spinLock.Enter(EnterSpinLockReason.ExitAnyWrite);
877 }
878 else
879 {
880 _spinLock.Enter(EnterSpinLockReason.ExitAnyWrite);
881 ReaderWriterCount threadRWCount = GetThreadRWCount(dontAllocate: false);
882 if (threadRWCount == null)
883 {
884 _spinLock.Exit();
886 }
887 if (threadRWCount.writercount < 1)
888 {
889 _spinLock.Exit();
891 }
892 threadRWCount.writercount--;
893 if (threadRWCount.writercount > 0)
894 {
895 _spinLock.Exit();
896 return;
897 }
898 }
902 }
903
905 {
906 if (!_fIsReentrant)
907 {
909 {
911 }
913 }
914 else
915 {
917 ReaderWriterCount threadRWCount = GetThreadRWCount(dontAllocate: true);
918 if (threadRWCount == null)
919 {
920 _spinLock.Exit();
922 }
923 if (threadRWCount.upgradecount < 1)
924 {
925 _spinLock.Exit();
927 }
928 threadRWCount.upgradecount--;
929 if (threadRWCount.upgradecount > 0)
930 {
931 _spinLock.Exit();
932 return;
933 }
935 }
936 _owners--;
939 }
940
941 private void LazyCreateEvent([NotNull] ref EventWaitHandle waitEvent, EnterLockType enterLockType)
942 {
943 _spinLock.Exit();
944 EventWaitHandle eventWaitHandle = new EventWaitHandle(initialState: false, (enterLockType == EnterLockType.Read) ? EventResetMode.ManualReset : EventResetMode.AutoReset);
945 EnterSpinLockReason reason;
946 switch (enterLockType)
947 {
948 case EnterLockType.Read:
949 case EnterLockType.UpgradeableRead:
950 reason = EnterSpinLockReason.Wait;
951 break;
952 case EnterLockType.Write:
953 reason = (EnterSpinLockReason)10;
954 break;
955 default:
956 reason = (EnterSpinLockReason)11;
957 break;
958 }
959 _spinLock.Enter(reason);
960 if (waitEvent == null)
961 {
962 waitEvent = eventWaitHandle;
963 }
964 else
965 {
966 eventWaitHandle.Dispose();
967 }
968 }
969
970 private bool WaitOnEvent(EventWaitHandle waitEvent, ref uint numWaiters, TimeoutTracker timeout, EnterLockType enterLockType)
971 {
972 WaiterStates waiterStates = WaiterStates.None;
973 EnterSpinLockReason reason;
974 switch (enterLockType)
975 {
976 case EnterLockType.UpgradeableRead:
977 waiterStates = WaiterStates.UpgradeableReadWaiterSignaled;
978 goto case EnterLockType.Read;
979 case EnterLockType.Read:
980 reason = EnterSpinLockReason.EnterAnyRead;
981 break;
982 case EnterLockType.Write:
983 waiterStates = WaiterStates.WriteWaiterSignaled;
984 reason = EnterSpinLockReason.EnterWrite;
985 break;
986 default:
987 reason = EnterSpinLockReason.UpgradeToWrite;
988 break;
989 }
990 if (waiterStates != 0 && (_waiterStates & waiterStates) != 0)
991 {
992 _waiterStates &= (WaiterStates)(byte)(~(int)waiterStates);
993 }
994 waitEvent.Reset();
995 numWaiters++;
996 HasNoWaiters = false;
997 if (_numWriteWaiters == 1)
998 {
1000 }
1001 if (_numWriteUpgradeWaiters == 1)
1002 {
1004 }
1005 bool flag = false;
1006 _spinLock.Exit();
1007 try
1008 {
1009 flag = waitEvent.WaitOne(timeout.RemainingMilliseconds);
1010 }
1011 finally
1012 {
1013 _spinLock.Enter(reason);
1014 numWaiters--;
1015 if (flag && waiterStates != 0 && (_waiterStates & waiterStates) != 0)
1016 {
1017 _waiterStates &= (WaiterStates)(byte)(~(int)waiterStates);
1018 }
1020 {
1021 HasNoWaiters = true;
1022 }
1023 if (_numWriteWaiters == 0)
1024 {
1026 }
1027 if (_numWriteUpgradeWaiters == 0)
1028 {
1030 }
1031 if (!flag)
1032 {
1033 if (enterLockType >= EnterLockType.Write)
1034 {
1036 }
1037 else
1038 {
1039 _spinLock.Exit();
1040 }
1041 }
1042 }
1043 return flag;
1044 }
1045
1047 {
1048 if (HasNoWaiters)
1049 {
1050 _spinLock.Exit();
1051 }
1052 else
1053 {
1055 }
1056 }
1057
1059 {
1060 uint numReaders = GetNumReaders();
1061 if (_fIsReentrant && _numWriteUpgradeWaiters != 0 && _fUpgradeThreadHoldingRead && numReaders == 2)
1062 {
1063 _spinLock.Exit();
1065 }
1066 else if (numReaders == 1 && _numWriteUpgradeWaiters != 0)
1067 {
1068 _spinLock.Exit();
1070 }
1071 else if (numReaders == 0 && _numWriteWaiters != 0)
1072 {
1073 WaiterStates waiterStates = _waiterStates & WaiterStates.WriteWaiterSignaled;
1074 if (waiterStates == WaiterStates.None)
1075 {
1076 _waiterStates |= WaiterStates.WriteWaiterSignaled;
1077 }
1078 _spinLock.Exit();
1079 if (waiterStates == WaiterStates.None)
1080 {
1081 _writeEvent.Set();
1082 }
1083 }
1084 else
1085 {
1087 }
1088 }
1089
1091 {
1093 {
1094 _spinLock.Exit();
1095 return;
1096 }
1097 bool flag = _numReadWaiters != 0;
1098 bool flag2 = _numUpgradeWaiters != 0 && _upgradeLockOwnerId == -1;
1099 if (flag2)
1100 {
1101 if ((_waiterStates & WaiterStates.UpgradeableReadWaiterSignaled) == 0)
1102 {
1103 _waiterStates |= WaiterStates.UpgradeableReadWaiterSignaled;
1104 }
1105 else
1106 {
1107 flag2 = false;
1108 }
1109 }
1110 _spinLock.Exit();
1111 if (flag)
1112 {
1113 _readEvent.Set();
1114 }
1115 if (flag2)
1116 {
1118 }
1119 }
1120
1121 private bool IsWriterAcquired()
1122 {
1123 return (_owners & 0xBFFFFFFFu) == 0;
1124 }
1125
1126 private void SetWriterAcquired()
1127 {
1128 _owners |= 2147483648u;
1129 }
1130
1131 private void ClearWriterAcquired()
1132 {
1133 _owners &= 2147483647u;
1134 }
1135
1136 private void SetWritersWaiting()
1137 {
1138 _owners |= 1073741824u;
1139 }
1140
1141 private void ClearWritersWaiting()
1142 {
1143 _owners &= 3221225471u;
1144 }
1145
1146 private void SetUpgraderWaiting()
1147 {
1148 _owners |= 536870912u;
1149 }
1150
1152 {
1153 _owners &= 3758096383u;
1154 }
1155
1156 private uint GetNumReaders()
1157 {
1158 return _owners & 0xFFFFFFFu;
1159 }
1160
1162 {
1163 if (!HasNoWaiters)
1164 {
1165 if (_numWriteWaiters == 0)
1166 {
1167 return _numWriteUpgradeWaiters == 0;
1168 }
1169 return false;
1170 }
1171 return true;
1172 }
1173
1174 private bool ShouldSpinForEnterAnyWrite(bool isUpgradeToWrite)
1175 {
1176 if (!isUpgradeToWrite)
1177 {
1178 return _numWriteUpgradeWaiters == 0;
1179 }
1180 return true;
1181 }
1182
1183 private static void SpinWait(int spinCount)
1184 {
1185 if (spinCount < 5 && Environment.ProcessorCount > 1)
1186 {
1187 Thread.SpinWait(20 * spinCount);
1188 }
1189 else
1190 {
1191 Thread.Sleep(0);
1192 }
1193 }
1194
1195 public void Dispose()
1196 {
1197 Dispose(disposing: true);
1198 }
1199
1200 private void Dispose(bool disposing)
1201 {
1202 if (disposing && !_fDisposed)
1203 {
1205 {
1207 }
1209 {
1211 }
1212 if (_writeEvent != null)
1213 {
1215 _writeEvent = null;
1216 }
1217 if (_readEvent != null)
1218 {
1220 _readEvent = null;
1221 }
1222 if (_upgradeEvent != null)
1223 {
1225 _upgradeEvent = null;
1226 }
1227 if (_waitUpgradeEvent != null)
1228 {
1230 _waitUpgradeEvent = null;
1231 }
1232 _fDisposed = true;
1233 }
1234 }
1235}
static int ProcessorCount
static int CurrentManagedThreadId
static int TickCount
static string SynchronizationLockException_IncorrectDispose
Definition SR.cs:2052
static string SynchronizationLockException_MisMatchedUpgrade
Definition SR.cs:2048
static string LockRecursionException_WriteAfterReadNotAllowed
Definition SR.cs:2046
static string SynchronizationLockException_MisMatchedWrite
Definition SR.cs:2058
static string LockRecursionException_UpgradeAfterReadNotAllowed
Definition SR.cs:2054
static string LockRecursionException_ReadAfterWriteNotAllowed
Definition SR.cs:2038
static string LockRecursionException_RecursiveReadNotAllowed
Definition SR.cs:2040
static string LockRecursionException_RecursiveWriteNotAllowed
Definition SR.cs:2042
static string LockRecursionException_RecursiveUpgradeNotAllowed
Definition SR.cs:2044
static string SynchronizationLockException_MisMatchedRead
Definition SR.cs:2050
static string LockRecursionException_UpgradeAfterWriteNotAllowed
Definition SR.cs:2056
Definition SR.cs:7
static int CompareExchange(ref int location1, int value, int comparand)
static int Add(ref int location1, int value)
static int Increment(ref int location)
static bool IsRWEntryEmpty(ReaderWriterCount rwc)
void LazyCreateEvent([NotNull] ref EventWaitHandle waitEvent, EnterLockType enterLockType)
bool TryEnterReadLock(int millisecondsTimeout)
bool TryEnterWriteLockCore(TimeoutTracker timeout)
bool TryEnterWriteLock(TimeoutTracker timeout)
ReaderWriterCount GetThreadRWCount(bool dontAllocate)
bool TryEnterUpgradeableReadLock(TimeoutTracker timeout)
bool TryEnterReadLock(TimeoutTracker timeout)
bool ShouldSpinForEnterAnyWrite(bool isUpgradeToWrite)
bool TryEnterWriteLock(int millisecondsTimeout)
bool TryEnterUpgradeableReadLock(int millisecondsTimeout)
bool WaitOnEvent(EventWaitHandle waitEvent, ref uint numWaiters, TimeoutTracker timeout, EnterLockType enterLockType)
ReaderWriterLockSlim(LockRecursionPolicy recursionPolicy)
bool TryEnterReadLockCore(TimeoutTracker timeout)
bool IsRwHashEntryChanged(ReaderWriterCount lrwc)
bool TryEnterUpgradeableReadLockCore(TimeoutTracker timeout)
static void Sleep(int millisecondsTimeout)
Definition Thread.cs:658
static void SpinWait(int iterations)
Definition Thread.cs:404
static void Write(ref bool location, bool value)
Definition Volatile.cs:74
virtual void Dispose(bool explicitDisposing)
virtual bool WaitOne(int millisecondsTimeout)
static int GetEnterDeprioritizationStateChange(EnterSpinLockReason reason)
bool IsEnterDeprioritized(EnterSpinLockReason reason)