private void OnStopRude() { Walk(ptr => { var handle = UvMemory.FromIntPtr <UvHandle>(ptr); if (handle != _post) { // handle can be null because UvMemory.FromIntPtr looks up a weak reference handle?.Dispose(); } }); }
private void ThreadStart(object parameter) { lock (_startSync) { var startTcs = (TaskCompletionSource <int>)parameter; try { _uv = new Uv(); _loop.Init(_uv); _post.Init(_loop, OnPost, EnqueueCloseHandle); _initCompleted = true; startTcs.SetResult(0); } catch (Exception ex) { startTcs.SetException(ex); return; } } try { _loop.Run(); if (_stopImmediate) { // thread-abort form of exit, resources will be leaked return; } // run the loop one more time to delete the open handles _post.Reference(); _post.Dispose(); // We need this walk because we call ReadStop on accepted connections when there's back pressure // Calling ReadStop makes the handle as in-active which means the loop can // end while there's still valid handles around. This makes loop.Dispose throw // with an EBUSY. To avoid that, we walk all of the handles and dispose them. Walk(ptr => { var handle = UvMemory.FromIntPtr <UvHandle>(ptr); // handle can be null because UvMemory.FromIntPtr looks up a weak reference handle?.Dispose(); }); // Ensure the Dispose operations complete in the event loop. _loop.Run(); _loop.Dispose(); } catch (Exception ex) { _closeError = ex; // Request shutdown so we can rethrow this exception // in Stop which should be observable. //_appLifetime.StopApplication(); } finally { //try //{ // MemoryPool.Dispose(); //} //catch (Exception ex) //{ // _closeError = _closeError == null ? ex : new AggregateException(_closeError, ex); //} WriteReqPool.Dispose(); _threadTcs.SetResult(null); #if DEBUG // Check for handle leaks after disposing everything CheckUvReqLeaks(); #endif } }