[banshee] Dap: Prevent misleading exceptions in LoadFromDevice()



commit 37cb8a36f0a5884936fde0c84e7a9da87d19794a
Author: Andrés G. Aragoneses <knocte gmail com>
Date:   Tue Feb 4 23:54:04 2014 +0100

    Dap: Prevent misleading exceptions in LoadFromDevice()
    
    In some systems such as mine, when you connect a device, and after
    that, you switch it from MTP mode to PTP mode, it could happen that
    two events for the same device, one for mapping and the other for
    unmapping, could arrive almost at the same time:
    
    [19 Debug 23:43:39.175] Found DAP support (Banshee.Dap.Mtp.MtpSource) for device Nexus 4 and Uuid 
/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2
    [20 Debug 23:43:39.175] Unmapping DAP source (/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2)
    
    The Unmap one was causing a call to DapSource.Dispose() which, in
    this case it set MtpSource.mtp_device to null, which would then
    generate an ArgumentNullException when trying to enter into a
    lock(), because the LoadFromDevice() method was still in progress
    (fired by the Map event).
    
    These 2 events coming together is very inconvinient because the
    load process (LoadDeviceContents()) is threaded, so if we need
    that the Unmap event interrupts the load process of the Map event,
    an exception will definitely happen. However, it's better that
    this exception is comprehensible instead of misleading, and for
    that we're going to use Thread.Abort() API which will generate
    a ThreadAbortException, rather than an ArgumentNullException or
    other even more misleading...

 src/Dap/Banshee.Dap/Banshee.Dap/DapSource.cs |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)
---
diff --git a/src/Dap/Banshee.Dap/Banshee.Dap/DapSource.cs b/src/Dap/Banshee.Dap/Banshee.Dap/DapSource.cs
index eac1bd2..8714b1d 100644
--- a/src/Dap/Banshee.Dap/Banshee.Dap/DapSource.cs
+++ b/src/Dap/Banshee.Dap/Banshee.Dap/DapSource.cs
@@ -98,6 +98,13 @@ namespace Banshee.Dap
 
         public override void Dispose ()
         {
+            if (load_thread != null) {
+                if (load_thread.IsAlive) {
+                    load_thread.Abort ();
+                }
+                load_thread = null;
+            }
+
             Flush ();
 
             PurgeTemporaryPlaylists ();
@@ -282,10 +289,12 @@ namespace Banshee.Dap
 
         public void LoadDeviceContents ()
         {
-            ThreadPool.QueueUserWorkItem (ThreadedLoadDeviceContents);
+            load_thread = ThreadAssist.Spawn (ThreadedLoadDeviceContents);
         }
 
-        private void ThreadedLoadDeviceContents (object state)
+        private Thread load_thread;
+
+        private void ThreadedLoadDeviceContents ()
         {
             try {
                 PurgeTracks ();


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]