88using System . Diagnostics ;
99using System . Runtime . InteropServices ;
1010using System . Runtime . Versioning ;
11- using System . Threading ;
1211
1312namespace Interop . Windows . Sni
1413{
15- internal unsafe class SqlDependencyProcessDispatcherStorage
14+ internal class SqlDependencyProcessDispatcherStorage
1615 {
17- private static void * s_data ;
16+ private static readonly object s_lockObj = new ( ) ;
17+ private static IntPtr s_data ;
1818 private static int s_size ;
19- private static volatile int s_lock ; // Int used for a spin-lock.
2019
2120 [ ResourceExposure ( ResourceScope . Process ) ] // SxS: there is no way to set scope = Instance, using Process which is wider
2221 [ ResourceConsumption ( ResourceScope . Process , ResourceScope . Process ) ]
2322 public static byte [ ] NativeGetData ( )
2423 {
25- IntPtr ptr = ( IntPtr ) s_data ;
26-
2724 byte [ ] result = null ;
28- if ( ptr != IntPtr . Zero )
25+ if ( s_data != IntPtr . Zero )
2926 {
3027 result = new byte [ s_size ] ;
31- Marshal . Copy ( ptr , result , 0 , s_size ) ;
28+ Marshal . Copy ( s_data , result , 0 , s_size ) ;
3229 }
3330
3431 return result ;
@@ -38,29 +35,18 @@ public static byte[] NativeGetData()
3835 [ ResourceConsumption ( ResourceScope . Process , ResourceScope . Process ) ]
3936 internal static void NativeSetData ( byte [ ] data )
4037 {
41- fixed ( byte * pDispatcher = data )
38+ lock ( s_lockObj )
4239 {
43- while ( Interlocked . CompareExchange ( ref s_lock , 1 , 0 ) != 0 )
40+ if ( s_data == IntPtr . Zero )
4441 {
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
5948 s_size = data . Length ;
6049 }
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.
6450 }
6551 }
6652 }
0 commit comments