From 13153694df045d24217658077c7d223d269504b5 Mon Sep 17 00:00:00 2001 From: brain Date: Fri, 7 Jul 2006 00:18:14 +0000 Subject: Added InspSocket::WantWrite(), InspSocket::OnWriteReady() and private data methods to make it work. See the XXX'ed section for a bit of minor craq git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@4120 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/inspsocket.h | 15 +++++++++++++++ src/inspsocket.cpp | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/include/inspsocket.h b/include/inspsocket.h index 6994e1647..9858f0432 100644 --- a/include/inspsocket.h +++ b/include/inspsocket.h @@ -156,6 +156,12 @@ protected: */ bool ClosePending; + /** Set to true when we're waiting for a write event. + * If this is true and a write event comes in, we + * call the write instead of the read method. + */ + bool WaitingForWriteEvent; + bool BindAddr(); public: @@ -224,6 +230,8 @@ public: */ virtual bool OnDataReady(); + virtual bool OnWriteReady(); + /** * When an outbound connection fails, and the * attempt times out, you will receive this event. @@ -298,6 +306,13 @@ public: */ void SetState(InspSocketState s); + /** + * Call this to receive the next write event + * that comes along for this fd to the OnWriteReady + * method. + */ + void WantWrite(); + /** * Returns the current socket state. */ diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp index 3de8e92b6..4264700f5 100644 --- a/src/inspsocket.cpp +++ b/src/inspsocket.cpp @@ -120,6 +120,23 @@ InspSocket::InspSocket(const std::string &ahost, int aport, bool listening, unsi } } +void InspSocket::WantWrite() +{ + /** XXX: + * The socket engine may only have each FD in the list ONCE. + * This means we cant watch for write AND read at the same + * time. We have to remove the READ fd, to insert the WRITE + * fd. Once we receive our WRITE event (which WILL ARRIVE, + * pretty much gauranteed) we switch back to watching for + * READ events again. + * + * This behaviour may be fixed in a later version. + */ + this->WaitingForWriteEvent = true; + ServerInstance->SE->DelFd(this->fd); + ServerInstance->SE->AddFd(this->fd,false,X_ESTAB_MODULE); +} + void InspSocket::SetQueues(int nfd) { // attempt to increase socket sendq and recvq as high as its possible @@ -446,7 +463,20 @@ bool InspSocket::Poll() return true; break; case I_CONNECTED: - n = this->OnDataReady(); + + if (this->WaitingForWriteEvent) + { + /* Switch back to read events */ + ServerInstance->SE->DelFd(this->fd); + ServerInstance->SE->AddFd(this->fd,true,X_ESTAB_MODULE); + /* Trigger the write event */ + n = this->OnWriteReady(); + } + else + { + /* Process the read event */ + n = this->OnDataReady(); + } /* Flush any pending, but not till after theyre done with the event * so there are less write calls involved. * Both FlushWriteBuffer AND the return result of OnDataReady must @@ -483,6 +513,7 @@ void InspSocket::OnError(InspSocketError e) { return; } int InspSocket::OnDisconnect() { return 0; } int InspSocket::OnIncomingConnection(int newfd, char* ip) { return 0; } bool InspSocket::OnDataReady() { return true; } +bool InspSocket::OnWriteReady() { return true; } void InspSocket::OnTimeout() { return; } void InspSocket::OnClose() { return; } -- cgit v1.2.3