public static bool UnsafeNotifyStableUnicastIpAddressTable(Action<object> callback, object state)
{
if (callback == null)
{
NetEventSource.Fail(null, "UnsafeNotifyStableUnicastIpAddressTable called without specifying callback!");
}
TeredoHelper helper = new TeredoHelper(callback, state);
uint err = Interop.IpHlpApi.ERROR_SUCCESS;
SafeFreeMibTable table = null;
lock (s_pendingNotifications)
{
// If OnAppDomainUnload gets the lock first, tell our caller that we'll finish async. Their AppDomain
// is about to go down anyways. If we do, hold the lock until we've added helper to the
// s_pendingNotifications list (if we're going to complete asynchronously).
if (Environment.HasShutdownStarted)
{
return false;
}
err = Interop.IpHlpApi.NotifyStableUnicastIpAddressTable(AddressFamily.Unspecified,
out table, helper._onStabilizedDelegate, IntPtr.Zero, out helper._cancelHandle);
if (table != null)
{
table.Dispose();
}
if (err == Interop.IpHlpApi.ERROR_IO_PENDING)
{
if (helper._cancelHandle.IsInvalid)
{
NetEventSource.Fail(null, "CancelHandle invalid despite returning ERROR_IO_PENDING");
}
// Async completion: add us to the s_pendingNotifications list so we'll be canceled in the
// event of an AppDomain unload.
s_pendingNotifications.Add(helper);
return false;
}
}
if (err != Interop.IpHlpApi.ERROR_SUCCESS)
{
throw new Win32Exception((int)err);
}
return true;
}