コード例 #1
0
        public TcpConnection connect(Ipv4Address address, uint16_t port)
        {
            Debug.Assert(dispatcher != null);
            Debug.Assert(context == null);
            if (dispatcher.interrupted())
            {
                throw InterruptedException();
            }

            string message;
            int    connection = global::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

            if (connection == -1)
            {
                message = "socket failed, " + lastErrorMessage();
            }
            else
            {
                sockaddr_in bindAddress = new sockaddr_in();
                bindAddress.sin_family      = AF_INET;
                bindAddress.sin_port        = 0;
                bindAddress.sin_addr.s_addr = INADDR_ANY;
//C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#:
                if (bind(connection, reinterpret_cast <sockaddr>(bindAddress), sizeof(sockaddr_in)) != 0)
                {
                    message = "bind failed, " + lastErrorMessage();
                }
                else
                {
                    int flags = fcntl(connection, F_GETFL, 0);
                    if (flags == -1 || fcntl(connection, F_SETFL, flags | O_NONBLOCK) == -1)
                    {
                        message = "fcntl failed, " + lastErrorMessage();
                    }
                    else
                    {
                        sockaddr_in addressData = new sockaddr_in();
                        addressData.sin_family      = AF_INET;
                        addressData.sin_port        = htons(port);
                        addressData.sin_addr.s_addr = htonl(address.getValue());
//C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#:
                        int result = global::connect(connection, reinterpret_cast <sockaddr>(addressData), sizeof(sockaddr_in));
                        if (result == -1)
                        {
                            if (errno == EINPROGRESS)
                            {
                                ContextPair            contextPair      = new ContextPair();
                                TcpConnectorContextExt connectorContext = new TcpConnectorContextExt();
                                connectorContext.interrupted = false;
                                connectorContext.context     = dispatcher.getCurrentContext();
                                connectorContext.connection  = connection;

                                contextPair.readContext  = null;
                                contextPair.writeContext = connectorContext;

                                epoll_event connectEvent = new epoll_event();
                                connectEvent.events   = EPOLLOUT | EPOLLRDHUP | EPOLLERR | EPOLLONESHOT;
                                connectEvent.data.ptr = contextPair;
                                if (epoll_ctl(dispatcher.getEpoll(), EPOLL_CTL_ADD, connection, connectEvent) == -1)
                                {
                                    message = "epoll_ctl failed, " + lastErrorMessage();
                                }
                                else
                                {
                                    context = connectorContext;
                                    dispatcher.getCurrentContext().interruptProcedure = () =>
                                    {
                                        TcpConnectorContextExt connectorContext1 = (TcpConnectorContextExt)context;
                                        if (!connectorContext1.interrupted)
                                        {
                                            if (close(connectorContext1.connection) == -1)
                                            {
                                                throw new System.Exception("TcpListener::stop, close failed, " + lastErrorMessage());
                                            }

                                            connectorContext1.interrupted = true;
                                            dispatcher.pushContext(connectorContext1.context);
                                        }
                                    };

                                    dispatcher.dispatch();
                                    dispatcher.getCurrentContext().interruptProcedure = null;
                                    Debug.Assert(dispatcher != null);
                                    Debug.Assert(connectorContext.context == dispatcher.getCurrentContext());
                                    Debug.Assert(contextPair.readContext == null);
                                    Debug.Assert(context == connectorContext);
                                    context = null;
                                    connectorContext.context = null;
                                    if (connectorContext.interrupted)
                                    {
                                        throw InterruptedException();
                                    }

                                    if (epoll_ctl(dispatcher.getEpoll(), EPOLL_CTL_DEL, connection, null) == -1)
                                    {
                                        message = "epoll_ctl failed, " + lastErrorMessage();
                                    }
                                    else
                                    {
                                        if ((connectorContext.events & (EPOLLERR | EPOLLHUP)) != 0)
                                        {
                                            int result = close(connection);
                                            if (result != 0)
                                            {
                                            }
                                            Debug.Assert(result != -1);

                                            throw new System.Exception("TcpConnector::connect, connection failed");
                                        }

                                        int       retval    = -1;
                                        socklen_t retValLen = sizeof(int);
                                        int       s         = getsockopt(connection, SOL_SOCKET, SO_ERROR, retval, retValLen);
                                        if (s == -1)
                                        {
                                            message = "getsockopt failed, " + lastErrorMessage();
                                        }
                                        else
                                        {
                                            if (retval != 0)
                                            {
                                                message = "getsockopt failed, " + lastErrorMessage();
                                            }
                                            else
                                            {
                                                return(new TcpConnection(dispatcher, connection));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            return(new TcpConnection(dispatcher, connection));
                        }
                    }
                }

                int result = close(connection);
                if (result != 0)
                {
                }
                Debug.Assert(result != -1);
            }


            throw new System.Exception("TcpConnector::connect, " + message);
        }
コード例 #2
0
        public void sleep(std::chrono.nanoseconds duration)
        {
            Debug.Assert(dispatcher != null);
            Debug.Assert(context == null);
            if (dispatcher.interrupted())
            {
                throw InterruptedException();
            }

            if (duration.count() == 0)
            {
                dispatcher.yield();
            }
            else
            {
                timer = dispatcher.getTimer();

                var        seconds = std::chrono.duration_cast <std::chrono.seconds>(duration);
                itimerspec expires = new itimerspec();
                expires.it_interval.tv_nsec = expires.it_interval.tv_sec = 0;
                expires.it_value.tv_sec     = seconds.count();
                expires.it_value.tv_nsec    = std::chrono.duration_cast <std::chrono.nanoseconds>(duration - seconds).count();
                timerfd_settime(timer, 0, expires, null);

                ContextPair      contextPair  = new ContextPair();
                OperationContext timerContext = new OperationContext();
                timerContext.interrupted = false;
                timerContext.context     = dispatcher.getCurrentContext();
                contextPair.writeContext = null;
                contextPair.readContext  = timerContext;

                epoll_event timerEvent = new epoll_event();
                timerEvent.events   = EPOLLIN | EPOLLONESHOT;
                timerEvent.data.ptr = contextPair;

                if (epoll_ctl(dispatcher.getEpoll(), EPOLL_CTL_MOD, timer, timerEvent) == -1)
                {
                    throw new System.Exception("Timer::sleep, epoll_ctl failed, " + lastErrorMessage());
                }
                dispatcher.getCurrentContext().interruptProcedure = () =>
                {
                    Debug.Assert(dispatcher != null);
                    Debug.Assert(context != null);
                    OperationContext timerContext = (OperationContext)context;
                    if (!timerContext.interrupted)
                    {
                        uint64_t value = 0;
                        if (global::read(timer, value, sizeof(uint64_t)) == -1)
                        {
                            //C++ TO C# CONVERTER TODO TASK: There is no equivalent to most C++ 'pragma' directives in C#:
                            //#pragma GCC diagnostic push
                            //C++ TO C# CONVERTER TODO TASK: There is no equivalent to most C++ 'pragma' directives in C#:
                            //#pragma GCC diagnostic ignored "-Wlogical-op"
                            if (errno == EAGAIN || errno == EWOULDBLOCK)
                            {
                                //C++ TO C# CONVERTER TODO TASK: There is no equivalent to most C++ 'pragma' directives in C#:
                                //#pragma GCC diagnostic pop
                                timerContext.interrupted = true;
                                dispatcher.pushContext(timerContext.context);
                            }
                            else
                            {
                                throw new System.Exception("Timer::sleep, interrupt procedure, read failed, " + lastErrorMessage());
                            }
                        }
                        else
                        {
                            Debug.Assert(value > 0);
                            dispatcher.pushContext(timerContext.context);
                        }

                        epoll_event timerEvent = new epoll_event();
                        timerEvent.events   = EPOLLONESHOT;
                        timerEvent.data.ptr = null;

                        if (epoll_ctl(dispatcher.getEpoll(), EPOLL_CTL_MOD, timer, timerEvent) == -1)
                        {
                            throw new System.Exception("Timer::sleep, interrupt procedure, epoll_ctl failed, " + lastErrorMessage());
                        }
                    }
                };

                context = timerContext;
                dispatcher.dispatch();
                dispatcher.getCurrentContext().interruptProcedure = null;
                Debug.Assert(dispatcher != null);
                Debug.Assert(timerContext.context == dispatcher.getCurrentContext());
                Debug.Assert(contextPair.writeContext == null);
                Debug.Assert(context == &timerContext);
                context = null;
                timerContext.context = null;
                dispatcher.pushTimer(timer);
                if (timerContext.interrupted)
                {
                    throw InterruptedException();
                }
            }
        }
コード例 #3
0
ファイル: TcpListener.cs プロジェクト: ooosbkf/turtlecoin-net
        public TcpConnection accept()
        {
            Debug.Assert(dispatcher != null);
            Debug.Assert(context == null);
            if (dispatcher.interrupted())
            {
                throw InterruptedException();
            }

            ContextPair      contextPair     = new ContextPair();
            OperationContext listenerContext = new OperationContext();

            listenerContext.interrupted = false;
            listenerContext.context     = dispatcher.getCurrentContext();

            contextPair.writeContext = null;
            contextPair.readContext  = listenerContext;

            epoll_event listenEvent = new epoll_event();

            listenEvent.events   = EPOLLIN | EPOLLONESHOT;
            listenEvent.data.ptr = contextPair;
            string message;

            if (epoll_ctl(dispatcher.getEpoll(), EPOLL_CTL_MOD, listener, listenEvent) == -1)
            {
                message = "epoll_ctl failed, " + lastErrorMessage();
            }
            else
            {
                context = listenerContext;
                dispatcher.getCurrentContext().interruptProcedure = () =>
                {
                    Debug.Assert(dispatcher != null);
                    Debug.Assert(context != null);
                    OperationContext listenerContext = (OperationContext)context;
                    if (!listenerContext.interrupted)
                    {
                        epoll_event listenEvent = new epoll_event();
                        listenEvent.events   = EPOLLONESHOT;
                        listenEvent.data.ptr = null;

                        if (epoll_ctl(dispatcher.getEpoll(), EPOLL_CTL_MOD, listener, listenEvent) == -1)
                        {
                            throw new System.Exception("TcpListener::accept, interrupt procedure, epoll_ctl failed, " + lastErrorMessage());
                        }

                        listenerContext.interrupted = true;
                        dispatcher.pushContext(listenerContext.context);
                    }
                };

                dispatcher.dispatch();
                dispatcher.getCurrentContext().interruptProcedure = null;
                Debug.Assert(dispatcher != null);
                Debug.Assert(listenerContext.context == dispatcher.getCurrentContext());
                Debug.Assert(contextPair.writeContext == null);
                Debug.Assert(context == &listenerContext);
                context = null;
                listenerContext.context = null;
                if (listenerContext.interrupted)
                {
                    throw InterruptedException();
                }

                if ((listenerContext.events & (EPOLLERR | EPOLLHUP)) != 0)
                {
                    throw new System.Exception("TcpListener::accept, accepting failed");
                }

                sockaddr  inAddr     = new sockaddr();
                socklen_t inLen      = sizeof(sockaddr);
                int       connection = global::accept(listener, inAddr, inLen);
                if (connection == -1)
                {
                    message = "accept failed, " + lastErrorMessage();
                }
                else
                {
                    int flags = fcntl(connection, F_GETFL, 0);
                    if (flags == -1 || fcntl(connection, F_SETFL, flags | O_NONBLOCK) == -1)
                    {
                        message = "fcntl failed, " + lastErrorMessage();
                    }
                    else
                    {
                        return(new TcpConnection(dispatcher, connection));
                    }

                    int result = close(connection);
                    if (result != 0)
                    {
                    }
                    Debug.Assert(result != -1);
                }
            }

            throw new System.Exception("TcpListener::accept, " + message);
        }