X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem.Runtime.InteropServices%2FSafeHandle.cs;h=8825118ecb83e6e06b849df27427131a5ef4fb0b;hb=d49951ccf584ba637afb1dab7fff714478e3174d;hp=438bb7998bfd158cee47c7bcc23ec86e86142264;hpb=434e59e4bc6cda7d62ad6725a8b5a590ff9c9d1f;p=mono.git diff --git a/mcs/class/corlib/System.Runtime.InteropServices/SafeHandle.cs b/mcs/class/corlib/System.Runtime.InteropServices/SafeHandle.cs index 438bb7998bf..8825118ecb8 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/SafeHandle.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/SafeHandle.cs @@ -41,11 +41,13 @@ // find out whether the runtime performs the P/Invoke if the // handle has been disposed already. // +// #if NET_2_0 using System; using System.Runtime.InteropServices; using System.Runtime.ConstrainedExecution; +using System.Threading; namespace System.Runtime.InteropServices { @@ -56,7 +58,6 @@ namespace System.Runtime.InteropServices // MonoSafeHandle // protected IntPtr handle; - object handle_lock = new object (); IntPtr invalid_handle_value; int refcount = 0; bool owns_handle; @@ -73,12 +74,15 @@ namespace System.Runtime.InteropServices if (refcount == 0) throw new ObjectDisposedException (GetType ().FullName); - lock (handle_lock){ - refcount--; - if (refcount == 0 && owns_handle){ - ReleaseHandle (); - handle = invalid_handle_value; - } + int newcount, current; + do { + current = refcount; + newcount = current-1; + } while (Interlocked.CompareExchange (ref refcount, newcount, current) != current); + + if (newcount == 0 && owns_handle){ + ReleaseHandle (); + handle = invalid_handle_value; } } @@ -96,8 +100,12 @@ namespace System.Runtime.InteropServices if (refcount == 0) throw new ObjectDisposedException (GetType ().FullName); - lock (handle_lock){ - if (handle == invalid_handle_value || refcount == 0){ + int newcount, current; + do { + current = refcount; + newcount = current + 1; + + if (handle == invalid_handle_value || current == 0){ // // In MS, calling sf.Close () followed by a call // to P/Invoke with SafeHandles throws this, but @@ -106,10 +114,8 @@ namespace System.Runtime.InteropServices // throw new ObjectDisposedException (GetType ().FullName); } - - refcount++; - success = true; - } + } while (Interlocked.CompareExchange (ref refcount, newcount, current) != current); + success = true; } public IntPtr DangerousGetHandle () @@ -126,12 +132,15 @@ namespace System.Runtime.InteropServices if (refcount == 0) throw new ObjectDisposedException (GetType ().FullName); - lock (handle_lock){ - refcount--; - if (refcount == 0 && owns_handle){ - ReleaseHandle (); - handle = invalid_handle_value; - } + int newcount, current; + do { + current = refcount; + newcount = current-1; + } while (Interlocked.CompareExchange (ref refcount, newcount, current) != current); + + if (newcount == 0 && owns_handle){ + ReleaseHandle (); + handle = invalid_handle_value; } }