8
8
using System . Diagnostics ;
9
9
using System . Runtime . InteropServices ;
10
10
using System . Runtime . Versioning ;
11
- using System . Threading ;
12
11
13
12
namespace Interop . Windows . Sni
14
13
{
15
- internal unsafe class SqlDependencyProcessDispatcherStorage
14
+ internal class SqlDependencyProcessDispatcherStorage
16
15
{
17
- private static void * s_data ;
16
+ private static readonly object s_lockObj = new ( ) ;
17
+ private static IntPtr s_data ;
18
18
private static int s_size ;
19
- private static volatile int s_lock ; // Int used for a spin-lock.
20
19
21
20
[ ResourceExposure ( ResourceScope . Process ) ] // SxS: there is no way to set scope = Instance, using Process which is wider
22
21
[ ResourceConsumption ( ResourceScope . Process , ResourceScope . Process ) ]
23
22
public static byte [ ] NativeGetData ( )
24
23
{
25
- IntPtr ptr = ( IntPtr ) s_data ;
26
-
27
24
byte [ ] result = null ;
28
- if ( ptr != IntPtr . Zero )
25
+ if ( s_data != IntPtr . Zero )
29
26
{
30
27
result = new byte [ s_size ] ;
31
- Marshal . Copy ( ptr , result , 0 , s_size ) ;
28
+ Marshal . Copy ( s_data , result , 0 , s_size ) ;
32
29
}
33
30
34
31
return result ;
@@ -38,29 +35,18 @@ public static byte[] NativeGetData()
38
35
[ ResourceConsumption ( ResourceScope . Process , ResourceScope . Process ) ]
39
36
internal static void NativeSetData ( byte [ ] data )
40
37
{
41
- fixed ( byte * pDispatcher = data )
38
+ lock ( s_lockObj )
42
39
{
43
- while ( Interlocked . CompareExchange ( ref s_lock , 1 , 0 ) != 0 )
40
+ if ( s_data == IntPtr . Zero )
44
41
{
45
- // Spin until we have the lock.
46
- Thread . Sleep ( 50 ) ; // Sleep with short-timeout to prevent starvation.
47
- }
48
- Trace . Assert ( s_lock == 1 ) ; // Now that we have the lock, lock should be equal to 1.
49
-
50
- if ( s_data == null )
51
- {
52
- s_data = Marshal . AllocHGlobal ( data . Length ) . ToPointer ( ) ;
53
-
54
- Trace . Assert ( s_data != null ) ;
55
-
56
- Buffer . MemoryCopy ( pDispatcher , s_data , data . Length , data . Length ) ;
57
-
58
- Trace . Assert ( 0 == s_size ) ; // Size should still be zero at this point.
42
+ s_data = Marshal . AllocHGlobal ( data . Length ) ;
43
+ Trace . Assert ( s_data != IntPtr . Zero ) ;
44
+
45
+ Marshal . Copy ( data , 0 , s_data , data . Length ) ;
46
+
47
+ Trace . Assert ( s_size == 0 ) ; // Size should still be zero at this point
59
48
s_size = data . Length ;
60
49
}
61
-
62
- int result = Interlocked . CompareExchange ( ref s_lock , 0 , 1 ) ;
63
- Trace . Assert ( 1 == result ) ; // The release of the lock should have been successful.
64
50
}
65
51
}
66
52
}
0 commit comments