Author: miguel
Date: 2006-12-11 19:40:52 -0500 (Mon, 11 Dec 2006)
New Revision: 69378

Added:
   trunk/mcs/class/corlib/Test/System.Runtime.InteropServices/SafeHandleTest.cs
Modified:
   trunk/mcs/class/corlib/System.Runtime.InteropServices/ChangeLog
   trunk/mcs/class/corlib/System.Runtime.InteropServices/SafeHandle.cs
   trunk/mcs/class/corlib/corlib_test.dll.sources
Log:
2006-12-11  Miguel de Icaza  <[EMAIL PROTECTED]>

        * SafeHandle.cs: Fix a handful of bugs, and add tests for them.
        Only release the handle if its owned by us.  Also throw
        ObjectDisposedException's



Modified: trunk/mcs/class/corlib/System.Runtime.InteropServices/ChangeLog
===================================================================
--- trunk/mcs/class/corlib/System.Runtime.InteropServices/ChangeLog     
2006-12-12 00:39:03 UTC (rev 69377)
+++ trunk/mcs/class/corlib/System.Runtime.InteropServices/ChangeLog     
2006-12-12 00:40:52 UTC (rev 69378)
@@ -1,7 +1,11 @@
 2006-12-11  Miguel de Icaza  <[EMAIL PROTECTED]>
 
-       * SafeHandle.cs: Implement finalizer.
+       * SafeHandle.cs: Fix a handful of bugs, and add tests for them.
+       Only release the handle if its owned by us.  Also throw
+       ObjectDisposedException's
 
+       Implement finalizer.
+
        DangerousAddRef will now throw an exception if the object was
        disposed.
 

