internal static extern int timerfd_settime(int fd, int flags, itimerspec new_value, itimerspec old_value);
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(); } } }