コード例 #1
0
        private void RemovePinFromPoll(int bcmPinNumber, ref int pollFileDescriptor, bool closePinValueFileDescriptor, bool closePollFileDescriptor)
        {
            //Console.WriteLine($"Removing pin from poll: {bcmPinNumber}");

            int fd = _pinValueFileDescriptors[bcmPinNumber];

            var ev = new epoll_event
            {
                events = PollEvents.EPOLLIN | PollEvents.EPOLLET | PollEvents.EPOLLPRI,
            };

            //Console.WriteLine($"poll_fd = {pollFileDescriptor}, pin_value_fd = {fd}");

            int r = epoll_ctl(pollFileDescriptor, PollOperations.EPOLL_CTL_DEL, fd, ref ev);

            if (r == -1)
            {
                throw Utils.CreateIOException("Error initializing pin interrupts", r);
            }

            if (closePinValueFileDescriptor)
            {
                close(fd);
                _pinValueFileDescriptors[bcmPinNumber] = -1;
            }

            if (closePollFileDescriptor)
            {
                close(pollFileDescriptor);
                pollFileDescriptor = -1;
            }
        }
コード例 #2
0
ファイル: SysFsDriver.Linux.cs プロジェクト: rcwowbagger/iot
        private void RemovePinFromPoll(int pinNumber, ref int valueFileDescriptor, ref int pollFileDescriptor, bool closePinValueFileDescriptor, bool closePollFileDescriptor, bool cancelEventDetectionThread)
        {
            epoll_event epollEvent = new epoll_event
            {
                events = PollEvents.EPOLLIN | PollEvents.EPOLLET | PollEvents.EPOLLPRI
            };

            int result = Interop.epoll_ctl(pollFileDescriptor, PollOperations.EPOLL_CTL_DEL, valueFileDescriptor, ref epollEvent);

            if (result == -1)
            {
                throw new IOException("Error while trying to initialize pin interrupts.");
            }

            if (closePinValueFileDescriptor)
            {
                Interop.close(valueFileDescriptor);
                valueFileDescriptor = -1;
            }
            if (closePollFileDescriptor)
            {
                if (cancelEventDetectionThread)
                {
                    s_eventThreadCancellationTokenSource.Cancel();
                    while (_eventDetectionThread != null && _eventDetectionThread.IsAlive)
                    {
                        Thread.Sleep(TimeSpan.FromMilliseconds(10)); // Wait until the event detection thread is aborted.
                    }
                }

                Interop.close(pollFileDescriptor);
                pollFileDescriptor = -1;
            }
        }
コード例 #3
0
ファイル: LinuxSocket.cs プロジェクト: UCIS/UCIS.Core
        void EpollWait()
        {
            Dictionary <int, LinuxSocket> sockmap;

            lock (typeof(LinuxSocket)) {
                if (epollfd == -1)
                {
                    epollfd = epoll_create1(0x80000);
                    if (epollfd == -1)
                    {
                        throw new PosixException("epoll_create1");
                    }
                    epollfds     = 0;
                    epollsockets = new Dictionary <int, LinuxSocket>();
                }
                sockmap = epollsockets;
                if (epollthread == null)
                {
                    epollthread = new Thread(EpollLoop);
                    epollthread.IsBackground = true;
                    epollthread.Start();
                }
            }
            lock (sockmap) sockmap[handle] = this;
            lock (this) {
                uint mode = (1 << 30);                 //ONESHOT
                if (recvqhead != null)
                {
                    mode |= 0x001;
                }
                if (sendqhead != null)
                {
                    mode |= 0x004;
                }
                if ((mode & 0x005) == 0)
                {
                    return;
                }
                epoll_event evt = new epoll_event()
                {
                    Events = mode, Data = (UInt64)handle
                };
                int ret = epoll_ctl(epollfd, 1, handle, ref evt);                 //ADD
                if (ret != -1)
                {
                    Interlocked.Increment(ref epollfds);
                }
                if (ret == -1 && Marshal.GetLastWin32Error() == 17)
                {
                    ret = epoll_ctl(epollfd, 3, handle, ref evt);                                                                 //MODIFY
                }
                if (ret == -1)
                {
                    throw new PosixException("epoll_ctl");
                }
            }
        }
