Skip to content

Commit b169c2c

Browse files
committed
Perform Free only on finalizers
1 parent a8f8c9d commit b169c2c

File tree

2 files changed

+38
-17
lines changed

2 files changed

+38
-17
lines changed

Utility/DnsARecordResult.cs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System;
44
using System.Net;
55
using System.Net.Sockets;
6+
using System.Runtime.CompilerServices;
67
using System.Runtime.InteropServices;
78

89
namespace Hi3Helper.Plugin.Core.Utility;
@@ -88,29 +89,38 @@ public static IPAddress[] GetIPAddressArray(DnsARecordResult* dnsARecordP)
8889
DnsARecordResult* next = endResultP->NextResult;
8990

9091
// Convert the struct into IPAddress instance.
91-
returnIpAddresses[offset++] = GetIPAddressFromResultAndDispose(endResultP);
92+
returnIpAddresses[offset++] = new IPAddress(new ReadOnlySpan<byte>(endResultP->AddressData, endResultP->AddressDataLength));
9293
endResultP = next;
9394
} while (endResultP != null); // Do the loop if the next entry is not null.
9495

9596
// If done, return the array.
9697
return returnIpAddresses;
9798
}
9899

99-
// ReSharper disable once InconsistentNaming
100-
private static IPAddress GetIPAddressFromResultAndDispose(DnsARecordResult* resultP)
100+
/// <summary>
101+
/// Free the instance of <see cref="DnsARecordResult"/> struct and its entries.
102+
/// </summary>
103+
/// <param name="resultP">The pointer of the current <see cref="DnsARecordResult"/> entry.</param>
104+
/// <param name="isFreeAll">If set to true, the current entry and all its next entries will be freed. Otherwise, just free the current one.</param>
105+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
106+
public static void Free(nint resultP, bool isFreeAll = true)
107+
=> Free((DnsARecordResult*)resultP, isFreeAll);
108+
109+
/// <summary>
110+
/// Free the instance of <see cref="DnsARecordResult"/> struct and its entries.
111+
/// </summary>
112+
/// <param name="resultP">The pointer of the current <see cref="DnsARecordResult"/> entry.</param>
113+
/// <param name="isFreeAll">If set to true, the current entry and all its next entries will be freed. Otherwise, just free the current one.</param>
114+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
115+
public static void Free(DnsARecordResult* resultP, bool isFreeAll = true)
101116
{
102-
try
103-
{
104-
return new IPAddress(new ReadOnlySpan<byte>(resultP->AddressData, resultP->AddressDataLength));
105-
}
106-
finally
117+
do
107118
{
108-
// If the result is not null, free the string and the struct.
109-
if (resultP != null)
110-
{
111-
Mem.Free(resultP);
112-
}
113-
}
119+
DnsARecordResult* nextP = resultP->NextResult;
120+
Mem.Free(resultP);
121+
122+
resultP = nextP;
123+
} while (resultP != null && isFreeAll);
114124
}
115125

116126
/// <summary>

Utility/PluginHttpClientBuilder.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,9 +417,20 @@ private static async Task<IPAddress[]> GetDnsResolverArrayFromCallbackAsync(stri
417417

418418
// Cast as ComAsyncResult and wait as Task, grab the pointer to the DnsARecordResult entries.
419419
nint dnsARecordResultP = await comAsyncResultP.AsTask<nint>();
420-
// Then call this MF to convert DnsARecordResult* (and also freeing the pointer) into IPAddress[],
421-
// then return the IPAddress[] so the socket callback can use it.
422-
return DnsARecordResult.GetIPAddressArray(dnsARecordResultP);
420+
try
421+
{
422+
// Then call this MF to convert DnsARecordResult* (and also freeing the pointer) into IPAddress[],
423+
// then return the IPAddress[] so the socket callback can use it.
424+
return DnsARecordResult.GetIPAddressArray(dnsARecordResultP);
425+
}
426+
finally
427+
{
428+
if (dnsARecordResultP != nint.Zero)
429+
{
430+
// Free the DnsARecordResult pointer only if it's not null.
431+
DnsARecordResult.Free(dnsARecordResultP);
432+
}
433+
}
423434

424435
unsafe nint GetAsyncResultPointer(out VoidCallback cancelTriggerCallback)
425436
{

0 commit comments

Comments
 (0)