From ab4dee91de96555db158db91240ff91520318068 Mon Sep 17 00:00:00 2001 From: brain Date: Thu, 14 Feb 2008 16:49:22 +0000 Subject: Keep count of the number of events in total, and seperate read, write and error event counters. We can use this for monitoring of heavy socket engine activity, e.g. a 'stuck' eventhandler git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@8933 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/socketengine.h | 6 ++++++ src/socketengine.cpp | 1 + src/socketengines/socketengine_epoll.cpp | 6 ++++++ src/socketengines/socketengine_iocp.cpp | 6 ++++++ src/socketengines/socketengine_kqueue.cpp | 7 +++++++ src/socketengines/socketengine_ports.cpp | 6 ++++++ src/socketengines/socketengine_select.cpp | 30 +++++++++++++++++++----------- 7 files changed, 51 insertions(+), 11 deletions(-) diff --git a/include/socketengine.h b/include/socketengine.h index 6f5d4131b..3acc7bd4f 100644 --- a/include/socketengine.h +++ b/include/socketengine.h @@ -69,6 +69,7 @@ class CoreExport EventHandler : public Extensible */ int fd; public: + /** Get the current file descriptor * @return The file descriptor of this handler */ @@ -169,6 +170,11 @@ protected: EventHandler* ref[MAX_DESCRIPTORS]; public: + double TotalEvents; + double ReadEvents; + double WriteEvents; + double ErrorEvents; + /** Constructor. * The constructor transparently initializes * the socket engine which the ircd is using. diff --git a/src/socketengine.cpp b/src/socketengine.cpp index 2e541141d..a4b6d7d29 100644 --- a/src/socketengine.cpp +++ b/src/socketengine.cpp @@ -62,6 +62,7 @@ void SocketEngine::WantWrite(EventHandler* eh) SocketEngine::SocketEngine(InspIRCd* Instance) : ServerInstance(Instance) { memset(ref, 0, sizeof(ref)); + TotalEvents = WriteEvents = ReadEvents = ErrorEvents = 0; } SocketEngine::~SocketEngine() diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp index 34fabdf15..ccfa0f769 100644 --- a/src/socketengines/socketengine_epoll.cpp +++ b/src/socketengines/socketengine_epoll.cpp @@ -121,16 +121,20 @@ int EPollEngine::DispatchEvents() int errcode; int i = epoll_wait(EngineHandle, events, MAX_DESCRIPTORS, 1000); + TotalEvents += i; + for (int j = 0; j < i; j++) { if (events[j].events & EPOLLHUP) { + ErrorEvents++; if (ref[events[j].data.fd]) ref[events[j].data.fd]->HandleEvent(EVENT_ERROR, 0); continue; } if (events[j].events & EPOLLERR) { + ErrorEvents++; /* Get error number */ if (getsockopt(events[j].data.fd, SOL_SOCKET, SO_ERROR, &errcode, &codesize) < 0) errcode = errno; @@ -140,6 +144,7 @@ int EPollEngine::DispatchEvents() } if (events[j].events & EPOLLOUT) { + WriteEvents++; struct epoll_event ev; memset(&ev,0,sizeof(struct epoll_event)); ev.events = EPOLLIN; @@ -150,6 +155,7 @@ int EPollEngine::DispatchEvents() } else { + ReadEvents++; if (ref[events[j].data.fd]) ref[events[j].data.fd]->HandleEvent(EVENT_READ); } diff --git a/src/socketengines/socketengine_iocp.cpp b/src/socketengines/socketengine_iocp.cpp index 4008c9d27..9b7dd63c7 100644 --- a/src/socketengines/socketengine_iocp.cpp +++ b/src/socketengines/socketengine_iocp.cpp @@ -302,10 +302,13 @@ int IOCPEngine::DispatchEvents() eh->GetExt("windows_readevent", m_readEvent); eh->GetExt("windows_writeevent", m_writeEvent); + TotalEvents++; + switch(ov->m_event) { case SOCKET_IO_EVENT_WRITE_READY: { + WriteEvents++; eh->Shrink("windows_writeevent"); eh->HandleEvent(EVENT_WRITE, 0); } @@ -313,6 +316,7 @@ int IOCPEngine::DispatchEvents() case SOCKET_IO_EVENT_READ_READY: { + ReadEvents++; if(ov->m_params) { // if we had params, it means we are a udp socket with a udp_overlap pointer in this long. @@ -346,6 +350,7 @@ int IOCPEngine::DispatchEvents() case SOCKET_IO_EVENT_ACCEPT: { /* this is kinda messy.. :/ */ + ReadEvents++; eh->HandleEvent(EVENT_READ, ov->m_params); delete ((accept_overlap*)ov->m_params); eh->Shrink("windows_acceptevent"); @@ -355,6 +360,7 @@ int IOCPEngine::DispatchEvents() case SOCKET_IO_EVENT_ERROR: { + ErrorEvents++; eh->HandleEvent(EVENT_ERROR, ov->m_params); } break; diff --git a/src/socketengines/socketengine_kqueue.cpp b/src/socketengines/socketengine_kqueue.cpp index 513677e44..a2bbd5afe 100644 --- a/src/socketengines/socketengine_kqueue.cpp +++ b/src/socketengines/socketengine_kqueue.cpp @@ -128,7 +128,11 @@ int KQueueEngine::DispatchEvents() { ts.tv_nsec = 0; ts.tv_sec = 1; + int i = kevent(EngineHandle, NULL, 0, &ke_list[0], MAX_DESCRIPTORS, &ts); + + TotalEvents += i; + for (int j = 0; j < i; j++) { if (ke_list[j].flags & EV_EOF) @@ -138,6 +142,7 @@ int KQueueEngine::DispatchEvents() * Unlike smelly epoll and select, where we have to getsockopt * to get the error, this saves us time and cpu cycles. Go BSD! */ + ErrorEvents++; if (ref[ke_list[j].ident]) ref[ke_list[j].ident]->HandleEvent(EVENT_ERROR, ke_list[j].fflags); continue; @@ -150,11 +155,13 @@ int KQueueEngine::DispatchEvents() struct kevent ke; EV_SET(&ke, ke_list[j].ident, EVFILT_READ, EV_ADD, 0, 0, NULL); kevent(EngineHandle, &ke, 1, 0, 0, NULL); + WriteEvents++; if (ref[ke_list[j].ident]) ref[ke_list[j].ident]->HandleEvent(EVENT_WRITE); } else { + ReadEvents++; if (ref[ke_list[j].ident]) ref[ke_list[j].ident]->HandleEvent(EVENT_READ); } diff --git a/src/socketengines/socketengine_ports.cpp b/src/socketengines/socketengine_ports.cpp index 8e866b311..0d97b91df 100644 --- a/src/socketengines/socketengine_ports.cpp +++ b/src/socketengines/socketengine_ports.cpp @@ -100,6 +100,8 @@ int PortsEngine::DispatchEvents() if (i == -1) return i; + TotalEvents += nget; + for (i = 0; i < nget; i++) { switch (this->events[i].portev_source) @@ -111,6 +113,10 @@ int PortsEngine::DispatchEvents() { // reinsert port for next time around port_associate(EngineHandle, PORT_SOURCE_FD, fd, POLLRDNORM, ref[fd]); + if ((this->events[i].portev_events & POLLRDNORM)) + ReadEvents++; + else + WriteEvents++; ref[fd]->HandleEvent((this->events[i].portev_events & POLLRDNORM) ? EVENT_READ : EVENT_WRITE); } } diff --git a/src/socketengines/socketengine_select.cpp b/src/socketengines/socketengine_select.cpp index b7427612e..cc7232b99 100644 --- a/src/socketengines/socketengine_select.cpp +++ b/src/socketengines/socketengine_select.cpp @@ -132,27 +132,35 @@ int SelectEngine::DispatchEvents() { if (FD_ISSET (ev[i]->GetFd(), &errfdset)) { - if (ev[i]) - { - if (getsockopt(ev[i]->GetFd(), SOL_SOCKET, SO_ERROR, (char*)&errcode, &codesize) < 0) - errcode = errno; + ErrorEvents++; + + if (getsockopt(ev[i]->GetFd(), SOL_SOCKET, SO_ERROR, (char*)&errcode, &codesize) < 0) + errcode = errno; + + ev[i]->HandleEvent(EVENT_ERROR, errcode); - ev[i]->HandleEvent(EVENT_ERROR, errcode); - } continue; } - if (ev[i]) + else { if (writeable[ev[i]->GetFd()]) { + WriteEvents++; writeable[ev[i]->GetFd()] = false; - if (ev[i]) - ev[i]->HandleEvent(EVENT_WRITE); + ev[i]->HandleEvent(EVENT_WRITE); } else { - if (ev[i]) - ev[i]->HandleEvent(ev[i]->Readable() ? EVENT_READ : EVENT_WRITE); + if (ev[i]->Readable()) + { + ReadEvents++; + ev[i]->HandleEvent(EVENT_READ); + } + else + { + WriteEvents++; + ev[i]->HandleEvent(EVENT_WRITE); + } } } } -- cgit v1.2.3