Пример #1
0
        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));
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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));
        }