summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2006-10-31 20:32:01 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2006-10-31 20:32:01 +0000
commit193b540aa750446bf67dcad132773541214c296d (patch)
tree08102297f03b3a1d7e064ec5c3077774106437de
parent4bb033449de57d7d2ac873bc70631b43ab7ce3d9 (diff)
Socket error state stuff
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@5607 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--include/dns.h2
-rw-r--r--include/inspircd.h2
-rw-r--r--include/inspsocket.h2
-rw-r--r--include/socket.h2
-rw-r--r--include/socketengine.h8
-rw-r--r--include/users.h2
-rw-r--r--src/dns.cpp2
-rw-r--r--src/inspircd.cpp2
-rw-r--r--src/inspsocket.cpp4
-rw-r--r--src/socket.cpp2
-rw-r--r--src/socketengine_epoll.cpp21
-rw-r--r--src/socketengine_select.cpp23
-rw-r--r--src/users.cpp2
13 files changed, 51 insertions, 23 deletions
diff --git a/include/dns.h b/include/dns.h
index b011a9ddb..79b286233 100644
--- a/include/dns.h
+++ b/include/dns.h
@@ -330,7 +330,7 @@ class DNS : public EventHandler
* Handle a SocketEngine read event
* Inherited from EventHandler
*/
- void HandleEvent(EventType et);
+ void HandleEvent(EventType et, int errornum = 0);
/**
* Add a Resolver* to the list of active classes
diff --git a/include/inspircd.h b/include/inspircd.h
index 3a752e21c..014f729b0 100644
--- a/include/inspircd.h
+++ b/include/inspircd.h
@@ -172,7 +172,7 @@ class FileLogger : public EventHandler
* another write event is scheduled to write
* the rest of the data when possible.
*/
- virtual void HandleEvent(EventType et);
+ virtual void HandleEvent(EventType et, int errornum = 0);
/** Write one or more preformatted log lines.
* If the data cannot be written immediately,
* this class will insert itself into the
diff --git a/include/inspsocket.h b/include/inspsocket.h
index af92615ea..71f16951e 100644
--- a/include/inspsocket.h
+++ b/include/inspsocket.h
@@ -365,7 +365,7 @@ class InspSocket : public EventHandler
*/
void MarkAsClosed();
- void HandleEvent(EventType et);
+ void HandleEvent(EventType et, int errornum = 0);
bool Readable();
};
diff --git a/include/socket.h b/include/socket.h
index f868daf92..6264b196f 100644
--- a/include/socket.h
+++ b/include/socket.h
@@ -154,7 +154,7 @@ class ListenSocket : public EventHandler
ListenSocket(InspIRCd* Instance, int sockfd, irc::sockets::insp_sockaddr client, irc::sockets::insp_sockaddr server, int port, char* addr);
/** Handle an I/O event
*/
- void HandleEvent(EventType et);
+ void HandleEvent(EventType et, int errornum = 0);
};
#endif
diff --git a/include/socketengine.h b/include/socketengine.h
index a4628b648..9b3cdec64 100644
--- a/include/socketengine.h
+++ b/include/socketengine.h
@@ -26,11 +26,15 @@
/** Types of event an EventHandler may receive.
* EVENT_READ is a readable file descriptor,
* and EVENT_WRITE is a writeable file descriptor.
+ * EVENT_ERROR can always occur, and indicates
+ * a write error or read error on the socket,
+ * e.g. EOF condition or broken pipe.
*/
enum EventType
{
EVENT_READ = 0,
- EVENT_WRITE = 1
+ EVENT_WRITE = 1,
+ EVENT_ERROR = 2
};
class InspIRCd;
@@ -127,7 +131,7 @@ class EventHandler : public Extensible
* @param et either one of EVENT_READ for read events,
* and EVENT_WRITE for write events.
*/
- virtual void HandleEvent(EventType et) = 0;
+ virtual void HandleEvent(EventType et, int errornum = 0) = 0;
};
/** Provides basic file-descriptor-based I/O support.
diff --git a/include/users.h b/include/users.h
index 1dc0aa43e..536f37a80 100644
--- a/include/users.h
+++ b/include/users.h
@@ -767,7 +767,7 @@ class userrec : public connection
/** Handle socket event.
* From EventHandler class.
*/
- void HandleEvent(EventType et);
+ void HandleEvent(EventType et, int errornum = 0);
/** Default destructor
*/
diff --git a/src/dns.cpp b/src/dns.cpp
index fb38a23b9..4248affae 100644
--- a/src/dns.cpp
+++ b/src/dns.cpp
@@ -944,7 +944,7 @@ int Resolver::GetId()
}
/** Process a socket read event */
-void DNS::HandleEvent(EventType et)
+void DNS::HandleEvent(EventType et, int errornum)
{
ServerInstance->Log(DEBUG,"Marshall reads: %d",this->GetFd());
/* Fetch the id and result of the next available packet */
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 53f3bb733..fe8b0b819 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -786,7 +786,7 @@ bool FileLogger::Readable()
return false;
}
-void FileLogger::HandleEvent(EventType et)
+void FileLogger::HandleEvent(EventType et, int errornum)
{
this->WriteLogLine("");
ServerInstance->SE->DelFd(this);
diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp
index 9b691fc7f..f8d5109fb 100644
--- a/src/inspsocket.cpp
+++ b/src/inspsocket.cpp
@@ -475,10 +475,12 @@ InspSocket::~InspSocket()
this->Close();
}
-void InspSocket::HandleEvent(EventType et)
+void InspSocket::HandleEvent(EventType et, int errornum)
{
switch (et)
{
+ case EVENT_ERROR:
+ break;
case EVENT_READ:
if (!this->Poll())
{
diff --git a/src/socket.cpp b/src/socket.cpp
index 4bf9dc30b..225b27733 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -51,7 +51,7 @@ ListenSocket::ListenSocket(InspIRCd* Instance, int sockfd, insp_sockaddr client,
}
}
-void ListenSocket::HandleEvent(EventType et)
+void ListenSocket::HandleEvent(EventType et, int errornum)
{
insp_sockaddr sock_us; // our port number
socklen_t uslen; // length of our port number
diff --git a/src/socketengine_epoll.cpp b/src/socketengine_epoll.cpp
index c3c0c89a2..618f30592 100644
--- a/src/socketengine_epoll.cpp
+++ b/src/socketengine_epoll.cpp
@@ -130,10 +130,25 @@ int EPollEngine::GetRemainingFds()
int EPollEngine::DispatchEvents()
{
+ socklen_t codesize;
+ int errcode;
int i = epoll_wait(EngineHandle, events, MAX_DESCRIPTORS, 150);
for (int j = 0; j < i; j++)
{
ServerInstance->Log(DEBUG,"Handle %s event on fd %d",events[j].events & EPOLLOUT ? "write" : "read", events[j].data.fd);
+ if (events[j].events & EPOLLHUP)
+ {
+ ref[events[j].data.fd]->HandleEvent(EVENT_ERROR, 0);
+ continue;
+ }
+ if (events[j].events & EPOLLERR)
+ {
+ /* Get error number */
+ if (getsockopt(events[j].data.fd, SOL_SOCKET, SO_ERROR, &errcode, &codesize) < 0)
+ errcode = errno;
+ ref[events[j].data.fd]->HandleEvent(EVENT_ERROR, errcode);
+ continue;
+ }
if (events[j].events & EPOLLOUT)
{
struct epoll_event ev;
@@ -144,11 +159,13 @@ int EPollEngine::DispatchEvents()
{
ServerInstance->Log(DEBUG,"epoll: Could not reset fd %d!", events[j].data.fd);
}
- ref[events[j].data.fd]->HandleEvent(EVENT_WRITE);
+ if (ref[events[j].data.fd])
+ ref[events[j].data.fd]->HandleEvent(EVENT_WRITE);
}
else
{
- ref[events[j].data.fd]->HandleEvent(EVENT_READ);
+ if (ref[events[j].data.fd])
+ ref[events[j].data.fd]->HandleEvent(EVENT_READ);
}
}
diff --git a/src/socketengine_select.cpp b/src/socketengine_select.cpp
index 8b0379152..cdd1bdc3c 100644
--- a/src/socketengine_select.cpp
+++ b/src/socketengine_select.cpp
@@ -134,16 +134,21 @@ int SelectEngine::DispatchEvents()
*/
for (int i = 0; i < result; i++)
{
- ServerInstance->Log(DEBUG,"Handle %s event on fd %d",writeable[ev[i]->GetFd()] || !ev[i]->Readable() ? "write" : "read", ev[i]->GetFd());
- if (writeable[ev[i]->GetFd()])
+ if (ev[i])
{
- ev[i]->HandleEvent(EVENT_WRITE);
- writeable[ev[i]->GetFd()] = false;
-
- }
- else
- {
- ev[i]->HandleEvent(ev[i]->Readable() ? EVENT_READ : EVENT_WRITE);
+ ServerInstance->Log(DEBUG,"Handle %s event on fd %d",writeable[ev[i]->GetFd()] || !ev[i]->Readable() ? "write" : "read", ev[i]->GetFd());
+ if (writeable[ev[i]->GetFd()])
+ {
+ if (ev[i])
+ ev[i]->HandleEvent(EVENT_WRITE);
+ writeable[ev[i]->GetFd()] = false;
+
+ }
+ else
+ {
+ if (ev[i])
+ ev[i]->HandleEvent(ev[i]->Readable() ? EVENT_READ : EVENT_WRITE);
+ }
}
}
diff --git a/src/users.cpp b/src/users.cpp
index 2c49e1ec7..6acbf137a 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -2026,7 +2026,7 @@ void userrec::ShowRULES()
this->WriteServ("NOTICE %s :End of %s rules.",this->nick,ServerInstance->Config->ServerName);
}
-void userrec::HandleEvent(EventType et)
+void userrec::HandleEvent(EventType et, int errornum)
{
/* WARNING: May delete this user! */
try