From a87936080bab26aaf53b3e31d2ff1ca2f740b325 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 31 Jan 2018 20:09:44 -0800 Subject: [PATCH] Limit the max number of registered resources (#95) * Limit the max number of registered resources This allows some token space to be used internally. Also, Mio 0.7 will be limiting the token space some as well. Mio: https://github.com/carllerche/mio/issues/788 Closes #42 --- src/reactor/mod.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/reactor/mod.rs b/src/reactor/mod.rs index 0104c8bc9..798b95152 100644 --- a/src/reactor/mod.rs +++ b/src/reactor/mod.rs @@ -20,7 +20,7 @@ //! [`PollEvented`]: struct.PollEvented.html //! [`TcpStream`]: ../net/struct.TcpStream.html -use std::fmt; +use std::{fmt, usize}; use std::io::{self, ErrorKind}; use std::mem; use std::sync::atomic::Ordering::{Relaxed, SeqCst}; @@ -90,6 +90,9 @@ enum Direction { const TOKEN_WAKEUP: mio::Token = mio::Token(0); const TOKEN_START: usize = 1; +// Kind of arbitrary, but this reserves some token space for later usage. +const MAX_SOURCES: usize = usize::MAX >> 4; + fn _assert_kinds() { fn _assert() {} @@ -280,13 +283,18 @@ impl Inner { fn add_source(&self, source: &Evented) -> io::Result { + let mut io_dispatch = self.io_dispatch.write().unwrap(); + + if io_dispatch.len() == MAX_SOURCES { + return Err(io::Error::new(io::ErrorKind::Other, "reactor at max registered I/O resources")); + } + // Acquire a write lock - let key = self.io_dispatch.write().unwrap() - .insert(ScheduledIo { - readiness: AtomicUsize::new(0), - reader: AtomicTask::new(), - writer: AtomicTask::new(), - }); + let key = io_dispatch.insert(ScheduledIo { + readiness: AtomicUsize::new(0), + reader: AtomicTask::new(), + writer: AtomicTask::new(), + }); try!(self.io.register(source, mio::Token(TOKEN_START + key),