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); }
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(); } } }
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); }