aboutsummaryrefslogtreecommitdiffstats
path: root/src/event/FullyBufferedSocket.cxx
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2013-11-06 20:36:37 +0100
committerMax Kellermann <max@duempel.org>2013-11-06 21:52:24 +0100
commit422b8472fec9443250895a281b6b0a20190daa22 (patch)
treeca6cd030ed408fc891445f0976ab3be7bc46e58b /src/event/FullyBufferedSocket.cxx
parent5b213b0504849b894cf930474fb1bff7cb34cd70 (diff)
downloadmpd-422b8472fec9443250895a281b6b0a20190daa22.tar.gz
mpd-422b8472fec9443250895a281b6b0a20190daa22.tar.xz
mpd-422b8472fec9443250895a281b6b0a20190daa22.zip
event/FullyBufferedSocket: try to write without extra roundtrip
Postpone the write using IdleMonitor instead of scheduling a write event. This reduces the number of system calls, because we don't need to register and unregister the write event in epoll.
Diffstat (limited to 'src/event/FullyBufferedSocket.cxx')
-rw-r--r--src/event/FullyBufferedSocket.cxx38
1 files changed, 24 insertions, 14 deletions
diff --git a/src/event/FullyBufferedSocket.cxx b/src/event/FullyBufferedSocket.cxx
index 6a0df183d..3b8cf3765 100644
--- a/src/event/FullyBufferedSocket.cxx
+++ b/src/event/FullyBufferedSocket.cxx
@@ -42,7 +42,8 @@ FullyBufferedSocket::DirectWrite(const void *data, size_t length)
if (IsSocketErrorAgain(code))
return 0;
- Cancel();
+ IdleMonitor::Cancel();
+ BufferedSocket::Cancel();
if (IsSocketErrorClosed(code))
OnSocketClosed();
@@ -61,6 +62,7 @@ FullyBufferedSocket::Flush()
size_t length;
const void *data = output.Read(&length);
if (data == nullptr) {
+ IdleMonitor::Cancel();
CancelWrite();
return true;
}
@@ -71,8 +73,10 @@ FullyBufferedSocket::Flush()
output.Consume(nbytes);
- if (output.IsEmpty())
+ if (output.IsEmpty()) {
+ IdleMonitor::Cancel();
CancelWrite();
+ }
return true;
}
@@ -82,6 +86,9 @@ FullyBufferedSocket::Write(const void *data, size_t length)
{
assert(IsDefined());
+ if (length == 0)
+ return true;
+
#if 0
/* TODO: disabled because this would add overhead on some callers (the ones that often), but it may be useful */
@@ -98,6 +105,8 @@ FullyBufferedSocket::Write(const void *data, size_t length)
}
#endif
+ const bool was_empty = output.IsEmpty();
+
if (!output.Append(data, length)) {
// TODO
static constexpr Domain buffered_socket_domain("buffered_socket");
@@ -107,30 +116,31 @@ FullyBufferedSocket::Write(const void *data, size_t length)
return false;
}
- ScheduleWrite();
+ if (was_empty)
+ IdleMonitor::Schedule();
return true;
}
bool
FullyBufferedSocket::OnSocketReady(unsigned flags)
{
- const bool was_empty = output.IsEmpty();
- if (!BufferedSocket::OnSocketReady(flags))
- return false;
-
- if (was_empty && !output.IsEmpty())
- /* just in case the OnSocketInput() method has added
- data to the output buffer: try to send it now
- instead of waiting for the next event loop
- iteration */
- flags |= WRITE;
-
if (flags & WRITE) {
assert(!output.IsEmpty());
+ assert(!IdleMonitor::IsActive());
if (!Flush())
return false;
}
+ if (!BufferedSocket::OnSocketReady(flags))
+ return false;
+
return true;
}
+
+void
+FullyBufferedSocket::OnIdle()
+{
+ if (Flush() && !output.IsEmpty())
+ ScheduleWrite();
+}