[Usb] Fix crashes while disposing 40/152640/1
authorDinesh Dwivedi <dinesh.d@samsung.com>
Tue, 26 Sep 2017 16:19:28 +0000 (21:49 +0530)
committerDinesh Dwivedi <dinesh.d@samsung.com>
Tue, 26 Sep 2017 16:19:28 +0000 (21:49 +0530)
Change-Id: Id886f0687fbff22c647e98b9596443f54dc5d66a
Signed-off-by: Dinesh Dwivedi <dinesh.d@samsung.com>
src/Tizen.System.Usb/Interop/Interop.Configuration.cs
src/Tizen.System.Usb/Interop/Interop.Context.cs
src/Tizen.System.Usb/Interop/Interop.Device.cs
src/Tizen.System.Usb/Interop/Interop.Endpoint.cs
src/Tizen.System.Usb/Interop/Interop.ErrorCode.cs
src/Tizen.System.Usb/Interop/Interop.Interface.cs
src/Tizen.System.Usb/Usb/UsbDevice.cs
src/Tizen.System.Usb/Usb/UsbInterface.cs
src/Tizen.System.Usb/Usb/UsbManager.cs

index 9bf5d8f..6f2d34c 100644 (file)
@@ -43,12 +43,12 @@ internal static partial class Interop
     internal class UsbConfigHandle : SafeUsbHandle
     {
         [DllImport(Libraries.Usb, EntryPoint = "usb_host_config_destroy")]
-        internal static extern ErrorCode ConfigDestroy(UsbConfigHandle /* usb_host_config_h */ config);
+        internal static extern ErrorCode ConfigDestroy(IntPtr /* usb_host_config_h */ config);
 
         public UsbConfigHandle(IntPtr handle) : base(handle) { }
         public override void Destroy()
         {
-            ConfigDestroy(this).ThrowIfFailed("Failed to destroy native HostConfig handle");
+            ConfigDestroy(handle).ThrowIfFailed("Failed to destroy native HostConfig handle");
         }
     }
 }
\ No newline at end of file
index 52a2c7e..4750414 100644 (file)
@@ -34,9 +34,6 @@ internal static partial class Interop
     [DllImport(Libraries.Usb, EntryPoint = "usb_host_set_hotplug_cb")]
     internal static extern ErrorCode SetHotplugCb(this UsbContextHandle /* usb_host_context_h */ ctx, HostHotplugCallback cb, HotplugEventType /* usb_host_hotplug_event_e */ hostEvent, IntPtr /* void */ userData, out HostHotplugHandle /* usb_host_hotplug_h */ handle);
 
-    [DllImport(Libraries.Usb, EntryPoint = "usb_host_unset_hotplug_cb")]
-    internal static extern ErrorCode UnsetHotplugCb(this HostHotplugHandle /* usb_host_hotplug_h */ handle);
-
     [DllImport(Libraries.Usb, EntryPoint = "usb_host_get_device_list")]
     internal static extern ErrorCode GetDeviceList(this UsbContextHandle /* usb_host_context_h */ ctx, out IntPtr /* usb_host_device_h */ devs, out int length);
 
@@ -51,7 +48,7 @@ internal static partial class Interop
         internal static extern ErrorCode Create(out IntPtr /* usb_host_context_h */ ctx);
 
         [DllImport(Libraries.Usb, EntryPoint = "usb_host_destroy")]
-        internal static extern ErrorCode Destroy(UsbContextHandle /* usb_host_context_h */ ctx);
+        internal static extern ErrorCode Destroy(IntPtr /* usb_host_context_h */ ctx);
 
         [DllImport(Libraries.Usb, EntryPoint = "usb_host_free_device_list")]
         internal static extern ErrorCode FreeDeviceList(IntPtr deviceList, bool unrefDevices);
@@ -68,7 +65,7 @@ internal static partial class Interop
                 FreeDeviceList(nativeDevListPtr, true).ThrowIfFailed("Failed to free native device list");
                 nativeDevListPtr = IntPtr.Zero;
             }
-            Destroy(this).ThrowIfFailed("Failed to destroy native context handle");
+            Destroy(handle).ThrowIfFailed("Failed to destroy native context handle");
         }
 
         internal List<HostDeviceHandle> GetDeviceList()
@@ -96,9 +93,15 @@ internal static partial class Interop
         }
     }
 
-    internal class HostHotplugHandle
+    internal class HostHotplugHandle : SafeUsbHandle
     {
-        private IntPtr _handle;
-        public HostHotplugHandle(IntPtr handle) { _handle = handle; }
+        [DllImport(Libraries.Usb, EntryPoint = "usb_host_unset_hotplug_cb")]
+        internal static extern ErrorCode UnsetHotplugCb(IntPtr /* usb_host_hotplug_h */ handle);
+
+        public HostHotplugHandle(IntPtr handle) : base(handle) { }
+        public override void Destroy()
+        {
+            UnsetHotplugCb(handle).ThrowIfFailed($"Failed to unset hot plug callback");
+        }
     }
 }
