* Change EnumerateGateways to use the 'static_EnumerateGatewaysHandler' callback. It looks like this was a c&p error, since the 'static_EnumerateGatewaysHandler' callback was implemented, just never referenced anywhere. * Add an overload to EnumerateGateways and EnumerateInterfaces that takes a callback that returns a bool indicating whether the enumeration should continue. This mirrors the native API. * Obsolete the EnumerateGateways and EnumerateInterfaces overloads that take a void callback (and remove in XAMCORE_5_0). * Add a test for EnumerateGateways that works (the previous failed, but never asserted the failure, so it would just silently time out). Fixes https://github.com/xamarin/xamarin-macios/issues/13772.
This commit is contained in:
Родитель
513355602d
Коммит
7e6edcbc36
|
@ -10,6 +10,7 @@
|
||||||
#nullable enable
|
#nullable enable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using ObjCRuntime;
|
using ObjCRuntime;
|
||||||
|
@ -112,22 +113,42 @@ namespace Network {
|
||||||
return nw_path_is_equal (GetCheckedHandle (), other.Handle);
|
return nw_path_is_equal (GetCheckedHandle (), other.Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate void nw_path_enumerate_interfaces_block_t (IntPtr block, IntPtr iface);
|
// Returning 'byte' since 'bool' isn't blittable
|
||||||
|
delegate byte nw_path_enumerate_interfaces_block_t (IntPtr block, IntPtr iface);
|
||||||
static nw_path_enumerate_interfaces_block_t static_Enumerator = TrampolineEnumerator;
|
static nw_path_enumerate_interfaces_block_t static_Enumerator = TrampolineEnumerator;
|
||||||
|
|
||||||
[MonoPInvokeCallback (typeof (nw_path_enumerate_interfaces_block_t))]
|
[MonoPInvokeCallback (typeof (nw_path_enumerate_interfaces_block_t))]
|
||||||
static void TrampolineEnumerator (IntPtr block, IntPtr iface)
|
static byte TrampolineEnumerator (IntPtr block, IntPtr iface)
|
||||||
{
|
{
|
||||||
var del = BlockLiteral.GetTarget<Action<NWInterface>> (block);
|
var del = BlockLiteral.GetTarget<Func<NWInterface, bool>> (block);
|
||||||
if (del is not null)
|
if (del is not null)
|
||||||
del (new NWInterface (iface, owns: false));
|
return del (new NWInterface (iface, owns: false)) ? (byte) 1 : (byte) 0;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport (Constants.NetworkLibrary)]
|
[DllImport (Constants.NetworkLibrary)]
|
||||||
static extern void nw_path_enumerate_interfaces (IntPtr handle, ref BlockLiteral callback);
|
static extern void nw_path_enumerate_interfaces (IntPtr handle, ref BlockLiteral callback);
|
||||||
|
|
||||||
[BindingImpl (BindingImplOptions.Optimizable)]
|
|
||||||
|
#if !XAMCORE_5_0
|
||||||
|
[Obsolete ("Use the overload that takes a 'Func<NWInterface, bool>' instead.")]
|
||||||
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||||
public void EnumerateInterfaces (Action<NWInterface> callback)
|
public void EnumerateInterfaces (Action<NWInterface> callback)
|
||||||
|
{
|
||||||
|
if (callback is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Func<NWInterface, bool> func = (v) =>
|
||||||
|
{
|
||||||
|
callback (v);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
EnumerateInterfaces (func);
|
||||||
|
}
|
||||||
|
#endif // !XAMCORE_5_0
|
||||||
|
|
||||||
|
[BindingImpl (BindingImplOptions.Optimizable)]
|
||||||
|
public void EnumerateInterfaces (Func<NWInterface, bool> callback)
|
||||||
{
|
{
|
||||||
if (callback is null)
|
if (callback is null)
|
||||||
return;
|
return;
|
||||||
|
@ -181,19 +202,45 @@ namespace Network {
|
||||||
[DllImport (Constants.NetworkLibrary)]
|
[DllImport (Constants.NetworkLibrary)]
|
||||||
static extern void nw_path_enumerate_gateways (IntPtr path, ref BlockLiteral enumerate_block);
|
static extern void nw_path_enumerate_gateways (IntPtr path, ref BlockLiteral enumerate_block);
|
||||||
|
|
||||||
delegate void nw_path_enumerate_gateways_t (IntPtr block, IntPtr endpoint);
|
// Returning 'byte' since 'bool' isn't blittable
|
||||||
|
delegate byte nw_path_enumerate_gateways_t (IntPtr block, IntPtr endpoint);
|
||||||
static nw_path_enumerate_gateways_t static_EnumerateGatewaysHandler = TrampolineGatewaysHandler;
|
static nw_path_enumerate_gateways_t static_EnumerateGatewaysHandler = TrampolineGatewaysHandler;
|
||||||
|
|
||||||
[MonoPInvokeCallback (typeof (nw_path_enumerate_gateways_t))]
|
[MonoPInvokeCallback (typeof (nw_path_enumerate_gateways_t))]
|
||||||
static void TrampolineGatewaysHandler (IntPtr block, IntPtr endpoint)
|
static byte TrampolineGatewaysHandler (IntPtr block, IntPtr endpoint)
|
||||||
{
|
{
|
||||||
var del = BlockLiteral.GetTarget<Action<NWEndpoint>> (block);
|
var del = BlockLiteral.GetTarget<Func<NWEndpoint, bool>> (block);
|
||||||
if (del is not null) {
|
if (del is not null) {
|
||||||
var nwEndpoint = new NWEndpoint (endpoint, owns: false);
|
var nwEndpoint = new NWEndpoint (endpoint, owns: false);
|
||||||
del (nwEndpoint);
|
return del (nwEndpoint) ? (byte) 1 : (byte) 0;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !XAMCORE_5_0
|
||||||
|
#if NET
|
||||||
|
[SupportedOSPlatform ("tvos13.0")]
|
||||||
|
[SupportedOSPlatform ("macos10.15")]
|
||||||
|
[SupportedOSPlatform ("ios13.0")]
|
||||||
|
[SupportedOSPlatform ("maccatalyst")]
|
||||||
|
#else
|
||||||
|
[TV (13,0)]
|
||||||
|
[Mac (10,15)]
|
||||||
|
[iOS (13,0)]
|
||||||
|
#endif
|
||||||
|
[Obsolete ("Use the overload that takes a 'Func<NWEndpoint, bool>' instead.")]
|
||||||
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||||
|
public void EnumerateGateways (Action<NWEndpoint> callback)
|
||||||
|
{
|
||||||
|
Func<NWEndpoint,bool> func = (v) =>
|
||||||
|
{
|
||||||
|
callback (v);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
EnumerateGateways (func);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if NET
|
#if NET
|
||||||
[SupportedOSPlatform ("tvos13.0")]
|
[SupportedOSPlatform ("tvos13.0")]
|
||||||
[SupportedOSPlatform ("macos10.15")]
|
[SupportedOSPlatform ("macos10.15")]
|
||||||
|
@ -205,13 +252,13 @@ namespace Network {
|
||||||
[iOS (13,0)]
|
[iOS (13,0)]
|
||||||
#endif
|
#endif
|
||||||
[BindingImpl (BindingImplOptions.Optimizable)]
|
[BindingImpl (BindingImplOptions.Optimizable)]
|
||||||
public void EnumerateGateways (Action<NWEndpoint> callback)
|
public void EnumerateGateways (Func<NWEndpoint, bool> callback)
|
||||||
{
|
{
|
||||||
if (callback is null)
|
if (callback is null)
|
||||||
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (callback));
|
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (callback));
|
||||||
|
|
||||||
BlockLiteral block_handler = new BlockLiteral ();
|
BlockLiteral block_handler = new BlockLiteral ();
|
||||||
block_handler.SetupBlockUnsafe (static_Enumerator, callback);
|
block_handler.SetupBlockUnsafe (static_EnumerateGatewaysHandler, callback);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
nw_path_enumerate_gateways (GetCheckedHandle (), ref block_handler);
|
nw_path_enumerate_gateways (GetCheckedHandle (), ref block_handler);
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace Cecil.Tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Events?
|
// TODO: Events?
|
||||||
Assert.That (found, Is.Empty, "Obsolete API");
|
Assert.That (found, Is.Empty, "Obsolete API: add '[EditorBrowsable (EditorBrowsableState.Never)]' for newly obsoleted API to pass this test.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FilterMember (ICustomAttributeProvider provider)
|
bool FilterMember (ICustomAttributeProvider provider)
|
||||||
|
|
|
@ -162,19 +162,43 @@ namespace MonoTouchFixtures.Network {
|
||||||
{
|
{
|
||||||
TestRuntime.AssertXcodeVersion (11, 0);
|
TestRuntime.AssertXcodeVersion (11, 0);
|
||||||
|
|
||||||
Assert.Throws<ArgumentNullException> (() => { path.EnumerateGateways (null); });
|
Assert.Throws<ArgumentNullException> (() => { path.EnumerateGateways ((Func<NWEndpoint, bool>) null); });
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void EnumerateGatewayTest ()
|
public void EnumerateGatewayTest ()
|
||||||
{
|
{
|
||||||
TestRuntime.AssertXcodeVersion (11, 0);
|
var e1 = new ManualResetEvent (false);
|
||||||
var e = new AutoResetEvent (false);
|
var e2 = new ManualResetEvent (false);
|
||||||
path.EnumerateGateways ((endPoint) => {
|
var monitor = new NWPathMonitor ();
|
||||||
Assert.IsNotNull (endPoint);
|
try {
|
||||||
e.Set ();
|
monitor.SetQueue (DispatchQueue.DefaultGlobalQueue);
|
||||||
|
monitor.Start ();
|
||||||
|
monitor.SnapshotHandler += path =>
|
||||||
|
{
|
||||||
|
path.EnumerateGateways (gateway =>
|
||||||
|
{
|
||||||
|
e1.Set ();
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
e.WaitOne (10000);
|
|
||||||
|
path.EnumerateInterfaces (@interface =>
|
||||||
|
{
|
||||||
|
e2.Set ();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
TestRuntime.RunAsync (TimeSpan.FromSeconds (5),
|
||||||
|
() => { },
|
||||||
|
() => WaitHandle.WaitAll (new WaitHandle [] { e1, e2 }, 0));
|
||||||
|
var rv = WaitHandle.WaitAll (new WaitHandle [] { e1, e2 }, 10000);
|
||||||
|
if (!rv)
|
||||||
|
TestRuntime.IgnoreInCI ("This test doesn't seem to be working on the bots, uncommon network setup?");
|
||||||
|
Assert.IsTrue (rv, "Called back");
|
||||||
|
} finally {
|
||||||
|
monitor.Cancel ();
|
||||||
|
monitor.Dispose ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
Загрузка…
Ссылка в новой задаче