public async Task BindAsync() { // TODO: Move thread management to LibuvTransportFactory // TODO: Split endpoint management from thread management for (var index = 0; index < TransportOptions.ThreadCount; index++) { Threads.Add(new LibuvThread(Libuv, TransportContext)); } foreach (var thread in Threads) { await thread.StartAsync().ConfigureAwait(false); } try { if (TransportOptions.ThreadCount == 1) { var listener = new Listener(TransportContext); _listeners.Add(listener); await listener.StartAsync(EndPoint, Threads[0]).ConfigureAwait(false); EndPoint = listener.EndPoint; } else { var pipeName = (Core.IsWindows ? @"\\.\pipe\kestrel_" : "/tmp/kestrel_") + Guid.NewGuid().ToString("n"); var pipeMessage = Guid.NewGuid().ToByteArray(); var listenerPrimary = new ListenerPrimary(TransportContext); _listeners.Add(listenerPrimary); await listenerPrimary.StartAsync(pipeName, pipeMessage, EndPoint, Threads[0]).ConfigureAwait(false); EndPoint = listenerPrimary.EndPoint; foreach (var thread in Threads.Skip(1)) { var listenerSecondary = new ListenerSecondary(TransportContext); _listeners.Add(listenerSecondary); await listenerSecondary.StartAsync(pipeName, pipeMessage, EndPoint, thread).ConfigureAwait(false); } } _acceptEnumerator = AcceptConnections(); } catch (UvException ex) when(ex.StatusCode == LibuvConstants.EADDRINUSE) { await UnbindAsync().ConfigureAwait(false); throw new AddressInUseException(ex.Message, ex); } catch { await UnbindAsync().ConfigureAwait(false); throw; } }
public PipeReadContext(ListenerPrimary listener) { _listener = listener; _bufHandle = GCHandle.Alloc(_buf, GCHandleType.Pinned); _bufPtr = _bufHandle.AddrOfPinnedObject(); }