コード例 #4
0
        private void AddPinToPoll(int bcmPinNumber, ref int pollFileDescriptor, out bool closePinValueFileDescriptor)
        {
            //Console.WriteLine($"Adding pin to poll: {bcmPinNumber}");

            if (pollFileDescriptor == -1)
            {
                pollFileDescriptor = epoll_create(1);

                if (pollFileDescriptor < 0)
                {
                    throw Utils.CreateIOException("Error initializing pin interrupts", pollFileDescriptor);
                }
            }

            closePinValueFileDescriptor = false;
            int fd = _pinValueFileDescriptors[bcmPinNumber];

            if (fd <= 0)
            {
                string valuePath = $"{GpioPath}/gpio{bcmPinNumber}/value";
                fd = open(valuePath, FileOpenFlags.O_RDONLY | FileOpenFlags.O_NONBLOCK);

                //Console.WriteLine($"{valuePath} open result: {fd}");

                if (fd < 0)
                {
                    throw Utils.CreateIOException("Error initializing pin interrupts", fd);
                }

                _pinValueFileDescriptors[bcmPinNumber] = fd;
                closePinValueFileDescriptor            = true;
            }

            var ev = new epoll_event
            {
                events = PollEvents.EPOLLIN | PollEvents.EPOLLET | PollEvents.EPOLLPRI,
                data   = new epoll_data()
                {
                    //fd = fd
                    bcmPinNumber = bcmPinNumber
                }
            };

            //Console.WriteLine($"poll_fd = {pollFileDescriptor}, pin_value_fd = {fd}");

            int r = epoll_ctl(pollFileDescriptor, PollOperations.EPOLL_CTL_ADD, fd, ref ev);

            if (r == -1)
            {
                throw Utils.CreateIOException("Error initializing pin interrupts", r);
            }

            // Ignore first time because it returns the current state
            epoll_wait(pollFileDescriptor, out _, 1, 0);
        }
コード例 #5
0
        public static unsafe PosixResult EPollControl(int epoll, int operation, int fd, int events, int data)
        {
            epoll_event ev = default(epoll_event);

            ev.events  = events;
            ev.data.fd = data;

            int rv = epoll_ctl(epoll, operation, fd, &ev);

            return(PosixResult.FromReturnValue(rv));
        }
コード例 #6
0
            public unsafe void Control(int op, int fd, int events, int key)
            {
                epoll_event ev = default;

                ev.events  = events;
                ev.data.fd = key;
                int rv = epoll_ctl(_epollFd, op, fd, &ev);

                if (rv != 0)
                {
                    PlatformException.Throw();
                }
            }
コード例 #7
0
        private TcpConnection(Dispatcher dispatcher, int socket)
        {
            this.dispatcher          = dispatcher;
            this.connection          = socket;
            contextPair.readContext  = null;
            contextPair.writeContext = null;
            epoll_event connectionEvent = new epoll_event();

            connectionEvent.events   = EPOLLONESHOT;
            connectionEvent.data.ptr = null;

            if (epoll_ctl(dispatcher.getEpoll(), EPOLL_CTL_ADD, socket, connectionEvent) == -1)
            {
                throw new System.Exception("TcpConnection::TcpConnection, epoll_ctl failed, " + lastErrorMessage());
            }
        }
