Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit e3d6fea

Browse files
ViktorHoferdanmoseley
authored andcommitted
Move Regex Shared/Exclusive Reference to own file
1 parent f117967 commit e3d6fea

File tree

3 files changed

+131
-135
lines changed

3 files changed

+131
-135
lines changed

src/System.Text.RegularExpressions/src/System.Text.RegularExpressions.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
<Compile Include="System\Text\RegularExpressions\GroupCollection.cs" />
2222
<Compile Include="System\Text\RegularExpressions\Match.cs" />
2323
<Compile Include="System\Text\RegularExpressions\MatchCollection.cs" />
24-
<Compile Include="System\Text\RegularExpressions\Regex.Cache.cs" />
24+
<Compile Include="System\Text\RegularExpressions\Reference.cs" />
25+
<Compile Include="System\Text\RegularExpressions\Regex.Cache.cs" />
2526
<Compile Include="System\Text\RegularExpressions\Regex.cs" />
2627
<Compile Include="System\Text\RegularExpressions\Regex.Match.cs" />
2728
<Compile Include="System\Text\RegularExpressions\Regex.Replace.cs" />
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Threading;
6+
7+
namespace System.Text.RegularExpressions
8+
{
9+
/// <summary>
10+
/// Used to cache one exclusive runner reference
11+
/// </summary>
12+
internal sealed class ExclusiveReference
13+
{
14+
private RegexRunner _ref;
15+
private object _obj;
16+
private int _locked;
17+
18+
/// <summary>
19+
/// Return an object and grab an exclusive lock.
20+
///
21+
/// If the exclusive lock can't be obtained, null is returned;
22+
/// if the object can't be returned, the lock is released.
23+
/// </summary>
24+
internal object Get()
25+
{
26+
// try to obtain the lock
27+
28+
if (0 == Interlocked.Exchange(ref _locked, 1))
29+
{
30+
// grab reference
31+
object obj = _ref;
32+
33+
// release the lock and return null if no reference
34+
if (obj == null)
35+
{
36+
_locked = 0;
37+
38+
return null;
39+
}
40+
41+
// remember the reference and keep the lock
42+
_obj = obj;
43+
44+
return obj;
45+
}
46+
47+
return null;
48+
}
49+
50+
/// <summary>
51+
/// Release an object back to the cache.
52+
///
53+
/// If the object is the one that's under lock, the lock is released.
54+
/// If there is no cached object, then the lock is obtained and the object is placed in the cache.
55+
/// </summary>
56+
internal void Release(object obj)
57+
{
58+
if (obj == null)
59+
throw new ArgumentNullException(nameof(obj));
60+
61+
// if this reference owns the lock, release it
62+
if (_obj == obj)
63+
{
64+
_obj = null;
65+
_locked = 0;
66+
67+
return;
68+
}
69+
70+
// if no reference owns the lock, try to cache this reference
71+
if (_obj == null)
72+
{
73+
// try to obtain the lock
74+
if (0 == Interlocked.Exchange(ref _locked, 1))
75+
{
76+
// if there's really no reference, cache this reference
77+
if (_ref == null)
78+
_ref = (RegexRunner)obj;
79+
80+
// release the lock
81+
_locked = 0;
82+
83+
return;
84+
}
85+
}
86+
}
87+
}
88+
89+
/// <summary>
90+
/// Used to cache a weak reference in a threadsafe way
91+
/// </summary>
92+
internal sealed class SharedReference
93+
{
94+
private WeakReference _ref = new WeakReference(null);
95+
private int _locked;
96+
97+
/// <summary>
98+
/// Return an object from a weakref, protected by a lock.
99+
///
100+
/// If the exclusive lock can't be obtained, null is returned;
101+
/// Note that _ref.Target is referenced only under the protection of the lock. (Is this necessary?)
102+
/// </summary>
103+
internal object Get()
104+
{
105+
if (0 == Interlocked.Exchange(ref _locked, 1))
106+
{
107+
object obj = _ref.Target;
108+
_locked = 0;
109+
return obj;
110+
}
111+
112+
return null;
113+
}
114+
115+
/// <summary>
116+
/// Suggest an object into a weakref, protected by a lock.
117+
///
118+
/// Note that _ref.Target is referenced only under the protection of the lock. (Is this necessary?)
119+
/// </summary>
120+
internal void Cache(object obj)
121+
{
122+
if (0 == Interlocked.Exchange(ref _locked, 1))
123+
{
124+
_ref.Target = obj;
125+
_locked = 0;
126+
}
127+
}
128+
}
129+
}

