diff --git a/src/event/MultiSocketMonitor.cxx b/src/event/MultiSocketMonitor.cxx
index bedb5f74a..d427821d9 100644
--- a/src/event/MultiSocketMonitor.cxx
+++ b/src/event/MultiSocketMonitor.cxx
@@ -28,7 +28,8 @@
 #endif
 
 MultiSocketMonitor::MultiSocketMonitor(EventLoop &_loop)
-	:IdleMonitor(_loop), TimeoutMonitor(_loop) {
+	:IdleMonitor(_loop),
+	 timeout_event(_loop, BIND_THIS_METHOD(OnTimeout)) {
 }
 
 void
@@ -38,7 +39,7 @@ MultiSocketMonitor::Reset()
 
 	fds.clear();
 	IdleMonitor::Cancel();
-	TimeoutMonitor::Cancel();
+	timeout_event.Cancel();
 	ready = refresh = false;
 }
 
@@ -81,9 +82,9 @@ MultiSocketMonitor::Prepare()
 {
 	const auto timeout = PrepareSockets();
 	if (timeout >= timeout.zero())
-		TimeoutMonitor::Schedule(timeout);
+		timeout_event.Schedule(timeout);
 	else
-		TimeoutMonitor::Cancel();
+		timeout_event.Cancel();
 
 }
 
diff --git a/src/event/MultiSocketMonitor.hxx b/src/event/MultiSocketMonitor.hxx
index 0b02b3d48..7f08c1511 100644
--- a/src/event/MultiSocketMonitor.hxx
+++ b/src/event/MultiSocketMonitor.hxx
@@ -22,7 +22,7 @@
 
 #include "check.h"
 #include "IdleMonitor.hxx"
-#include "TimeoutMonitor.hxx"
+#include "TimerEvent.hxx"
 #include "SocketMonitor.hxx"
 #include "Compiler.h"
 
@@ -51,7 +51,7 @@ class EventLoop;
  * In PrepareSockets(), use UpdateSocketList() and AddSocket().
  * DispatchSockets() will be called if at least one socket is ready.
  */
-class MultiSocketMonitor : IdleMonitor, TimeoutMonitor
+class MultiSocketMonitor : IdleMonitor
 {
 	class SingleFD final : public SocketMonitor {
 		MultiSocketMonitor &multi;
@@ -97,6 +97,8 @@ class MultiSocketMonitor : IdleMonitor, TimeoutMonitor
 
 	friend class SingleFD;
 
+	TimerEvent timeout_event;
+
 	/**
 	 * DispatchSockets() should be called.
 	 */
@@ -224,7 +226,7 @@ private:
 
 	void Prepare();
 
-	virtual void OnTimeout() final {
+	void OnTimeout() {
 		SetReady();
 		IdleMonitor::Schedule();
 	}