コード例 #8
0
        private void AddPinToPoll(int pinNumber, ref int valueFileDescriptor, ref int pollFileDescriptor, out bool closePinValueFileDescriptor)
        {
            if (pollFileDescriptor == -1)
            {
                pollFileDescriptor = Interop.epoll_create(1);
                if (pollFileDescriptor < 0)
                {
                    throw new IOException("Error while trying to initialize pin interrupts (epoll_create failed).");
                }
            }

            closePinValueFileDescriptor = false;

            if (valueFileDescriptor == -1)
            {
                string valuePath = Path.Combine(GpioBasePath, $"gpio{pinNumber + s_pinOffset}", "value");
                valueFileDescriptor = Interop.open(valuePath, FileOpenFlags.O_RDONLY | FileOpenFlags.O_NONBLOCK);
                if (valueFileDescriptor < 0)
                {
                    throw new IOException($"Error while trying to open pin value file {valuePath}.");
                }

                closePinValueFileDescriptor = true;
            }

            epoll_event epollEvent = new epoll_event
            {
                events = PollEvents.EPOLLIN | PollEvents.EPOLLET | PollEvents.EPOLLPRI,
                data   = new epoll_data()
                {
                    pinNumber = pinNumber
                }
            };

            int result = Interop.epoll_ctl(pollFileDescriptor, PollOperations.EPOLL_CTL_ADD, valueFileDescriptor, ref epollEvent);

            if (result == -1)
            {
                throw new IOException("Error while trying to initialize pin interrupts (epoll_ctl failed).");
            }

            // Ignore first time because it will always return the current state.
            Interop.epoll_wait(pollFileDescriptor, out _, 1, 0);
        }
コード例 #9
0
        public X11PlatformThreading(AvaloniaX11Platform platform)
        {
            _platform      = platform;
            _display       = platform.Display;
            _eventHandlers = platform.Windows;
            _mainThread    = Thread.CurrentThread;
            var fd = XLib.XConnectionNumber(_display);
            var ev = new epoll_event()
            {
                events = EPOLLIN,
                data   = { u32 = (int)EventCodes.X11 }
            };

            _epoll = epoll_create1(0);
            if (_epoll == -1)
            {
                throw new X11Exception("epoll_create1 failed");
            }

            if (epoll_ctl(_epoll, EPOLL_CTL_ADD, fd, ref ev) == -1)
            {
                throw new X11Exception("Unable to attach X11 connection handle to epoll");
            }

            var fds = stackalloc int[2];

            pipe2(fds, O_NONBLOCK);
            _sigread  = fds[0];
            _sigwrite = fds[1];

            ev = new epoll_event
            {
                events = EPOLLIN,
                data   = { u32 = (int)EventCodes.Signal }
            };
            if (epoll_ctl(_epoll, EPOLL_CTL_ADD, _sigread, ref ev) == -1)
            {
                throw new X11Exception("Unable to attach signal pipe to epoll");
            }
        }
コード例 #10
0
ファイル: LinuxSocket.cs プロジェクト: UCIS/UCIS.Core
        //public void Connect(IPAddress[] addresses, int port);
        //public void Connect(string host, int port);
        protected virtual void Dispose(bool disposing)
        {
            int fd = handle;

            handle = -1;
            if (fd != -1)
            {
                Dictionary <int, LinuxSocket> sockmap;
                lock (typeof(LinuxSocket)) {
                    if (epollfd != -1)
                    {
                        epoll_event evt = new epoll_event();
                        epoll_ctl(epollfd, 2, fd, ref evt);
                    }
                    sockmap = epollsockets;
                }
                if (sockmap != null)
                {
                    lock (sockmap) sockmap.Remove(fd);
                }
                close(fd);
            }
        }
