* 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
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.CompilerServices;
|
||||
using ObjCRuntime;
|
||||
|
@ -112,22 +113,42 @@ namespace Network {
|
|||
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;
|
||||
|
||||
[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)
|
||||
del (new NWInterface (iface, owns: false));
|
||||
return del (new NWInterface (iface, owns: false)) ? (byte) 1 : (byte) 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
[DllImport (Constants.NetworkLibrary)]
|
||||
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)
|
||||
{
|
||||
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)
|
||||
return;
|
||||
|
@ -181,19 +202,45 @@ namespace Network {
|
|||
[DllImport (Constants.NetworkLibrary)]
|
||||
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;
|
||||
|
||||
[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) {
|
||||
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
|
||||
[SupportedOSPlatform ("tvos13.0")]
|
||||
[SupportedOSPlatform ("macos10.15")]
|
||||
|
@ -205,13 +252,13 @@ namespace Network {
|
|||
[iOS (13,0)]
|
||||
#endif
|
||||
[BindingImpl (BindingImplOptions.Optimizable)]
|
||||
public void EnumerateGateways (Action<NWEndpoint> callback)
|
||||
public void EnumerateGateways (Func<NWEndpoint, bool> callback)
|
||||
{
|
||||
if (callback is null)
|
||||
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (callback));
|
||||
|
||||
BlockLiteral block_handler = new BlockLiteral ();
|
||||
block_handler.SetupBlockUnsafe (static_Enumerator, callback);
|
||||
block_handler.SetupBlockUnsafe (static_EnumerateGatewaysHandler, callback);
|
||||
|
||||
try {
|
||||
nw_path_enumerate_gateways (GetCheckedHandle (), ref block_handler);
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace Cecil.Tests {
|
|||
}
|
||||
|
||||
// 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)
|
||||
|
|
|
@ -162,19 +162,43 @@ namespace MonoTouchFixtures.Network {
|
|||
{
|
||||
TestRuntime.AssertXcodeVersion (11, 0);
|
||||
|
||||
Assert.Throws<ArgumentNullException> (() => { path.EnumerateGateways (null); });
|
||||
Assert.Throws<ArgumentNullException> (() => { path.EnumerateGateways ((Func<NWEndpoint, bool>) null); });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EnumerateGatewayTest ()
|
||||
{
|
||||
TestRuntime.AssertXcodeVersion (11, 0);
|
||||
var e = new AutoResetEvent (false);
|
||||
path.EnumerateGateways ((endPoint) => {
|
||||
Assert.IsNotNull (endPoint);
|
||||
e.Set ();
|
||||
var e1 = new ManualResetEvent (false);
|
||||
var e2 = new ManualResetEvent (false);
|
||||
var monitor = new NWPathMonitor ();
|
||||
try {
|
||||
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]
|
||||
|
|
Загрузка…
Ссылка в новой задаче