private void OnStabilized(IntPtr context, IntPtr table) { UnsafeNetInfoNativeMethods.FreeMibTable(table); if (!this.runCallbackCalled) { lock (this) { if (!this.runCallbackCalled) { this.runCallbackCalled = true; ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(this.RunCallback), null); } } } }
// This callback gets run on a native worker thread, which we don't want to allow arbitrary user code to // execute on (it will block AppDomain unload, for one). Free the MibTable and delegate (exactly once) // to the managed ThreadPool for the rest of the processing. // // We can't use SafeHandle here for table because the marshaller doesn't support them in reverse p/invokes. // We won't get an AppDomain unload here anyways, because OnAppDomainUnloaded will block until all of these // callbacks are done. private void OnStabilized(IntPtr context, IntPtr table) { UnsafeNetInfoNativeMethods.FreeMibTable(table); // Lock the TeredoHelper instance to ensure that only the first call to OnStabilized will get to call // RunCallback. This is the only place that TeredoHelpers get locked, as individual instances are not // exposed to higher layers, so there's no chance for deadlock. if (!runCallbackCalled) { lock (this) { if (!runCallbackCalled) { runCallbackCalled = true; ThreadPool.UnsafeQueueUserWorkItem(RunCallback, null); } } } }
protected override bool ReleaseHandle() { UnsafeNetInfoNativeMethods.FreeMibTable(base.handle); base.handle = IntPtr.Zero; return(true); }