コード例 #11
0
        public void Initialize(IScreenInfoProvider info, Action <RawInputEventArgs> onInput)
        {
            _onInput = onInput;
            _epoll   = epoll_create1(0);
            for (var c = 0; c < _deviceDescriptions.Length; c++)
            {
                var description = _deviceDescriptions[c];
                var dev         = EvDevDevice.Open(description.Path);
                EvDevDeviceHandler handler;
                if (description is EvDevTouchScreenDeviceDescription touch)
                {
                    handler = new EvDevSingleTouchScreen(dev, touch, info)
                    {
                        InputRoot = _inputRoot
                    }
                }
                ;
                else
                {
                    throw new Exception("Unknown device description type " + description.GetType().FullName);
                }

                handler.OnEvent += OnRawEvent;
                _handlers.Add(handler);

                var ev = new epoll_event {
                    events = EPOLLIN, data = { u32 = (uint)c }
                };
                epoll_ctl(_epoll, EPOLL_CTL_ADD, dev.Fd, ref ev);
            }

            new Thread(InputThread)
            {
                IsBackground = true
            }.Start();
        }
コード例 #12
0
 extern static int epoll_ctl(int epfd, int op, int fd, ref epoll_event __event);
コード例 #13
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();
                }
            }
        }
コード例 #14
0
ファイル: LinuxSocket.cs プロジェクト: UCIS/UCIS.Core
 static void EpollLoop()
 {
     epoll_event[] events = new epoll_event[8];
     try {
         Dictionary <int, LinuxSocket> sockmap = epollsockets;
         if (sockmap == null)
         {
             return;
         }
         while (true)
         {
             int ret = epoll_wait(epollfd, events, events.Length, 1000);
             if (ret == -1 && Marshal.GetLastWin32Error() == 4)
             {
                 continue;                                                                    //Interrupted by signal
             }
             if (ret == -1)
             {
                 throw new PosixException("epoll_wait");
             }
             for (int i = 0; i < ret; i++)
             {
                 Interlocked.Decrement(ref epollfds);
                 LinuxSocket sock;
                 lock (sockmap) if (!sockmap.TryGetValue((int)events[i].Data, out sock))
                     {
                         sock = null;
                     }
                 UInt32 evt = events[i].Events;
                 if (sock != null)
                 {
                     sock.EpollEvent((evt & 0x001) != 0, (evt & 0x004) != 0, (evt & 0x008) != 0, (evt & 0x010) != 0);
                 }
             }
             if (sockmap.Count == 0)
             {
                 lock (typeof(LinuxSocket)) {
                     if (sockmap.Count != 0)
                     {
                         continue;
                     }
                     close(epollfd);
                     epollfd      = -1;
                     epollthread  = null;
                     epollsockets = null;
                     break;
                 }
             }
         }
     } catch {
         lock (typeof(LinuxSocket)) {
             if (epollfd != -1)
             {
                 close(epollfd);
             }
             epollfd      = -1;
             epollthread  = null;
             epollsockets = null;
         }
         throw;
     }
 }
コード例 #15
0
ファイル: LinuxSocket.cs プロジェクト: UCIS/UCIS.Core
 static extern int epoll_ctl(int epfd, int op, int fd, [In] ref epoll_event @event);
コード例 #16
0
 private static extern int epoll_ctl(int epfd, int op, int fd, ref epoll_event __event);
コード例 #17
0
ファイル: Interop.epoll_ctl.cs プロジェクト: nnyamhon/corefx
 public static extern unsafe int epoll_ctl(int epfd, int op, int fd, epoll_event* @event);
コード例 #18
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);
        }
コード例 #19
0
 internal static extern int epoll_wait(int epfd, out epoll_event events, int maxevents, int timeout);
