/// 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>
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 ;
/// </summary>
public void Dispose()
{
- Close();
+ Dispose(true);
+ GC.SuppressFinalize(this);
}
internal UInt32 InitParam(ref Interop.TEEC_Parameter32[] dst, int i, Parameter src)
for (int i=0; i < 4; ++i) {
if (shm[i] != null) {
- context.ReleaseSharedMemory(shm[i]);
+ shm[i].Dispose();
shm[i] = null;
}
}
for (int i=0; i < 4; ++i) {
if (shm[i] != null) {
- context.ReleaseSharedMemory(shm[i]);
+ shm[i].Dispose();
shm[i] = null;
}
}
/// <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>
for (int i=0; i < 4; ++i) {
if (shm[i] != null) {
- context.ReleaseSharedMemory(shm[i]);
+ shm[i].Dispose();
shm[i] = null;
}
}
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
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)
{
}
}
- // 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;
/// <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);
}
/// <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>
/// <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>
/// <exception cref="ArgumentException">The argument is wrong.</exception>
public void ReleaseSharedMemory(SharedMemory shm)
{
- Interop.Libteec.ReleaseSharedMemory(ref shm.shm);
+ shm.Dispose();
}
};