public ValueTask <ConnectionContext> Connect(IPEndPoint endpoint) { var domain = endpoint.AddressFamily == AddressFamily.InterNetwork ? AF_INET : AF_INET6; LinuxSocket s = socket(domain, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_TCP); if (_threadContext.Options.TcpNoDelay) { s.SetOption(SOL_TCP, TCP_NODELAY, 1); } var context = new OutboundConnectionContext(s, endpoint, _threadContext); var tcs = new TaskCompletionSource <ConnectionContext>(TaskCreationOptions.RunContinuationsAsynchronously); // Ensure the transport thread doesn't run continuations context.ConnectCompletion = tcs; endpoint.ToSockAddr(context.Addr, out var addrLength); context.AddrLen = addrLength; _connections[s] = context; Connect(context); _threadContext.Notify(); return(new ValueTask <ConnectionContext>(tcs.Task)); }
private void CompleteConnect(OutboundConnectionContext context, int result) { var completion = context.ConnectCompletion; if (result < 0) { if (-result != EAGAIN || -result != EINTR) { context.ConnectCompletion = null; completion.TrySetException(new ErrnoException(-result)); } Debug.WriteLine($"connect completed with EAGAIN on {(int)context.Socket}"); Connect(context); return; } Debug.WriteLine($"Connected to {(int)context.Socket}"); context.ConnectCompletion = null; // no need to hold on to this context.LocalEndPoint = context.Socket.GetLocalAddress(); completion.TrySetResult(context); Read(context); ReadFromApp(context); }
private void Connect(OutboundConnectionContext context) { var socket = context.Socket; Debug.WriteLine($"Adding connect on {(int)socket}"); _ring.AcquireSubmission(out var submission); submission.PrepareConnect(socket, (sockaddr *)context.Addr, context.AddrLen, Mask(socket, ConnectMask)); _ring.Release(submission); }
public ValueTask <ConnectionContext> Connect(IPEndPoint endpoint) { var domain = endpoint.AddressFamily == AddressFamily.InterNetwork ? AF_INET : AF_INET6; LinuxSocket s = socket(domain, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_TCP); if (_threadContext.Options.TcpNoDelay) { s.SetOption(SOL_TCP, TCP_NODELAY, 1); } var context = new OutboundConnectionContext(s, endpoint, _threadContext); bool connectedSynchronously; try { connectedSynchronously = s.TryConnectNonBlocking(endpoint); } catch (ErrnoException ex) { return(new ValueTask <ConnectionContext>(Task.FromException <ConnectionContext>(ex))); } if (connectedSynchronously) { context.LocalEndPoint = s.GetLocalAddress(); return(new ValueTask <ConnectionContext>(context)); } var tcs = new TaskCompletionSource <ConnectionContext>(); context.ConnectCompletion = tcs; // Socket will become writable, once connect completed _clientSocketQueue.Enqueue(context); _threadContext.Notify(); return(new ValueTask <ConnectionContext>(tcs.Task)); }
private void CompleteConnect(OutboundConnectionContext context, int result) { var completion = context.ConnectCompletion; if (result < 0) { if (-result != EAGAIN || -result != EINTR) { context.ConnectCompletion = null; completion.TrySetException(new ErrnoException(-result)); } Connect(context); return; } context.ConnectCompletion = null; // no need to hold on to this context.LocalEndPoint = context.Socket.GetLocalAddress(); completion.TrySetResult(context); ReadPoll(context); ReadFromApp(context); }
private void Connect(OutboundConnectionContext context) { var socket = context.Socket; _ring.PrepareConnect(socket, (sockaddr *)context.Addr, context.AddrLen, Mask(socket, ConnectMask)); }