Skip to content

Commit

Permalink
Instead of a static refcount per Sensor/Device, make a table of refco…
Browse files Browse the repository at this point in the history
…unts indexed by the Handle.
  • Loading branch information
JBBee committed Jan 10, 2020
1 parent 548dc67 commit 19df94c
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 43 deletions.
48 changes: 13 additions & 35 deletions wrappers/csharp/Intel.RealSense/Base/RefCountedPooledObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ namespace Intel.RealSense.Base
/// </summary>
public class RefCountedPooledObject : PooledObject
{
private RefCount refCount;
protected RefCount refCount;

protected RefCountedPooledObject(IntPtr ptr, Deleter deleter, RefCount _refCount)
protected RefCountedPooledObject(IntPtr ptr, Deleter deleter)
: base(ptr, deleter)
{
refCount = _refCount;
}

internal void Retain()
Expand All @@ -27,22 +26,11 @@ internal void Retain()
throw new ObjectDisposedException("RefCountedPooledObject");
}

var cnt = Thread.VolatileRead(ref refCount.count);

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

var u = Interlocked.CompareExchange(ref refCount.count, cnt + 1, cnt);
if (u == cnt)
{
break;
}
cnt = u;
throw new OverflowException("RefCountedPooledObject can't handle more than " + int.MaxValue + " disposables");
}
refCount.count++;
}

protected override void Dispose(bool disposing)
Expand All @@ -64,26 +52,16 @@ protected override void Dispose(bool disposing)

private bool Release(bool disposing)
{
bool didDispose = false;
var cnt = Thread.VolatileRead(ref refCount.count);
for (; ; )
{
System.Diagnostics.Debug.Assert(cnt > 0);
System.Diagnostics.Debug.Assert(refCount.count > 0);

var u = cnt - 1;
var b = Interlocked.CompareExchange(ref refCount.count, u, cnt);
if (b == cnt)
{
if (u == 0)
{
base.Dispose(disposing);
didDispose = true;
}
break;
}
cnt = b;
refCount.count--;
if (refCount.count == 0)
{
base.Dispose(disposing);
return true;
}
return didDispose;

return false;
}

internal override void Initialize()
Expand Down
40 changes: 36 additions & 4 deletions wrappers/csharp/Intel.RealSense/Devices/Device.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,54 @@ namespace Intel.RealSense
/// </summary>
public class Device : Base.RefCountedPooledObject
{
protected static Base.RefCount refCount = new Base.RefCount();
protected static Hashtable refCountTable = new Hashtable();
protected static readonly object tableLock = new object();

internal override void Initialize()
{
Retain();
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)
{
lock (tableLock)
{
if (m_instance.IsInvalid)
{
return;
}

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, refCount)
: base(ptr, null)
{
this.Initialize();
}

internal Device(IntPtr ptr, Base.Deleter deleter)
: base(ptr, deleter, refCount)
: base(ptr, deleter)
{
this.Initialize();
}
Expand Down
37 changes: 33 additions & 4 deletions wrappers/csharp/Intel.RealSense/Sensors/Sensor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,27 @@ namespace Intel.RealSense
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;

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

internal override void Initialize()
{
Retain();
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 @@ -47,7 +59,7 @@ public static T Create<T>(Sensor other)
}

internal Sensor(IntPtr sensor)
: base(sensor, NativeMethods.rs2_delete_sensor, refCount)
: base(sensor, NativeMethods.rs2_delete_sensor)
{
Initialize();
}
Expand All @@ -56,7 +68,24 @@ protected override void Dispose(bool disposing)
{
//m_queue.Dispose();
(Options as OptionsList).Dispose();
base.Dispose(disposing);

lock (tableLock)
{
if (m_instance.IsInvalid)
{
return;
}

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 19df94c

Please sign in to comment.