Skip to content

Commit

Permalink
Reverted reference disposal to the original mechanism.
Browse files Browse the repository at this point in the history
  • Loading branch information
Quahu committed Mar 5, 2024
1 parent 35d03d3 commit ed6a8c7
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 8 deletions.
3 changes: 1 addition & 2 deletions src/Laylua.Tests/Tests/Entities/LuaReferenceTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using Laylua.Moon;
using NUnit.Framework;

Expand Down Expand Up @@ -75,7 +75,6 @@ public unsafe void NoReferencesToAliveObject_MarshalerFiresLeakedReferenceEvent(

// Assert
Assert.That(leakedReference, Is.EqualTo(reference));
return;

int CreateTable()
{
Expand Down
2 changes: 1 addition & 1 deletion src/Laylua/Library/Entities/Reference/LuaReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ private protected LuaReference()
if (LuaRegistry.IsPersistentReference(_reference) || _lua == null)
return;

_lua.Marshaler.ReturnReference(this);
_lua.Marshaler.OnReferenceCollected(this);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down
11 changes: 9 additions & 2 deletions src/Laylua/Library/Marshaler/LuaMarshaler.Internal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,22 @@ public abstract partial class LuaMarshaler
{
protected internal abstract void RemoveUserDataHandle(UserDataHandle handle);

internal void ReturnReference(LuaReference reference)
internal void OnReferenceCollected(LuaReference reference)
{
if (LuaReference.IsAlive(reference))
{
ReferenceLeaked?.Invoke(this, new LuaReferenceLeakedEventArgs(reference));

reference.Dispose();
_leakedReferences.Push(reference);
}
else
{
ReturnReference(reference);
}
}

private void ReturnReference(LuaReference reference)
{
if (_entityPool.Return(reference))
{
GC.ReRegisterForFinalize(reference);
Expand Down
27 changes: 24 additions & 3 deletions src/Laylua/Library/Marshaler/LuaMarshaler.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System;
using System.Collections.Concurrent;
using System.Runtime.CompilerServices;
using System.Threading;
using Laylua.Moon;
Expand Down Expand Up @@ -34,8 +35,10 @@ public UserDataDescriptorProvider UserDataDescriptorProvider
/// You can utilize this event to find out if your application
/// is failing to correctly dispose all <see cref="LuaReference"/> instances.
/// <para/>
/// Subscribed event handlers should be as lightweight as possible
/// and must not throw any exceptions.
/// Subscribed event handlers should be lightweight and must not throw exceptions.
/// <para/>
/// Subscribed handlers must not perform any Lua interactions,
/// as they might corrupt the Lua state.
/// </remarks>
public event EventHandler<LuaReferenceLeakedEventArgs>? ReferenceLeaked;

Expand All @@ -53,6 +56,7 @@ public LuaMarshalerEntityPoolConfiguration EntityPoolConfiguration

private UserDataDescriptorProvider _userDataDescriptorProvider = UserDataDescriptorProvider.Default;
private LuaReferencePool _entityPool = null!;
private readonly ConcurrentStack<LuaReference> _leakedReferences = new();

/// <summary>
/// Instantiates a new marshaler with the specified Lua instance.
Expand All @@ -77,6 +81,7 @@ protected LuaMarshaler(Lua lua)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected LuaTable CreateTable(int reference)
{
DisposeLeakedReferences();
return _entityPool.RentTable(reference);
}

Expand All @@ -90,6 +95,7 @@ protected LuaTable CreateTable(int reference)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected LuaFunction CreateFunction(int reference)
{
DisposeLeakedReferences();
return _entityPool.RentFunction(reference);
}

Expand All @@ -104,6 +110,7 @@ protected LuaFunction CreateFunction(int reference)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected LuaUserData CreateUserData(int reference, IntPtr ptr)
{
DisposeLeakedReferences();
return _entityPool.RentUserData(reference, ptr);
}

Expand All @@ -118,9 +125,21 @@ protected LuaUserData CreateUserData(int reference, IntPtr ptr)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected unsafe LuaThread CreateThread(int reference, lua_State* L)
{
DisposeLeakedReferences();
return _entityPool.RentThread(reference, L);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DisposeLeakedReferences()
{
while (_leakedReferences.TryPop(out var reference))
{
reference.Dispose();

ReturnReference(reference);
}
}

/// <summary>
/// Tries to convert the Lua value at the specified stack index
/// to a .NET value of type <typeparamref name="T"/>.
Expand Down Expand Up @@ -158,6 +177,8 @@ protected virtual void Dispose(bool disposing)
/// </summary>
public void Dispose()
{
DisposeLeakedReferences();

Dispose(true);
GC.SuppressFinalize(this);
}
Expand Down

0 comments on commit ed6a8c7

Please sign in to comment.