src/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.cs

Lines changed: 0 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -554,138 +554,4 @@ internal bool Debug
554554
}
555555
#endif
556556
}
557-
558-
/*
559-
* Used to cache one exclusive runner reference
560-
*/
561-
internal sealed class ExclusiveReference
562-
{
563-
private RegexRunner _ref;
564-
private object _obj;
565-
private int _locked;
566-
567-
/*
568-
* Return an object and grab an exclusive lock.
569-
*
570-
* If the exclusive lock can't be obtained, null is returned;
571-
* if the object can't be returned, the lock is released.
572-
*
573-
*/
574-
internal object Get()
575-
{
576-
// try to obtain the lock
577-
578-
if (0 == Interlocked.Exchange(ref _locked, 1))
579-
{
580-
// grab reference
581-
582-
583-
object obj = _ref;
584-
585-
// release the lock and return null if no reference
586-
587-
if (obj == null)
588-
{
589-
_locked = 0;
590-
return null;
591-
}
592-
593-
// remember the reference and keep the lock
594-
595-
_obj = obj;
596-
return obj;
597-
}
598-
599-
return null;
600-
}
601-
602-
/*
603-
* Release an object back to the cache
604-
*
605-
* If the object is the one that's under lock, the lock
606-
* is released.
607-
*
608-
* If there is no cached object, then the lock is obtained
609-
* and the object is placed in the cache.
610-
*
611-
*/
612-
internal void Release(object obj)
613-
{
614-
if (obj == null)
615-
throw new ArgumentNullException(nameof(obj));
616-
617-
// if this reference owns the lock, release it
618-
619-
if (_obj == obj)
620-
{
621-
_obj = null;
622-
_locked = 0;
623-
return;
624-
}
625-
626-
// if no reference owns the lock, try to cache this reference
627-
628-
if (_obj == null)
629-
{
630-
// try to obtain the lock
631-
632-
if (0 == Interlocked.Exchange(ref _locked, 1))
633-
{
634-
// if there's really no reference, cache this reference
635-
636-
if (_ref == null)
637-
_ref = (RegexRunner)obj;
638-
639-
// release the lock
640-
641-
_locked = 0;
642-
return;
643-
}
644-
}
645-
}
646-
}
647-
648-
/*
649-
* Used to cache a weak reference in a threadsafe way
650-
*/
651-
internal sealed class SharedReference
652-
{
653-
private WeakReference _ref = new WeakReference(null);
654-
private int _locked;
655-
656-
/*
657-
* Return an object from a weakref, protected by a lock.
658-
*
659-
* If the exclusive lock can't be obtained, null is returned;
660-
*
661-
* Note that _ref.Target is referenced only under the protection
662-
* of the lock. (Is this necessary?)
663-
*/
664-
internal object Get()
665-
{
666-
if (0 == Interlocked.Exchange(ref _locked, 1))
667-
{
668-
object obj = _ref.Target;
669-
_locked = 0;
670-
return obj;
671-
}
672-
673-
return null;
674-
}
675-
676-
/*
677-
* Suggest an object into a weakref, protected by a lock.
678-
*
679-
* Note that _ref.Target is referenced only under the protection
680-
* of the lock. (Is this necessary?)
681-
*/
682-
internal void Cache(object obj)
683-
{
684-
if (0 == Interlocked.Exchange(ref _locked, 1))
685-
{
686-
_ref.Target = obj;
687-
_locked = 0;
688-
}
689-
}
690-
}
691557
}

0 commit comments

Comments
 (0)