コード例 #20
0
ファイル: TcpListener.cs プロジェクト: ooosbkf/turtlecoin-net
        public TcpListener(Dispatcher dispatcher, Ipv4Address addr, uint16_t port)
        {
            this.dispatcher = dispatcher;
            string message;

            listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
            if (listener == -1)
            {
                message = "socket failed, " + lastErrorMessage();
            }
            else
            {
                int flags = fcntl(listener, F_GETFL, 0);
                if (flags == -1 || fcntl(listener, F_SETFL, flags | O_NONBLOCK) == -1)
                {
                    message = "fcntl failed, " + lastErrorMessage();
                }
                else
                {
                    int on = 1;
                    if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, on, sizeof(int)) == -1)
                    {
                        message = "setsockopt failed, " + lastErrorMessage();
                    }
                    else
                    {
                        sockaddr_in address = new sockaddr_in();
                        address.sin_family      = AF_INET;
                        address.sin_port        = htons(port);
                        address.sin_addr.s_addr = htonl(addr.getValue());
//C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#:
                        if (bind(listener, reinterpret_cast <sockaddr>(address), sizeof(sockaddr_in)) != 0)
                        {
                            message = "bind failed, " + lastErrorMessage();
                        }
                        else if (listen(listener, SOMAXCONN) != 0)
                        {
                            message = "listen failed, " + lastErrorMessage();
                        }
                        else
                        {
                            epoll_event listenEvent = new epoll_event();
                            listenEvent.events   = EPOLLONESHOT;
                            listenEvent.data.ptr = null;

                            if (epoll_ctl(dispatcher.getEpoll(), EPOLL_CTL_ADD, listener, listenEvent) == -1)
                            {
                                message = "epoll_ctl failed, " + lastErrorMessage();
                            }
                            else
                            {
                                context = null;
                                return;
                            }
                        }
                    }
                }

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

            throw new System.Exception("TcpListener::TcpListener, " + message);
        }
コード例 #21
0
ファイル: Dispatcher.cs プロジェクト: ooosbkf/turtlecoin-net
        public Dispatcher()
        {
            string message;

            epoll = global::epoll_create1(0);
            if (epoll == -1)
            {
                message = "epoll_create1 failed, " + lastErrorMessage();
            }
            else
            {
                mainContext.ucontext = new ucontext_t();
//C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#:
                if (getcontext(reinterpret_cast <ucontext_t>(mainContext.ucontext)) == -1)
                {
                    message = "getcontext failed, " + lastErrorMessage();
                }
                else
                {
                    remoteSpawnEvent = eventfd(0, O_NONBLOCK);
                    if (remoteSpawnEvent == -1)
                    {
                        message = "eventfd failed, " + lastErrorMessage();
                    }
                    else
                    {
                        remoteSpawnEventContext.writeContext = null;
                        remoteSpawnEventContext.readContext  = null;

                        epoll_event remoteSpawnEventEpollEvent = new epoll_event();
                        remoteSpawnEventEpollEvent.events   = EPOLLIN;
                        remoteSpawnEventEpollEvent.data.ptr = remoteSpawnEventContext;

                        if (epoll_ctl(epoll, EPOLL_CTL_ADD, remoteSpawnEvent, remoteSpawnEventEpollEvent) == -1)
                        {
                            message = "epoll_ctl failed, " + lastErrorMessage();
                        }
                        else
                        {
//C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#:
                            *reinterpret_cast <pthread_mutex_t>(this.mutex) = pthread_mutex_t(PTHREAD_MUTEX_INITIALIZER);

                            mainContext.interrupted      = false;
                            mainContext.group            = contextGroup;
                            mainContext.groupPrev        = null;
                            mainContext.groupNext        = null;
                            mainContext.inExecutionQueue = false;
                            contextGroup.firstContext    = null;
                            contextGroup.lastContext     = null;
                            contextGroup.firstWaiter     = null;
                            contextGroup.lastWaiter      = null;
                            currentContext       = mainContext;
                            firstResumingContext = null;
                            firstReusableContext = null;
                            runningContextCount  = 0;
                            return;
                        }

                        var result = close(remoteSpawnEvent);
                        if (result)
                        {
                        }
                        Debug.Assert(result == 0);
                    }
                }

                var result = close(epoll);
                if (result)
                {
                }
                Debug.Assert(result == 0);
            }

            throw new System.Exception("Dispatcher::Dispatcher, " + message);
        }