index e5f8c28..613c1e7 100644 (file)
@@ -31,7 +31,7 @@ internal static partial class Interop
     internal static extern ErrorCode Open(this HostDeviceHandle /* usb_host_device_h */ dev);
 
     [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_close")]
-    internal static extern ErrorCode Close(this HostDeviceHandle /* usb_host_device_h */ dev);
+    internal static extern ErrorCode CloseHandle(this HostDeviceHandle /* usb_host_device_h */ dev);
 
     [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_get_bus_number")]
     internal static extern ErrorCode GetBusNumber(this HostDeviceHandle /* usb_host_device_h */ dev, out int busNumber);
index 65536e7..3cd2353 100644 (file)
@@ -73,9 +73,9 @@ internal static partial class Interop
     [DllImport(Libraries.Usb, EntryPoint = "usb_host_transfer")]
     internal static extern ErrorCode Transfer(this UsbEndpointHandle /* usb_host_endpoint_h */ ep, byte[] data, int length, out int transferred, uint timeout);
 
-    internal class UsbEndpointHandle
+    internal class UsbEndpointHandle : SafeUsbHandle
     {
-        private IntPtr _handle;
-        public UsbEndpointHandle(IntPtr handle){ _handle = handle; }
+        public UsbEndpointHandle(IntPtr handle) : base(handle) { }
+        public override void Destroy() { }
     }
 }
\ No newline at end of file
index 973dc9d..38d9ee2 100644 (file)
@@ -114,4 +114,4 @@ internal static class ErrorCodeExtensions
             default: return new InvalidOperationException(errMessage);
         }
     }
-}
\ No newline at end of file
+}
index 5cae2f3..22727dd 100644 (file)
@@ -42,9 +42,9 @@ internal static partial class Interop
     internal static extern ErrorCode GetStr(this UsbInterfaceHandle /* usb_host_interface_h */ usbInterface, ref int length, byte[] data);
 
 
-    internal class UsbInterfaceHandle
+    internal class UsbInterfaceHandle : SafeUsbHandle
     {
-        private IntPtr _handle;
-        public UsbInterfaceHandle(IntPtr handle) { _handle = handle; }
+        public UsbInterfaceHandle(IntPtr handle) : base(handle) { }
+        public override void Destroy() { }
     }
 }
\ No newline at end of file
index f6e37d3..4116752 100755 (executable)
@@ -27,12 +27,20 @@ namespace Tizen.System.Usb
     {
         internal readonly Interop.HostDeviceHandle _handle;
         private readonly UsbManager _parent;
-        private Dictionary<int, UsbConfiguration> _configurations;
+        private Dictionary<int, UsbConfiguration> _configurations = new Dictionary<int, UsbConfiguration>();
 
         internal UsbDevice(UsbManager parent, Interop.HostDeviceHandle handle)
         {
             _parent = parent;
             _handle = handle;
+
+            int count = Interop.NativeGet<int>(_handle.GetNumConfigurations);
+            for (int i = 0; i < count; ++i)
+            {
+                Interop.UsbConfigHandle configHandle;
+                _handle.GetConfig(i, out configHandle);
+                _configurations.Add(i, new UsbConfiguration(this, configHandle));
+            }
         }
 
         /// <summary>
@@ -117,17 +125,6 @@ namespace Tizen.System.Usb
             get
             {
                 ThrowIfDisposed();
-                if (_configurations == null)
-                {
-                    _configurations = new Dictionary<int, UsbConfiguration>();
-                    int count = Interop.NativeGet<int>(_handle.GetNumConfigurations);
-                    for (int i = 0; i < count; ++i)
-                    {
-                        Interop.UsbConfigHandle configHandle;
-                        _handle.GetConfig(i, out configHandle);
-                        _configurations.Add(i, new UsbConfiguration(this, configHandle));
-                    }
-                }
                 return _configurations;
             }
         }
@@ -177,7 +174,7 @@ namespace Tizen.System.Usb
             ThrowIfDisposed();
             if (IsOpened == false) throw new InvalidOperationException("Device must be opened for operation first");
 
-            _handle.Close();
+            _handle.CloseHandle().ThrowIfFailed("Failed to close device for use");
         }
 
         internal void ThrowIfDisposed()
index 04a9d48..80e77e2 100755 (executable)
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-using System.Collections.Generic;
 using System;
+using System.Collections.Generic;
 
 namespace Tizen.System.Usb
 {
index aba4987..f539174 100644 (file)
@@ -25,8 +25,8 @@ namespace Tizen.System.Usb
     /// </summary>
     public class UsbManager : IDisposable
     {
-        private readonly Interop.UsbContextHandle _context;
-        private readonly Interop.HostHotplugHandle _hotpluggedHandle;
+        private readonly Interop.UsbContextHandle _context = null;
+        private readonly Interop.HostHotplugHandle _hotpluggedHandle = null;
         private List<UsbDevice> _devices = new List<UsbDevice>();
 
         /// <summary>
@@ -98,8 +98,8 @@ namespace Tizen.System.Usb
         {
             if (!disposedValue)
             {
-                _hotpluggedHandle.UnsetHotplugCb();
-                _context.Dispose();
+                if (_hotpluggedHandle != null) _hotpluggedHandle.Dispose();
+                if (_context != null) _context.Dispose();
                 disposedValue = true;
             }
         }