Пример #1
0
        private void disconnect(EpollHandler handler)
        {
            var os = new Overspan(50);

            // detach the handler
            var socketHandle = handler.OnDetach();

            // unsubscribe from Epoll events
            Remove(socketHandle, 0);

            // close the socket
            if (Syscall.close(socketHandle) < 0)
            {
                Log.Error($"Call to close(socked) failed: {Stdlib.GetLastError()}");
            }
            Log.Epoll("[{0}] socked disconnected, closed", socketHandle);

            os.Check("disconnect()");
        }
Пример #2
0
        public void PollOnce(EpollEvent[] events, int timeoutMode = -1)
        {
            if (timeoutMode < 0)
            {
                Log.Epoll("Listener waiting for signals");
            }

            var count = Syscall.epoll_wait(epfd, events, events.Length, timeoutMode);

            if (count < 0)
            {
                Log.Error($"Call to epoll_wait() failed with code {count}: {Stdlib.GetLastError()}");
                return;
            }

            if (count > 0)
            {
                Log.Epoll("+" + count);
            }
            for (var i = 0; i < count; i++)
            {
                var ev = events[i];
                Log.Epoll("Epoll[{0}] got {1} for {2}", i, ev.events, ev.u32);

                // find the handler
                var socket  = (int)ev.u32;
                var handler = server.GetHandler(socket);

                if (((int)ev.events & disconnectMask) > 0)
                {
                    disconnect(handler);
                }
                else
                if (ev.events.HasFlag(EpollEvents.EPOLLIN))
                {
                    if (socket == listenerSocket)
                    {
                        OnReadReady();
                        Update(socket, GetEvents());
                    }
                    else
                    {
                        var os  = new Overspan(50);
                        var ret = handler.OnReadReady();
                        os.Check("OnReadReady()");
                        if (ret < 0)
                        {
                            disconnect(handler);
                        }
                        else
                        {
                            Update(socket, handler.GetEvents());
                        }
                    }
                }
                else
                if (ev.events.HasFlag(EpollEvents.EPOLLOUT))
                {
                    var os  = new Overspan(50);
                    var ret = handler.OnWriteReady();
                    os.Check("OnWriteReady()");
                    if (ret < 0)
                    {
                        disconnect(handler);
                    }
                    else
                    {
                        Update(socket, handler.GetEvents());
                    }
                }
            }
        }
Пример #3
0
        // called either from OnAttach or on EPOLLIN
        public int OnReadReady()
        {
            Log.Epoll("[{0}] OnReadReady()", socketHandle);
            if (state != EState.Reading)
            {
                Log.Error("OnReadReady() in state " + state);
            }
            if (socketHandle < 0)
            {
                Log.Error("Error: OnReadReady on detached socket");
                return(0);
            }

            var read = Syscall.read(socketHandle,
                                    IntPtr.Add(bufferPtr, totalRead),
                                    (ulong)(Buffer.Length - totalRead));

            Log.Epoll("[{0}] read() returned {1}", socketHandle, read);

            if (read < 0)
            {
                var errno = Stdlib.GetLastError();
                if (errno == Errno.EAGAIN || errno == Errno.EWOULDBLOCK || errno == 0)
                {
                    return(0); // continue in the Reading state
                }
                Log.Error("[{0}] read() socket error {1}", socketHandle, errno);
                return(-1); // waiting for the socket to be detached/closed
            }
            if (read == 0)
            {
                Log.Epoll("[{0}] peer closed connection", socketHandle);
                return(-1);
            }

            if (totalRead == 0 && processingStarted.Ticks == 0)
            {
                processingStarted = Stats.Watch.Elapsed;
            }

            totalRead += (int)read;
            if (RequestLength == 0)
            {
                ParseRequestHeader(totalRead);
            }
            if (RequestLength == 0 || RequestLength > 0 && totalRead < RequestLength)
            {
                return((int)read); // continue in the Reading state
            }

            // done!
            //Console.Write('<');
            Log.Epoll("[{0}] Read completed, size={1}", socketHandle, RequestLength);
            if (RequestLength > MaxRequestSize)
            {
                MaxRequestSize = RequestLength;
            }

            // process the request
            setProcessing();
            Log.Epoll("[{0}] Send to processing, query_id={1}", socketHandle, QueryId);

            var os = new Overspan(20);

            server.ProcessContext(this);
            os.Check(ContextType);

            return(0);
        }