Troubleshooting Embargo / EmbargoServer TC

This commit is contained in:
Christian Köllner 2019-08-20 21:26:13 +02:00
parent 44fd4edfe9
commit fecfa94433
4 changed files with 24 additions and 27 deletions

View File

@ -774,6 +774,7 @@ namespace Capnp.Net.Runtime.Tests
var cap = new TestCallOrderImpl(); var cap = new TestCallOrderImpl();
cap.CountToDispose = 6; cap.CountToDispose = 6;
Skeleton.BeginAssertNotDisposed(cap);
var earlyCall = main.GetCallSequence(0, default); var earlyCall = main.GetCallSequence(0, default);
var echo = main.Echo(cap, default); var echo = main.Echo(cap, default);
@ -807,6 +808,8 @@ namespace Capnp.Net.Runtime.Tests
Assert.AreEqual(3u, call3.Result); Assert.AreEqual(3u, call3.Result);
Assert.AreEqual(4u, call4.Result); Assert.AreEqual(4u, call4.Result);
Assert.AreEqual(5u, call5.Result); Assert.AreEqual(5u, call5.Result);
Skeleton.EndAssertNotDisposed(cap);
} }
} }
} }

View File

@ -24,6 +24,8 @@ namespace Capnp.Rpc
{ {
_question = question ?? throw new ArgumentNullException(nameof(question)); _question = question ?? throw new ArgumentNullException(nameof(question));
_access = access ?? throw new ArgumentNullException(nameof(access)); _access = access ?? throw new ArgumentNullException(nameof(access));
_ = AwaitWhenResolved();
} }
async void ReAllowFinishWhenDone(Task task) async void ReAllowFinishWhenDone(Task task)
@ -56,6 +58,8 @@ namespace Capnp.Rpc
protected override Proxy ResolvedCap protected override Proxy ResolvedCap
{ {
get get
{
lock (_question.ReentrancyBlocker)
{ {
if (_resolvedCap == null && !_question.IsTailCall && _question.IsReturned) if (_resolvedCap == null && !_question.IsTailCall && _question.IsReturned)
{ {
@ -74,6 +78,7 @@ namespace Capnp.Rpc
return _resolvedCap; return _resolvedCap;
} }
} }
}
async Task<Proxy> AwaitWhenResolved() async Task<Proxy> AwaitWhenResolved()
{ {

View File

@ -973,7 +973,7 @@ namespace Capnp.Rpc
void ReleaseExport(uint id, uint count) void ReleaseExport(uint id, uint count)
{ {
bool exists, badrc = false; bool exists;
lock (_reentrancyBlocker) lock (_reentrancyBlocker)
{ {
@ -993,9 +993,9 @@ namespace Capnp.Rpc
_revExportTable.ReplacementTryRemove(rc.Cap, out uint _); _revExportTable.ReplacementTryRemove(rc.Cap, out uint _);
} }
} }
catch (System.Exception) catch (System.Exception exception)
{ {
badrc = true; Logger.LogWarning($"Attempting to release capability with invalid reference count: {exception.Message}");
} }
} }
} }
@ -1004,10 +1004,6 @@ namespace Capnp.Rpc
{ {
Logger.LogWarning("Attempting to release unknown capability ID"); Logger.LogWarning("Attempting to release unknown capability ID");
} }
else if (badrc)
{
Logger.LogWarning("Attempting to release capability with invalid reference count");
}
} }
void ProcessRelease(Release.READER release) void ProcessRelease(Release.READER release)

View File

@ -29,9 +29,7 @@ namespace Capnp.Rpc
} }
} }
#if DEBUG
const int NoDisposeFlag = 0x4000000; const int NoDisposeFlag = 0x4000000;
#endif
static readonly ConditionalWeakTable<object, Skeleton> _implMap = static readonly ConditionalWeakTable<object, Skeleton> _implMap =
new ConditionalWeakTable<object, Skeleton>(); new ConditionalWeakTable<object, Skeleton>();
@ -63,7 +61,6 @@ namespace Capnp.Rpc
return new SkeletonRelinquisher(GetOrCreateSkeleton(impl, true)); return new SkeletonRelinquisher(GetOrCreateSkeleton(impl, true));
} }
#if DEBUG
/// <summary> /// <summary>
/// This DEBUG-only diagnostic method states that the Skeleton corresponding to a given capability is not expected to /// This DEBUG-only diagnostic method states that the Skeleton corresponding to a given capability is not expected to
/// be disposed until the next call to EndAssertNotDisposed(). /// be disposed until the next call to EndAssertNotDisposed().
@ -84,7 +81,6 @@ namespace Capnp.Rpc
{ {
GetOrCreateSkeleton(impl, false).EndAssertNotDisposed(); GetOrCreateSkeleton(impl, false).EndAssertNotDisposed();
} }
#endif
int _refCount = 0; int _refCount = 0;
@ -103,7 +99,6 @@ namespace Capnp.Rpc
Interlocked.Increment(ref _refCount); Interlocked.Increment(ref _refCount);
} }
#if DEBUG
internal void BeginAssertNotDisposed() internal void BeginAssertNotDisposed()
{ {
if ((Interlocked.Add(ref _refCount, NoDisposeFlag) & NoDisposeFlag) == 0) if ((Interlocked.Add(ref _refCount, NoDisposeFlag) & NoDisposeFlag) == 0)
@ -118,7 +113,6 @@ namespace Capnp.Rpc
throw new InvalidOperationException("Flag already cleared. State is now broken."); throw new InvalidOperationException("Flag already cleared. State is now broken.");
} }
} }
#endif
internal void Relinquish() internal void Relinquish()
{ {
@ -126,9 +120,8 @@ namespace Capnp.Rpc
if (0 == count) if (0 == count)
{ {
#if DEBUG if ((count & NoDisposeFlag) != 0)
Debug.Assert((_refCount & NoDisposeFlag) == 0, "Skeleton disposal not expected in this state"); throw new InvalidOperationException("Unexpected Skeleton disposal");
#endif
Dispose(true); Dispose(true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);