Skip to content

Commit

Permalink
Test issue for reference tracking in Objective-C (dotnet#56441)
Browse files Browse the repository at this point in the history
* Test issue for reference count in Objective-C

* Review feedback.
  • Loading branch information
AaronRobinsonMSFT authored Jul 30, 2021
1 parent fbed4b9 commit 0573d55
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,18 @@ namespace
::abort();
}


assert(mem != nullptr);
auto cxt = (Contract*)mem;

cxt->RefCountDown--;
cxt->RefCountUp++;

if (cxt->RefCountDown == 0)
{
// No more references
return 0;
}
else
{
cxt->RefCountDown--;
cxt->RefCountUp++;
return 1;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
<!-- Test unsupported outside of OSX -->
<CLRTestTargetUnsupported Condition="'$(TargetsOSX)' != 'true'">true</CLRTestTargetUnsupported>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<!-- Disable under GCStress. Tracking: https://github.com/dotnet/runtime/issues/53359 -->
<GCStressIncompatible>true</GCStressIncompatible>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.cs" />
Expand Down
17 changes: 10 additions & 7 deletions src/tests/Interop/ObjectiveC/ObjectiveCMarshalAPI/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,17 +139,17 @@ static void InitializeObjectiveCMarshal()
ObjectiveCMarshal.Initialize(beginEndCallback, isReferencedCallback, trackedObjectEnteredFinalization, OnUnhandledExceptionPropagationHandler);
}

static GCHandle AllocAndTrackObject<T>() where T : Base, new()
static GCHandle AllocAndTrackObject<T>(uint count) where T : Base, new()
{
var obj = new T();
GCHandle h = ObjectiveCMarshal.CreateReferenceTrackingHandle(obj, out Span<IntPtr> s);

// Validate contract length for tagged memory.
Assert.AreEqual(2, s.Length);

// Make the "is referenced" callback run a few times.
// Make the "is referenced" callback run at least 'count' number of times.
fixed (void* p = s)
obj.SetContractMemory((IntPtr)p, count: 3);
obj.SetContractMemory((IntPtr)p, count);
return h;
}

Expand Down Expand Up @@ -188,24 +188,27 @@ static unsafe void Validate_ReferenceTracking_Scenario()
ObjectiveCMarshal.CreateReferenceTrackingHandle(new AttributedNoFinalizer(), out _);
});

// Provide the minimum number of times the reference callback should run.
// See IsRefCb() in NativeObjCMarshalTests.cpp for usage logic.
const uint callbackCount = 3;
{
GCHandle h = AllocAndTrackObject<Base>();
GCHandle h = AllocAndTrackObject<Base>(callbackCount);
handles.Add(h);
Validate_AllocAndFreeAnotherHandle<Base>(h);
}
{
GCHandle h = AllocAndTrackObject<Derived>();
GCHandle h = AllocAndTrackObject<Derived>(callbackCount);
handles.Add(h);
Validate_AllocAndFreeAnotherHandle<Derived>(h);
}
{
GCHandle h = AllocAndTrackObject<DerivedWithFinalizer>();
GCHandle h = AllocAndTrackObject<DerivedWithFinalizer>(callbackCount);
handles.Add(h);
Validate_AllocAndFreeAnotherHandle<DerivedWithFinalizer>(h);
}

// Trigger the GC
for (int i = 0; i < 5; ++i)
for (int i = 0; i < (callbackCount + 2); ++i)
{
GC.Collect();
GC.WaitForPendingFinalizers();
Expand Down

0 comments on commit 0573d55

Please sign in to comment.