[banshee] [Mtp] Fix some leaks with Albums and Playlists in the bindings



commit 5956e611236873b93b80624f913be1611e150d89
Author: Alan McGovern <alan mcgovern gmail com>
Date:   Sun Feb 14 11:11:47 2010 +0100

    [Mtp] Fix some leaks with Albums and Playlists in the bindings
    
    Also removes FolderHandle from the code as the folder pointer is always
    released right after it's created (unlike the Device handle which is
    alive for a long amount of time). Fixes bgo#605388.
    
    Signed-off-by: Bertrand Lorentz <bertrand lorentz gmail com>

 src/Libraries/Mtp/Mtp/Album.cs     |   31 ++++++++++---
 src/Libraries/Mtp/Mtp/Folder.cs    |   82 ++++++++++-------------------------
 src/Libraries/Mtp/Mtp/MtpDevice.cs |   22 +---------
 src/Libraries/Mtp/Mtp/Playlist.cs  |   20 +++++++-
 4 files changed, 67 insertions(+), 88 deletions(-)
---
diff --git a/src/Libraries/Mtp/Mtp/Album.cs b/src/Libraries/Mtp/Mtp/Album.cs
index a381c08..afb8e21 100644
--- a/src/Libraries/Mtp/Mtp/Album.cs
+++ b/src/Libraries/Mtp/Mtp/Album.cs
@@ -35,6 +35,21 @@ namespace Mtp
 {
     public class Album : AbstractTrackList
     {
+        internal static List<Album> GetAlbums (MtpDevice device)
+        {
+            List<Album> albums = new List<Album> ();
+
+            IntPtr ptr = LIBMTP_Get_Album_List (device.Handle);
+            while (ptr != IntPtr.Zero) {
+                AlbumStruct d = (AlbumStruct)Marshal.PtrToStructure(ptr, typeof(AlbumStruct));
+                LIBMTP_destroy_album_t (ptr);
+                albums.Add (new Album (device, d));
+                ptr = d.next;
+            }
+
+            return albums;
+        }
+
         private AlbumStruct album;
 
         public uint AlbumId {
@@ -154,21 +169,23 @@ namespace Mtp
             if (ptr == IntPtr.Zero) {
                 return null;
             } else {
-                return new Album (device, (AlbumStruct) Marshal.PtrToStructure(ptr, typeof (AlbumStruct)));
+                AlbumStruct album = (AlbumStruct) Marshal.PtrToStructure(ptr, typeof (AlbumStruct));
+                LIBMTP_destroy_album_t (ptr);
+                return new Album (device, album);
             }
         }
 
-        [DllImport("libmtp.dll")]
-        internal static extern IntPtr LIBMTP_new_album_t (); // LIBMTP_album_t*
+        //[DllImport("libmtp.dll")]
+        //internal static extern IntPtr LIBMTP_new_album_t (); // LIBMTP_album_t*
 
         [DllImport("libmtp.dll")]
-        internal static extern void LIBMTP_destroy_album_t (ref AlbumStruct album);
+        static extern void LIBMTP_destroy_album_t (IntPtr album);
 
         [DllImport("libmtp.dll")]
-        internal static extern IntPtr LIBMTP_Get_Album_List (MtpDeviceHandle handle); // LIBMTP_album_t*
+        static extern IntPtr LIBMTP_Get_Album_List (MtpDeviceHandle handle); // LIBMTP_album_t*
 
         [DllImport("libmtp.dll")]
-        internal static extern IntPtr LIBMTP_Get_Album (MtpDeviceHandle handle, uint albumId); // LIBMTP_album_t*
+        static extern IntPtr LIBMTP_Get_Album (MtpDeviceHandle handle, uint albumId); // LIBMTP_album_t*
 
 #if LIBMTP8
         [DllImport("libmtp.dll")]
@@ -179,7 +196,7 @@ namespace Mtp
 #endif
 
         [DllImport("libmtp.dll")]
-        internal static extern int LIBMTP_Update_Album (MtpDeviceHandle handle, ref AlbumStruct album);
+        static extern int LIBMTP_Update_Album (MtpDeviceHandle handle, ref AlbumStruct album);
     }
 
     [StructLayout(LayoutKind.Sequential)]
diff --git a/src/Libraries/Mtp/Mtp/Folder.cs b/src/Libraries/Mtp/Mtp/Folder.cs
index febd0cc..5fc7dce 100644
--- a/src/Libraries/Mtp/Mtp/Folder.cs
+++ b/src/Libraries/Mtp/Mtp/Folder.cs
@@ -87,25 +87,22 @@ namespace Mtp
         
         public List<Folder> GetChildren ()
         {
-            using (FolderHandle handle = GetFolderList(device.Handle))
+            IntPtr root = GetFolderList(device.Handle);
+            IntPtr ptr = Find (root, folderId);
+
+            FolderStruct f = (FolderStruct)Marshal.PtrToStructure(ptr, typeof(FolderStruct));
+
+            ptr = f.child;
+            List<Folder> folders = new List<Folder>();
+            while (ptr != IntPtr.Zero)
             {
-                // Find the pointer to the folderstruct representing this folder
-                IntPtr ptr = handle.DangerousGetHandle();
-                ptr = Find (ptr, folderId);
-                
-                FolderStruct f = (FolderStruct)Marshal.PtrToStructure(ptr, typeof(FolderStruct));
-                
-                ptr = f.child;
-                List<Folder> folders = new List<Folder>();
-                while (ptr != IntPtr.Zero)
-                {
-                    FolderStruct folder = (FolderStruct)Marshal.PtrToStructure(ptr, typeof(FolderStruct));
-                    folders.Add(new Folder(folder, device));
-                    ptr = folder.sibling;
-                }
-                
-                return folders;
+                FolderStruct folder = (FolderStruct)Marshal.PtrToStructure(ptr, typeof(FolderStruct));
+                folders.Add(new Folder(folder, device));
+                ptr = folder.sibling;
             }
+
+            LIBMTP_destroy_folder_t (root);
+            return folders;
         }
         
         public void Remove()
@@ -117,20 +114,22 @@ namespace Mtp
         {
             return String.Format ("{0} (id {1}, parent id {2})", Name, FolderId, ParentId);
         }
-        
+
         internal static List<Folder> GetRootFolders (MtpDevice device)
         {
             List<Folder> folders = new List<Folder>();
-            using (FolderHandle handle = GetFolderList (device.Handle))
-            {
-                for (IntPtr ptr = handle.DangerousGetHandle(); ptr != IntPtr.Zero;)
-                {
+            IntPtr root = GetFolderList (device.Handle);
+            try {
+                for (IntPtr ptr = root; ptr != IntPtr.Zero;) {
                     FolderStruct folder = (FolderStruct)Marshal.PtrToStructure(ptr, typeof(FolderStruct));
                     folders.Add(new Folder (folder, device));
                     ptr = folder.sibling;
                 }
-                return folders;
+            } finally {
+                // Recursively destroy the folder tree
+                LIBMTP_destroy_folder_t (root);
             }
+            return folders;
         }
 
         internal static uint CreateFolder (MtpDeviceHandle handle, string name, uint parentId)
@@ -159,10 +158,9 @@ namespace Mtp
             return LIBMTP_Find_Folder (folderList, folderId);
         }
 
-        internal static FolderHandle GetFolderList (MtpDeviceHandle handle)
+        internal static IntPtr GetFolderList (MtpDeviceHandle handle)
         {
-            IntPtr ptr = LIBMTP_Get_Folder_List (handle);
-            return new FolderHandle(ptr);
+            return LIBMTP_Get_Folder_List (handle);
         }
 
         // Folder Management
@@ -187,38 +185,6 @@ namespace Mtp
 #endif
     }
 
-    internal class FolderHandle : SafeHandle
-    {
-        private FolderHandle()
-            : base(IntPtr.Zero, true)
-        {
-            
-        }
-        
-        internal FolderHandle(IntPtr ptr)
-            : this(ptr, true)
-        {
-            
-        }
-        
-        internal FolderHandle(IntPtr ptr, bool ownsHandle)
-            : base (IntPtr.Zero, ownsHandle)
-        {
-            SetHandle (ptr);
-        }
-        
-        public override bool IsInvalid
-        {
-            get { return handle == IntPtr.Zero; }
-        }
-
-        protected override bool ReleaseHandle ()
-        {
-            Folder.DestroyFolder (handle);
-            return true;
-        }
-    }
-    
     [StructLayout(LayoutKind.Sequential)]
     internal struct FolderStruct
     {
diff --git a/src/Libraries/Mtp/Mtp/MtpDevice.cs b/src/Libraries/Mtp/Mtp/MtpDevice.cs
index a16d314..4ad350e 100644
--- a/src/Libraries/Mtp/Mtp/MtpDevice.cs
+++ b/src/Libraries/Mtp/Mtp/MtpDevice.cs
@@ -192,30 +192,12 @@ namespace Mtp
 
         public List<Playlist> GetPlaylists ()
         {
-            List<Playlist> playlists = new List<Playlist> ();
-
-            IntPtr ptr = Playlist.LIBMTP_Get_Playlist_List (Handle);
-            while (ptr != IntPtr.Zero) {
-                PlaylistStruct d = (PlaylistStruct)Marshal.PtrToStructure(ptr, typeof(PlaylistStruct));
-                playlists.Add (new Playlist (this, d));
-                ptr = d.next;
-            }
-            
-            return playlists;
+            return Playlist.GetPlaylists (this);
         }
 
         public List<Album> GetAlbums ()
         {
-            List<Album> albums = new List<Album> ();
-
-            IntPtr ptr = Album.LIBMTP_Get_Album_List (Handle);
-            while (ptr != IntPtr.Zero) {
-                AlbumStruct d = (AlbumStruct)Marshal.PtrToStructure(ptr, typeof(AlbumStruct));
-                albums.Add (new Album (this, d));
-                ptr = d.next;
-            }
-            
-            return albums;
+            return Album.GetAlbums (this);
         }
         
         public List<DeviceStorage> GetStorage ()
diff --git a/src/Libraries/Mtp/Mtp/Playlist.cs b/src/Libraries/Mtp/Mtp/Playlist.cs
index cad92cc..5df6aba 100644
--- a/src/Libraries/Mtp/Mtp/Playlist.cs
+++ b/src/Libraries/Mtp/Mtp/Playlist.cs
@@ -28,12 +28,26 @@
  */
 
 using System;
+using System.Collections.Generic;
 using System.Runtime.InteropServices;
 
 namespace Mtp
 {
     public sealed class Playlist : AbstractTrackList
     {
+        internal static List<Playlist> GetPlaylists (MtpDevice device)
+        {
+            List<Playlist> playlists = new List<Playlist> ();
+            IntPtr ptr = Playlist.LIBMTP_Get_Playlist_List (device.Handle);
+            while (ptr != IntPtr.Zero) {
+                PlaylistStruct d = (PlaylistStruct)Marshal.PtrToStructure(ptr, typeof(PlaylistStruct));
+                LIBMTP_destroy_playlist_t (ptr);
+                playlists.Add (new Playlist (device, d));
+                ptr = d.next;
+            }
+            return playlists;
+        }
+
         private PlaylistStruct playlist;
 
         public override uint Count {
@@ -87,11 +101,11 @@ namespace Mtp
 
         // Playlist Management
 
-        //[DllImport("libmtp.dll")]
-        //private static extern void LIBMTP_destroy_playlist_t (ref PlaylistStruct playlist);
+        [DllImport("libmtp.dll")]
+        private static extern void LIBMTP_destroy_playlist_t (IntPtr playlist);
 
         [DllImport("libmtp.dll")]
-        internal static extern IntPtr LIBMTP_Get_Playlist_List (MtpDeviceHandle handle); // LIBMTP_playlist_t*
+        private static extern IntPtr LIBMTP_Get_Playlist_List (MtpDeviceHandle handle); // LIBMTP_playlist_t*
 
         [DllImport("libmtp.dll")]
 #if LIBMTP8



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