From 1387155a934f9735d74ebc7d15cc143adf5fe91a Mon Sep 17 00:00:00 2001 From: jeremy-jang <35089715+jeremy-jang@users.noreply.github.com> Date: Fri, 5 Oct 2018 08:33:32 +0900 Subject: [PATCH] [Packagemanager] Fix lifetime of callback delegate (#503) The callback delegate which is passed to unmanaged code can be garbage-collected before invoked. So we need to save delegate in managed code until invoked. Change-Id: Ie8671fa816242040e0372fdf5bf102d41eaaa3cd Signed-off-by: Sangyoon Jang --- .../Tizen.Applications/Package.cs | 17 ++++++++++++++++- .../Tizen.Applications/PackageManager.cs | 18 +++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) mode change 100755 => 100644 src/Tizen.Applications.PackageManager/Tizen.Applications/Package.cs diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/Package.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/Package.cs old mode 100755 new mode 100644 index e33df18..000be4a --- a/src/Tizen.Applications.PackageManager/Tizen.Applications/Package.cs +++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/Package.cs @@ -45,6 +45,9 @@ namespace Tizen.Applications private List _privileges; private int _installedTime; + private Dictionary _packageManagerSizeInfoCallbackDict = new Dictionary(); + private int _callbackId = 0; + private Package(string pkgId) { _id = pkgId; @@ -204,9 +207,21 @@ namespace Tizen.Applications var pkgSizeInfo = PackageSizeInformation.GetPackageSizeInformation(sizeInfoHandle); tcs.TrySetResult(pkgSizeInfo); } + + lock (_packageManagerSizeInfoCallbackDict) + { + _packageManagerSizeInfoCallbackDict.Remove(userData); + } }; - Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerGetSizeInfo(Id, sizeInfoCb, IntPtr.Zero); + IntPtr callbackId; + lock (_packageManagerSizeInfoCallbackDict) + { + callbackId = (IntPtr)_callbackId++; + _packageManagerSizeInfoCallbackDict[callbackId] = sizeInfoCb; + } + + Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerGetSizeInfo(Id, sizeInfoCb, callbackId); if (err != Interop.PackageManager.ErrorCode.None) { tcs.TrySetException(PackageManagerErrorFactory.GetException(err, "Failed to get total package size info of " + Id)); diff --git a/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageManager.cs b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageManager.cs index 80d55d2..c813028 100644 --- a/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageManager.cs +++ b/src/Tizen.Applications.PackageManager/Tizen.Applications/PackageManager.cs @@ -43,6 +43,9 @@ namespace Tizen.Applications private static Interop.PackageManager.PackageManagerEventCallback s_packageManagerEventCallback; + private static Dictionary s_totalSizeInfoCallbackDict = new Dictionary(); + private static int s_callbackId = 0; + /// /// Event callback method for the request. /// @@ -383,15 +386,28 @@ namespace Tizen.Applications public static async Task GetTotalSizeInformationAsync() { TaskCompletionSource tcs = new TaskCompletionSource(); + Interop.PackageManager.PackageManagerTotalSizeInfoCallback cb = (handle, userData) => { if (handle != IntPtr.Zero) { tcs.TrySetResult(PackageSizeInformation.GetPackageSizeInformation(handle)); } + + lock (s_totalSizeInfoCallbackDict) + { + s_totalSizeInfoCallbackDict.Remove(userData); + } }; - var err = Interop.PackageManager.PackageManagerGetTotalSizeInfo(cb, IntPtr.Zero); + IntPtr callbackId; + lock (s_totalSizeInfoCallbackDict) + { + callbackId = (IntPtr)s_callbackId++; + s_totalSizeInfoCallbackDict[callbackId] = cb; + } + + var err = Interop.PackageManager.PackageManagerGetTotalSizeInfo(cb, callbackId); if (err != Interop.PackageManager.ErrorCode.None) { tcs.TrySetException(PackageManagerErrorFactory.GetException(err, "Failed to get total package size info")); -- 2.7.4