summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/inspsocket.cpp4
-rw-r--r--src/modules/extra/m_ssl_gnutls.cpp6
-rw-r--r--src/modules/extra/m_ssl_openssl.cpp8
-rw-r--r--src/socketengines/socketengine_epoll.cpp20
-rw-r--r--src/socketengines/socketengine_iocp.cpp4
-rw-r--r--src/socketengines/socketengine_kqueue.cpp12
-rw-r--r--src/socketengines/socketengine_poll.cpp7
-rw-r--r--src/socketengines/socketengine_ports.cpp4
-rw-r--r--src/socketengines/socketengine_select.cpp4
9 files changed, 43 insertions, 26 deletions
diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp
index 6348d7982..004d679ed 100644
--- a/src/inspsocket.cpp
+++ b/src/inspsocket.cpp
@@ -97,7 +97,7 @@ BufferedSocketError BufferedSocket::BeginConnect(const irc::sockets::sockaddrs&
this->state = I_CONNECTING;
- if (!ServerInstance->SE->AddFd(this, FD_WANT_NO_READ | FD_WANT_POLL_WRITE))
+ if (!ServerInstance->SE->AddFd(this, FD_WANT_NO_READ | FD_WANT_SINGLE_WRITE))
return I_ERR_NOMOREFDS;
this->Timeout = new SocketTimeout(this->GetFd(), this, timeout, ServerInstance->Time());
@@ -414,6 +414,8 @@ void BufferedSocket::DoWrite()
this->OnConnected();
if (GetIOHook())
GetIOHook()->OnStreamSocketConnect(this);
+ else
+ ServerInstance->SE->ChangeEventMask(this, FD_WANT_FAST_READ | FD_WANT_EDGE_WRITE);
}
this->StreamSocket::DoWrite();
}
diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp
index c65b8528a..3362e9378 100644
--- a/src/modules/extra/m_ssl_gnutls.cpp
+++ b/src/modules/extra/m_ssl_gnutls.cpp
@@ -540,12 +540,12 @@ class ModuleSSLGnuTLS : public Module
else if (ret > 0)
{
sendq = sendq.substr(ret);
- ServerInstance->SE->ChangeEventMask(user, FD_WANT_POLL_WRITE);
+ ServerInstance->SE->ChangeEventMask(user, FD_WANT_SINGLE_WRITE);
return 0;
}
else if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
{
- ServerInstance->SE->ChangeEventMask(user, FD_WANT_POLL_WRITE);
+ ServerInstance->SE->ChangeEventMask(user, FD_WANT_SINGLE_WRITE);
return 0;
}
else if (ret == 0)
@@ -585,7 +585,7 @@ class ModuleSSLGnuTLS : public Module
{
// gnutls_handshake() wants to write() again.
session->status = ISSL_HANDSHAKING_WRITE;
- ServerInstance->SE->ChangeEventMask(user, FD_WANT_NO_READ | FD_WANT_POLL_WRITE);
+ ServerInstance->SE->ChangeEventMask(user, FD_WANT_NO_READ | FD_WANT_SINGLE_WRITE);
}
}
else
diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp
index e72bdc816..645add4c2 100644
--- a/src/modules/extra/m_ssl_openssl.cpp
+++ b/src/modules/extra/m_ssl_openssl.cpp
@@ -450,7 +450,7 @@ class ModuleSSLOpenSSL : public Module
}
else if (err == SSL_ERROR_WANT_WRITE)
{
- ServerInstance->SE->ChangeEventMask(user, FD_WANT_NO_READ | FD_WANT_POLL_WRITE);
+ ServerInstance->SE->ChangeEventMask(user, FD_WANT_NO_READ | FD_WANT_SINGLE_WRITE);
return 0;
}
else
@@ -501,7 +501,7 @@ class ModuleSSLOpenSSL : public Module
else if (ret > 0)
{
buffer = buffer.substr(ret);
- ServerInstance->SE->ChangeEventMask(user, FD_WANT_POLL_WRITE);
+ ServerInstance->SE->ChangeEventMask(user, FD_WANT_SINGLE_WRITE);
return 0;
}
else if (ret == 0)
@@ -515,7 +515,7 @@ class ModuleSSLOpenSSL : public Module
if (err == SSL_ERROR_WANT_WRITE)
{
- ServerInstance->SE->ChangeEventMask(user, FD_WANT_POLL_WRITE);
+ ServerInstance->SE->ChangeEventMask(user, FD_WANT_SINGLE_WRITE);
return 0;
}
else if (err == SSL_ERROR_WANT_READ)
@@ -554,7 +554,7 @@ class ModuleSSLOpenSSL : public Module
}
else if (err == SSL_ERROR_WANT_WRITE)
{
- ServerInstance->SE->ChangeEventMask(user, FD_WANT_NO_READ | FD_WANT_POLL_WRITE);
+ ServerInstance->SE->ChangeEventMask(user, FD_WANT_NO_READ | FD_WANT_SINGLE_WRITE);
session->status = ISSL_HANDSHAKING;
return true;
}
diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp
index 672ff4a7b..059798d25 100644
--- a/src/socketengines/socketengine_epoll.cpp
+++ b/src/socketengines/socketengine_epoll.cpp
@@ -58,12 +58,12 @@ EPollEngine::~EPollEngine()
static int mask_to_epoll(int event_mask)
{
int rv = 0;
- if (event_mask & (FD_WANT_POLL_READ | FD_WANT_POLL_WRITE))
+ if (event_mask & (FD_WANT_POLL_READ | FD_WANT_POLL_WRITE | FD_WANT_SINGLE_WRITE))
{
// we need to use standard polling on this FD
if (event_mask & (FD_WANT_POLL_READ | FD_WANT_FAST_READ))
rv |= EPOLLIN;
- if (event_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE))
+ if (event_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE))
rv |= EPOLLOUT;
}
else
@@ -182,16 +182,28 @@ int EPollEngine::DispatchEvents()
eh->HandleEvent(EVENT_ERROR, errcode);
continue;
}
+ int mask = eh->GetEventMask();
+ if (events[j].events & EPOLLIN)
+ mask &= ~FD_READ_WILL_BLOCK;
+ if (events[j].events & EPOLLOUT)
+ {
+ mask &= ~FD_WRITE_WILL_BLOCK;
+ if (mask & FD_WANT_SINGLE_WRITE)
+ {
+ int nm = mask & ~FD_WANT_SINGLE_WRITE;
+ OnSetEvent(eh, mask, nm);
+ mask = nm;
+ }
+ }
+ SetEventMask(eh, mask);
if (events[j].events & EPOLLIN)
{
ReadEvents++;
- SetEventMask(eh, eh->GetEventMask() & ~FD_READ_WILL_BLOCK);
eh->HandleEvent(EVENT_READ);
}
if (events[j].events & EPOLLOUT)
{
WriteEvents++;
- SetEventMask(eh, eh->GetEventMask() & ~FD_WRITE_WILL_BLOCK);
eh->HandleEvent(EVENT_WRITE);
}
}
diff --git a/src/socketengines/socketengine_iocp.cpp b/src/socketengines/socketengine_iocp.cpp
index e09fb4d0a..c253bf0a6 100644
--- a/src/socketengines/socketengine_iocp.cpp
+++ b/src/socketengines/socketengine_iocp.cpp
@@ -91,7 +91,7 @@ bool IOCPEngine::AddFd(EventHandler* eh, int event_mask)
ServerInstance->Logs->Log("SOCKET",DEBUG, "New fake fd: %u, real fd: %u, address 0x%p", *fake_fd, eh->GetFd(), eh);
/* post a write event if there is data to be written */
- if (event_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE))
+ if (event_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE))
WantWrite(eh);
/* we're all good =) */
@@ -183,7 +183,7 @@ void IOCPEngine::OnSetEvent(EventHandler* eh, int old_mask, int new_mask)
return;
/* Post event - write begin */
- if((new_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE)) && !eh->GetExt("windows_writeevent", m_writeEvent))
+ if((new_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE)) && !eh->GetExt("windows_writeevent", m_writeEvent))
{
ULONG_PTR completion_key = (ULONG_PTR)*fake_fd;
Overlapped * ov = new Overlapped(SOCKET_IO_EVENT_WRITE_READY, 0);
diff --git a/src/socketengines/socketengine_kqueue.cpp b/src/socketengines/socketengine_kqueue.cpp
index c9734e85d..1a783153e 100644
--- a/src/socketengines/socketengine_kqueue.cpp
+++ b/src/socketengines/socketengine_kqueue.cpp
@@ -76,7 +76,7 @@ bool KQueueEngine::AddFd(EventHandler* eh, int event_mask)
return false;
}
- if (event_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE)) {
+ if (event_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE)) {
// ...and sometimes want to write
WantWrite(eh);
}
@@ -148,7 +148,7 @@ void KQueueEngine::OnSetEvent(EventHandler* eh, int old_mask, int new_mask)
eh->GetFd(), strerror(errno));
}
}
- if ((new_mask & FD_WANT_EDGE_WRITE) && !(old_mask & FD_WANT_EDGE_WRITE))
+ if ((new_mask & (FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE)) && !(old_mask & (FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE)))
{
// new one-shot write
struct kevent ke;
@@ -184,11 +184,11 @@ int KQueueEngine::DispatchEvents()
if (ke_list[j].filter == EVFILT_WRITE)
{
WriteEvents++;
- /* When mask is FD_WANT_FAST_WRITE, we set a one-shot
- * write, so we need to clear that bit to detect when it
- * set again.
+ /* When mask is FD_WANT_FAST_WRITE or FD_WANT_SINGLE_WRITE,
+ * we set a one-shot write, so we need to clear that bit
+ * to detect when it set again.
*/
- const int bits_to_clr = FD_WANT_FAST_WRITE | FD_WRITE_WILL_BLOCK;
+ const int bits_to_clr = FD_WANT_SINGLE_WRITE | FD_WANT_FAST_WRITE | FD_WRITE_WILL_BLOCK;
SetEventMask(eh, eh->GetEventMask() & ~bits_to_clr);
eh->HandleEvent(EVENT_WRITE);
}
diff --git a/src/socketengines/socketengine_poll.cpp b/src/socketengines/socketengine_poll.cpp
index 6f50e2798..a72d21d1f 100644
--- a/src/socketengines/socketengine_poll.cpp
+++ b/src/socketengines/socketengine_poll.cpp
@@ -63,7 +63,7 @@ static int mask_to_poll(int event_mask)
int rv = 0;
if (event_mask & (FD_WANT_POLL_READ | FD_WANT_FAST_READ))
rv |= POLLIN;
- if (event_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE))
+ if (event_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE))
rv |= POLLOUT;
return rv;
}
@@ -208,7 +208,10 @@ int PollEngine::DispatchEvents()
if (events[index].revents & POLLOUT)
{
- SetEventMask(eh, eh->GetEventMask() & ~FD_WRITE_WILL_BLOCK);
+ int mask = eh->GetEventMask();
+ mask &= ~(FD_WRITE_WILL_BLOCK | FD_WANT_SINGLE_WRITE);
+ SetEventMask(eh, mask);
+ events[index].events = mask_to_poll(mask);
eh->HandleEvent(EVENT_WRITE);
}
}
diff --git a/src/socketengines/socketengine_ports.cpp b/src/socketengines/socketengine_ports.cpp
index a99806fc4..d23857f50 100644
--- a/src/socketengines/socketengine_ports.cpp
+++ b/src/socketengines/socketengine_ports.cpp
@@ -60,7 +60,7 @@ static int mask_to_events(int event_mask)
int rv = 0;
if (event_mask & (FD_WANT_POLL_READ | FD_WANT_FAST_READ))
rv |= POLLRDNORM;
- if (event_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE))
+ if (event_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE))
rv |= POLLWRNORM;
return rv;
}
@@ -132,7 +132,7 @@ int PortsEngine::DispatchEvents()
{
int mask = eh->GetEventMask();
if (events[i].portev_events & POLLWRNORM)
- mask &= ~(FD_WRITE_WILL_BLOCK | FD_WANT_FAST_WRITE);
+ mask &= ~(FD_WRITE_WILL_BLOCK | FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE);
if (events[i].portev_events & POLLRDNORM)
mask &= ~FD_READ_WILL_BLOCK;
// reinsert port for next time around, pretending to be one-shot for writes
diff --git a/src/socketengines/socketengine_select.cpp b/src/socketengines/socketengine_select.cpp
index f089fd698..eacfc0fbf 100644
--- a/src/socketengines/socketengine_select.cpp
+++ b/src/socketengines/socketengine_select.cpp
@@ -89,7 +89,7 @@ int SelectEngine::DispatchEvents()
int state = eh->GetEventMask();
if (state & (FD_WANT_POLL_READ | FD_WANT_FAST_READ))
FD_SET (i, &rfdset);
- if (state & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE))
+ if (state & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE))
FD_SET (i, &wfdset);
FD_SET (i, &errfdset);
}
@@ -134,7 +134,7 @@ int SelectEngine::DispatchEvents()
if (FD_ISSET (i, &wfdset))
{
WriteEvents++;
- SetEventMask(eh, eh->GetEventMask() & ~FD_WRITE_WILL_BLOCK);
+ SetEventMask(eh, eh->GetEventMask() & ~(FD_WRITE_WILL_BLOCK | FD_WANT_SINGLE_WRITE));
ev->HandleEvent(EVENT_WRITE);
}
}