Skip to content

Commit

Permalink
Merge pull request #5622 from JBBee/cs_wrapper_fix3
Browse files Browse the repository at this point in the history
C# Wrapper Reference Counting for Sensor/Device
  • Loading branch information
dorodnic committed Mar 10, 2020
2 parents 39df687 + 96e256a commit 5014b46
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 5 deletions.
1 change: 1 addition & 0 deletions wrappers/csharp/Intel.RealSense/Base/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ target_sources(${LRS_DOTNET_TARGET}
"${CMAKE_CURRENT_LIST_DIR}/DeleterHandle.cs"
"${CMAKE_CURRENT_LIST_DIR}/Object.cs"
"${CMAKE_CURRENT_LIST_DIR}/PooledObject.cs"
"${CMAKE_CURRENT_LIST_DIR}/RefCountedPooledObject.cs"
)
76 changes: 76 additions & 0 deletions wrappers/csharp/Intel.RealSense/Base/RefCountedPooledObject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2017 Intel Corporation. All Rights Reserved.

//Adapted from: https://github.com/dotnet/reactive/blob/master/Rx.NET/Source/src/System.Reactive/Disposables/RefCountDisposable.cs
namespace Intel.RealSense.Base
{
using System;

/// <summary>
/// Base class for objects in an <cref see="ObjectPool">ObjectPool</cref>
/// </summary>
public class RefCountedPooledObject : PooledObject
{
protected RefCount refCount;

protected RefCountedPooledObject(IntPtr ptr, Deleter deleter)
: base(ptr, deleter)
{
}

internal void Retain()
{
if (m_instance.IsInvalid)
{
throw new ObjectDisposedException("RefCountedPooledObject");
}

if (refCount.count == int.MaxValue)
{
throw new OverflowException("RefCountedPooledObject can't handle more than " + int.MaxValue + " disposables");
}
refCount.count++;
}

protected override void Dispose(bool disposing)
{
if (m_instance.IsInvalid)
{
return;
}

bool didDispose = Release(disposing);

//Dispose of this instance even if the underlying resource still exists
if (!didDispose)
{
m_instance.SetHandleAsInvalid();
ObjectPool.Release(this);
}
}

private bool Release(bool disposing)
{
System.Diagnostics.Debug.Assert(refCount.count > 0);

refCount.count--;
if (refCount.count == 0)
{
base.Dispose(disposing);
return true;
}

return false;
}

internal override void Initialize()
{
throw new NotImplementedException();
}
}

public sealed class RefCount
{
public int count;
}
}
37 changes: 36 additions & 1 deletion wrappers/csharp/Intel.RealSense/Devices/Device.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,48 @@ namespace Intel.RealSense
/// <summary>
/// The device object represents a physical camera and provides the means to manipulate it.
/// </summary>
public class Device : Base.PooledObject
public class Device : Base.RefCountedPooledObject
{
protected static Hashtable refCountTable = new Hashtable();
protected static readonly object tableLock = new object();

internal override void Initialize()
{
lock (tableLock)
{
if (refCountTable.Contains(Handle))
refCount = refCountTable[Handle] as Base.RefCount;
else
{
refCount = new Base.RefCount();
refCountTable[Handle] = refCount;
}
Retain();
}
Info = new InfoCollection(NativeMethods.rs2_supports_device_info, NativeMethods.rs2_get_device_info, Handle);
}

protected override void Dispose(bool disposing)
{
if (m_instance.IsInvalid)
{
return;
}

lock (tableLock)
{
IntPtr localHandle = Handle;
System.Diagnostics.Debug.Assert(refCountTable.Contains(localHandle));

base.Dispose(disposing);

if (refCount.count == 0)
{
refCountTable.Remove(localHandle);
}
}
}

internal Device(IntPtr ptr)
: base(ptr, null)
{
Expand Down
38 changes: 34 additions & 4 deletions wrappers/csharp/Intel.RealSense/Sensors/Sensor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,24 @@ namespace Intel.RealSense
using System.Runtime.InteropServices;

// TODO: subclasses - DepthSensor, DepthStereoSensor, PoseSensor...
public class Sensor : Base.PooledObject, IOptions
public class Sensor : Base.RefCountedPooledObject, IOptions
{
protected static Hashtable refCountTable = new Hashtable();
protected static readonly object tableLock = new object();

internal override void Initialize()
{
lock (tableLock)
{
if (refCountTable.Contains(Handle))
refCount = refCountTable[Handle] as Base.RefCount;
else
{
refCount = new Base.RefCount();
refCountTable[Handle] = refCount;
}
Retain();
}
Info = new InfoCollection(NativeMethods.rs2_supports_sensor_info, NativeMethods.rs2_get_sensor_info, Handle);
Options = new OptionsList(Handle);
}
Expand Down Expand Up @@ -46,15 +60,31 @@ public static T Create<T>(Sensor other)
internal Sensor(IntPtr sensor)
: base(sensor, NativeMethods.rs2_delete_sensor)
{
Info = new InfoCollection(NativeMethods.rs2_supports_sensor_info, NativeMethods.rs2_get_sensor_info, Handle);
Options = new OptionsList(Handle);
Initialize();
}

protected override void Dispose(bool disposing)
{
if (m_instance.IsInvalid)
{
return;
}

//m_queue.Dispose();
(Options as OptionsList).Dispose();
base.Dispose(disposing);

lock (tableLock)
{
IntPtr localHandle = Handle;
System.Diagnostics.Debug.Assert(refCountTable.Contains(localHandle));

base.Dispose(disposing);

if (refCount.count == 0)
{
refCountTable.Remove(localHandle);
}
}
}

public class CameraInfos : IEnumerable<KeyValuePair<CameraInfo, string>>
Expand Down

0 comments on commit 5014b46

Please sign in to comment.