Modified: trunk/mcs/class/corlib/System.Runtime.InteropServices/SafeHandle.cs
===================================================================
--- trunk/mcs/class/corlib/System.Runtime.InteropServices/SafeHandle.cs 
2006-12-12 00:39:03 UTC (rev 69377)
+++ trunk/mcs/class/corlib/System.Runtime.InteropServices/SafeHandle.cs 
2006-12-12 00:40:52 UTC (rev 69378)
@@ -70,9 +70,12 @@
 
                public void Close ()
                {
+                       if (refcount == 0)
+                               throw new ObjectDisposedException (GetType 
().FullName);
+
                        lock (handle_lock){
                                refcount--;
-                               if (refcount == 0){
+                               if (refcount == 0 && owns_handle){
                                        ReleaseHandle ();
                                        handle = invalid_handle_value;
                                }
@@ -90,6 +93,9 @@
                //
                public void DangerousAddRef (ref bool success)
                {
+                       if (refcount == 0)
+                               throw new ObjectDisposedException (GetType 
().FullName);
+
                        lock (handle_lock){
                                if (handle == invalid_handle_value || refcount 
== 0){
                                        //
@@ -98,7 +104,7 @@
                                        // am left wondering: when would 
"success" be
                                        // set to false?
                                        //
-                                       throw new ObjectDisposedException 
("handle");
+                                       throw new ObjectDisposedException 
(GetType ().FullName);
                                }
                                
                                refcount++;
@@ -108,12 +114,18 @@
 
                public IntPtr DangerousGetHandle ()
                {
+                       if (refcount == 0){
+                               throw new ObjectDisposedException (GetType 
().FullName);
+                       }
+
                        return handle;
                }
 
                public void DangerousRelease ()
                {
-                       Console.WriteLine ("DangerousRelease called");
+                       if (refcount == 0)
+                               throw new ObjectDisposedException (GetType 
().FullName);
+
                        lock (handle_lock){
                                refcount--;
                                if (refcount == 0 && owns_handle){
@@ -148,7 +160,7 @@
                                // the question is whether:
                                //   * The runtime will ever call Dipose(false) 
for SafeHandles (special runtime case)
                                //   * Whether we should just call 
ReleaseHandle regardless?
-                               // 
+                               //
                        }
                }
 

Added: 
trunk/mcs/class/corlib/Test/System.Runtime.InteropServices/SafeHandleTest.cs
===================================================================
--- 
trunk/mcs/class/corlib/Test/System.Runtime.InteropServices/SafeHandleTest.cs    
    2006-12-12 00:39:03 UTC (rev 69377)
+++ 
trunk/mcs/class/corlib/Test/System.Runtime.InteropServices/SafeHandleTest.cs    
    2006-12-12 00:40:52 UTC (rev 69378)
@@ -0,0 +1,93 @@
+//
+// System.Runtime.InteropServices.SafeHandle Test Cases
+//
+// Authors:
+//     Miguel de Icaza ([EMAIL PROTECTED])
+//
+// Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com)
+//
+#if NET_2_0
+using NUnit.Framework;
+using System;
+using System.Runtime.InteropServices;
+using System.Security;
+using Microsoft.Win32.SafeHandles;
+
+namespace MonoTests.System.Runtime.InteropServices
+{
+       [TestFixture]
+       public class SafeHandleTest 
+       {
+               //
+               // This mimics SafeFileHandle, but does not actually own a 
handle
+               // We use this to test ownership and dispose exceptions.
+               //
+               public class FakeSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
+               {
+                       public bool released = false;
+                       
+                       public FakeSafeHandle (): base (true)
+                       {
+                       }
+                       
+                       public FakeSafeHandle (bool ownership) : base 
(ownership)
+                       {
+                       }
+
+                       protected override bool ReleaseHandle ()
+                       {
+                               released = true;
+                               return true;
+                       }
+               }
+               
+               [Test]
+               [ExpectedException (typeof (ObjectDisposedException))]
+               public void Dispose1 ()
+               {
+                       FakeSafeHandle sf = new FakeSafeHandle ();
+
+                       sf.DangerousRelease ();
+                       sf.DangerousRelease ();
+               }
+
+               [Test]
+               [ExpectedException (typeof (ObjectDisposedException))]
+               public void Dispose2 ()
+               {
+                       FakeSafeHandle sf = new FakeSafeHandle ();
+
+                       sf.DangerousRelease ();
+                       sf.Close ();
+               }
+
+               [Test]
+               [ExpectedException (typeof (ObjectDisposedException))]
+               public void Dispose3 ()
+               {
+                       FakeSafeHandle sf = new FakeSafeHandle ();
+
+                       sf.Close ();
+                       sf.DangerousRelease ();
+               }
+
+               [Test]
+               public void NoReleaseUnowned ()
+               {
+                       FakeSafeHandle sf = new FakeSafeHandle (false);
+
+                       sf.Close ();
+                       Assert.AreEqual (sf.released, false, "r1");
+
+                       sf = new FakeSafeHandle (false);
+                       sf.DangerousRelease ();
+                       Assert.AreEqual (sf.released, false, "r2");
+
+                       sf = new FakeSafeHandle (false);
+                       ((IDisposable) sf).Dispose ();
+                       Assert.AreEqual (sf.released, false, "r3");
+               }
+       }
+}
+
+#endif


Property changes on: 
trunk/mcs/class/corlib/Test/System.Runtime.InteropServices/SafeHandleTest.cs
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/mcs/class/corlib/corlib_test.dll.sources
===================================================================
--- trunk/mcs/class/corlib/corlib_test.dll.sources      2006-12-12 00:39:03 UTC 
(rev 69377)
+++ trunk/mcs/class/corlib/corlib_test.dll.sources      2006-12-12 00:40:52 UTC 
(rev 69378)
@@ -130,6 +130,7 @@
 System.Runtime.InteropServices/GCHandleTest.cs
 System.Runtime.InteropServices/MarshalTest.cs
 System.Runtime.InteropServices/RuntimeEnvironmentTest.cs
+System.Runtime.InteropServices/SafeHandleTest.cs
 System.Runtime.Remoting/ContextTest.cs
 System.Runtime.Remoting/SoapServicesTest.cs
 System.Runtime.Remoting/SynchronizationAttributeTest.cs

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to