[TEEC] Make SharedMemory disposable (#121) 5.0.0.14278
authorKrzysztof Dynowski <k.dynowski@samsung.com>
Tue, 6 Mar 2018 09:57:20 +0000 (10:57 +0100)
committerterry2000s <ds73.lee@samsung.com>
Tue, 6 Mar 2018 09:57:20 +0000 (18:57 +0900)
src/Tizen.Security.TEEC/Tizen.Security.TEEC/Libteec.cs

index ad93795..6965415 100644 (file)
@@ -109,20 +109,61 @@ namespace Tizen.Security.TEEC
     /// with the implementation or allocated by it.
     /// </summary>
     /// <since_tizen> 3 </since_tizen>
-    public sealed class SharedMemory
+    public sealed class SharedMemory : IDisposable
     {
+        private bool disposed = false;
+        private bool initialized = false;
+        private Context context; // keep reference for correct finalizers order
         internal Interop.TEEC_SharedMemory shm;
         internal IntPtr shmptr;
-        internal SharedMemory(ref Interop.TEEC_SharedMemory shm)
+        internal SharedMemory(Context context)
+        {
+            this.context = context;
+            shmptr = Marshal.AllocHGlobal(Marshal.SizeOf<Interop.TEEC_SharedMemory>());
+        }
+        internal void setShm(ref Interop.TEEC_SharedMemory shm)
         {
-            this.shm=shm;
-            shmptr = Marshal.AllocHGlobal(Marshal.SizeOf(shm));
+            this.shm = shm;
             Marshal.StructureToPtr(shm, shmptr, false);
+            initialized = true;
+            ++context.shmcnt;
         }
-        ~SharedMemory()
+        private void Dispose(bool disposing)
         {
+            if (disposed) {
+                return ;
+            }
+            if (context == null) {
+                throw new Exception("internal error: context is null");
+            }
+            if (initialized) {
+                Interop.Libteec.ReleaseSharedMemory(ref shm);
+                initialized = false;
+                --context.shmcnt;
+            }
             Marshal.FreeHGlobal(shmptr);
+            shmptr = IntPtr.Zero;
+            context = null;
+            disposed = true;
         }
+
+        /// <summary>
+        /// Destructor of the class.
+        /// </summary>
+        ~SharedMemory()
+        {
+            Dispose(false);
+        }
+
+        /// <summary>
+        /// Disposable interface implememtation.
+        /// </summary>
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
         /// <summary>
         /// This property represents the shared memory size in bytes.
         /// </summary>
@@ -344,8 +385,7 @@ namespace Tizen.Security.TEEC
             for (int i=0; i < 4; ++i) shm[i] = null;
         }
 
-        // internal since class is sealed
-        internal void Dispose(bool disposing)
+        private void Dispose(bool disposing)
         {
             if (disposed) {
                 return ;
@@ -374,7 +414,8 @@ namespace Tizen.Security.TEEC
         /// </summary>
         public void Dispose()
         {
-            Close();
+            Dispose(true);
+            GC.SuppressFinalize(this);
         }
 
         internal UInt32 InitParam(ref Interop.TEEC_Parameter32[] dst, int i, Parameter src)
@@ -570,7 +611,7 @@ namespace Tizen.Security.TEEC
 
             for (int i=0; i < 4; ++i) {
                 if (shm[i] != null) {
-                    context.ReleaseSharedMemory(shm[i]);
+                    shm[i].Dispose();
                     shm[i] = null;
                 }
             }
@@ -603,7 +644,7 @@ namespace Tizen.Security.TEEC
 
             for (int i=0; i < 4; ++i) {
                 if (shm[i] != null) {
-                    context.ReleaseSharedMemory(shm[i]);
+                    shm[i].Dispose();
                     shm[i] = null;
                 }
             }
@@ -625,8 +666,7 @@ namespace Tizen.Security.TEEC
         /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
         /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
         public void Close() {
-            Dispose(true);
-            GC.SuppressFinalize(this);
+            Dispose();
         }
 
         /// <summary>
@@ -682,7 +722,7 @@ namespace Tizen.Security.TEEC
 
             for (int i=0; i < 4; ++i) {
                 if (shm[i] != null) {
-                    context.ReleaseSharedMemory(shm[i]);
+                    shm[i].Dispose();
                     shm[i] = null;
                 }
             }
@@ -722,6 +762,7 @@ namespace Tizen.Security.TEEC
         private bool disposed = false;
         private bool initialized = false;
         internal IntPtr context_imp;
+        internal uint shmcnt = 0;
 
         /// <summary>
         /// This function (constructor) initializes a new TEE Context, forming a connection between this client application and the
@@ -743,7 +784,7 @@ namespace Tizen.Security.TEEC
             try {
                 int ret = Interop.Libteec.InitializeContext(name, context_imp);
                 Interop.CheckNThrowException(ret, string.Format("InititalizeContext('{0}')", name));
-                               initialized = true;
+                initialized = true;
             }
             catch (global::System.DllNotFoundException e)
             {
@@ -753,14 +794,14 @@ namespace Tizen.Security.TEEC
             }
         }
 
-        // internal since class is sealed
-        internal void Dispose(bool disposing)
+        private void Dispose(bool disposing)
         {
             if (disposed) {
                 return ;
             }
             if (initialized) {
                 Interop.Libteec.FinalizeContext(context_imp);
+                initialized = false;
             }
             Marshal.FreeHGlobal(context_imp);
             context_imp = IntPtr.Zero;
@@ -783,6 +824,10 @@ namespace Tizen.Security.TEEC
         /// <privlevel>partner</privlevel>
         /// <feature>http://tizen.org/feature/security.tee</feature>
         public void Dispose() {
+            if (shmcnt != 0) {
+                Tizen.Log.Error("TZ_CLIENTAPI", "Context.Dispose not all shm released yet!");
+                return ;
+            }
             Dispose(true);
             GC.SuppressFinalize(this);
         }
@@ -906,13 +951,15 @@ namespace Tizen.Security.TEEC
         /// <exception cref="ArgumentException">The argument <paramref name="memaddr"/> is wrong.</exception>
         public SharedMemory RegisterSharedMemory(IntPtr memaddr, UInt32 size, SharedMemoryFlags flags)
         {
+            SharedMemory sharedmem =  new SharedMemory(this);
             Interop.TEEC_SharedMemory shm = new Interop.TEEC_SharedMemory();
             shm.buffer = memaddr;
-            shm.size = new UIntPtr(size);
+            shm.size = (UIntPtr)size;
             shm.flags = (UInt32)flags;
             int ret = Interop.Libteec.RegisterSharedMemory(context_imp, ref shm);
             Interop.CheckNThrowException(ret, "RegisterSharedMemory");
-            return new SharedMemory(ref shm);
+            sharedmem.setShm(ref shm);
+            return sharedmem;
         }
 
         /// <summary>
@@ -931,12 +978,14 @@ namespace Tizen.Security.TEEC
         /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
         public SharedMemory AllocateSharedMemory(UInt32 size, SharedMemoryFlags flags)
         {
+            SharedMemory sharedmem =  new SharedMemory(this);
             Interop.TEEC_SharedMemory shm = new Interop.TEEC_SharedMemory();
-            shm.size = new UIntPtr(size);
+            shm.size = (UIntPtr)size;
             shm.flags = (UInt32)flags;
             int ret = Interop.Libteec.AllocateSharedMemory(context_imp, ref shm);
             Interop.CheckNThrowException(ret, "AllocateSharedMemory");
-            return new SharedMemory(ref shm);
+            sharedmem.setShm(ref shm);
+            return sharedmem;
         }
 
         /// <summary>
@@ -962,7 +1011,7 @@ namespace Tizen.Security.TEEC
         /// <exception cref="ArgumentException">The argument is wrong.</exception>
         public void ReleaseSharedMemory(SharedMemory shm)
         {
-            Interop.Libteec.ReleaseSharedMemory(ref shm.shm);
+            shm.Dispose();
         }
     };