コード例 #22
0
        internal static unsafe void Run(int portNumber, bool executeOnEpollThread)
        {
            int socketFileDescriptor = socket(AF_INET, SOCK_STREAM, 0);

            if (socketFileDescriptor < 0)
            {
                Environment.FailFast($"Failed to create socket, socket returned {socketFileDescriptor}");
            }

            sockaddr_in socketAddress = new sockaddr_in
            {
                sin_family = AF_INET,
                sin_port   = htons((ushort)portNumber),
                sin_addr   = INADDR_ANY
            };
            int bindResult = bind(socketFileDescriptor, (sockaddr *)&socketAddress, sizeof(sockaddr_in));

            if (bindResult < 0)
            {
                Environment.FailFast($"Failed to bind, bind returned {bindResult}");
            }

            int listenResult = listen(socketFileDescriptor, BACKLOG);

            if (listenResult < 0)
            {
                Environment.FailFast($"Failed to start listening, listen returned {listenResult}");
            }

            int epollFileDescriptor = epoll_create(MAX_EVENTS);

            if (epollFileDescriptor < 0)
            {
                Environment.FailFast($"Failed to create epoll, epoll_create returned {epollFileDescriptor}");
            }

            epoll_event epollAddSocketEvent = new epoll_event
            {
                events = EPOLLIN,
                data   = new epoll_data_t
                {
                    fd = socketFileDescriptor
                }
            };

            if (epoll_ctl(epollFileDescriptor, EPOLL_CTL_ADD, socketFileDescriptor, &epollAddSocketEvent) == -1)
            {
                Environment.FailFast("Failed to add new socket file descriptor to epoll");
            }

            epoll_event[] epollEvents   = new epoll_event[MAX_EVENTS];
            byte[]        messageBuffer = new byte[MAX_MESSAGE_LENGTH];

            fixed(epoll_event *pinnedEvents = epollEvents)
            fixed(byte *pinnedMessageBuffer = messageBuffer)
            {
                while (true)
                {
                    int eventsCount = epoll_wait(epollFileDescriptor, pinnedEvents, MAX_EVENTS, -1);
                    if (eventsCount == -1)
                    {
                        Environment.FailFast("epoll_wait returned -1");
                    }

                    for (int i = 0; i < eventsCount; i++)
                    {
                        int currentSocketFileDescriptor = epollEvents[i].data.fd;
                        if (currentSocketFileDescriptor == socketFileDescriptor)
                        {
                            sockaddr_in clientAddress;
                            socklen_t   clientAddressSize = sizeof(sockaddr_in);
                            int         acceptResult      = accept4(socketFileDescriptor, (sockaddr *)&clientAddress, &clientAddressSize, SOCK_NONBLOCK);
                            if (acceptResult == -1)
                            {
                                Environment.FailFast($"accept4 returned {acceptResult}");
                            }

                            epollAddSocketEvent.events  = EPOLLIN | EPOLLET;
                            epollAddSocketEvent.data.fd = acceptResult;

                            if (epoll_ctl(epollFileDescriptor, EPOLL_CTL_ADD, acceptResult, &epollAddSocketEvent) == -1)
                            {
                                Environment.FailFast("Failed to add socket to epoll");
                            }
                        }
                        else if (executeOnEpollThread)
                        {
                            ssize_t bytesRead = recv(currentSocketFileDescriptor, pinnedMessageBuffer, MAX_MESSAGE_LENGTH, 0);
                            send(currentSocketFileDescriptor, pinnedMessageBuffer, (size_t)bytesRead, 0);
                        }
                        else
                        {
                            ThreadPool.UnsafeQueueUserWorkItem <int>(Copy, currentSocketFileDescriptor, false);
                        }
                    }
                }
            }
        }
コード例 #23
0
ファイル: Interop.epoll_wait.cs プロジェクト: nnyamhon/corefx
 public static extern unsafe int epoll_wait(int epfd, epoll_event* events, int maxevents, int timeout);
コード例 #24
0
 internal static extern int epoll_ctl(int epfd, PollOperations op, int fd, ref epoll_event events);
コード例 #25
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);
        }