Bug 1410107 - Grow audioipc server slabs as required. r=kinetik
authorDan Glastonbury <dan.glastonbury@gmail.com>
Wed, 25 Oct 2017 09:14:45 +1000
changeset 388053 aaa39a5309985d35debb0aaeaa3316dc074aa608
parent 388052 3170d21cbd25d32466502d12119f6d9824c84bbf
child 388054 1345767fb2d502a9ab705ca73ccecbc7f5209c99
push id32739
push useracraciun@mozilla.com
push dateWed, 25 Oct 2017 09:29:21 +0000
treeherdermozilla-central@252a8528c5ab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs1410107
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1410107 - Grow audioipc server slabs as required. r=kinetik MozReview-Commit-ID: zFfex3LX7K
media/audioipc/server/src/lib.rs
--- a/media/audioipc/server/src/lib.rs
+++ b/media/audioipc/server/src/lib.rs
@@ -48,16 +48,22 @@ pub mod errors {
     }
 }
 
 use errors::*;
 
 // TODO: Remove and let caller allocate based on cubeb backend requirements.
 const SHM_AREA_SIZE: usize = 2 * 1024 * 1024;
 
+// The size in which the server conns slab is grown.
+const SERVER_CONN_CHUNK_SIZE: usize = 16;
+
+// The size in which the stream slab is grown.
+const STREAM_CONN_CHUNK_SIZE: usize = 64;
+
 // TODO: this should forward to the client.
 struct Callback {
     /// Size of input frame in bytes
     input_frame_size: u16,
     /// Size of output frame in bytes
     output_frame_size: u16,
     connection: audioipc::Connection,
     input_shm: SharedMemWriter,
@@ -158,17 +164,17 @@ struct ServerConn {
 }
 
 impl ServerConn {
     fn new(io: UnixStream) -> ServerConn {
         let mut sc = ServerConn {
             io: io,
             token: None,
             // TODO: Handle increasing slab size. Pick a good default size.
-            streams: StreamSlab::with_capacity(64),
+            streams: StreamSlab::with_capacity(STREAM_CONN_CHUNK_SIZE),
             decoder: Decoder::new(),
             recv_buffer: BytesMut::with_capacity(4096),
             send_buffer: BytesMut::with_capacity(4096),
             pending_send: VecDeque::new(),
             device_ids: HashSet::new()
         };
         sc.device_ids.insert(0); // nullptr is always a valid (default) device id.
         sc
@@ -430,16 +436,24 @@ impl ServerConn {
                 input_frame_size: input_frame_size,
                 output_frame_size: output_frame_size,
                 connection: conn2,
                 input_shm: input_shm,
                 output_shm: output_shm
             }
         ) {
             Ok(stream) => {
+                if !self.streams.has_available() {
+                    trace!(
+                        "server connection ran out of stream slots. reserving {} more.",
+                        STREAM_CONN_CHUNK_SIZE
+                    );
+                    self.streams.reserve_exact(STREAM_CONN_CHUNK_SIZE);
+                }
+
                 let stm_tok = match self.streams.vacant_entry() {
                     Some(entry) => {
                         debug!(
                             "Registering stream {:?}",
                             entry.index(),
                         );
 
                         entry.insert(stream).index()
@@ -577,31 +591,40 @@ pub struct Server {
     conns: Slab<ServerConn>
 }
 
 impl Server {
     pub fn new(socket: UnixListener) -> Server {
         Server {
             socket: socket,
             context: None,
-            conns: Slab::with_capacity(16)
+            conns: Slab::with_capacity(SERVER_CONN_CHUNK_SIZE)
         }
     }
 
     fn accept(&mut self, poll: &mut mio::Poll) -> Result<()> {
         debug!("Server accepting connection");
 
         let client_socket = match self.socket.accept() {
             Err(e) => {
                 error!("server accept error: {}", e);
                 return Err(e.into());
             },
             Ok(None) => panic!("accept returned EAGAIN unexpectedly"),
             Ok(Some((socket, _))) => socket,
         };
+
+        if !self.conns.has_available() {
+            trace!(
+                "server ran out of connection slots. reserving {} more.",
+                SERVER_CONN_CHUNK_SIZE
+            );
+            self.conns.reserve_exact(SERVER_CONN_CHUNK_SIZE);
+        }
+
         let token = match self.conns.vacant_entry() {
             Some(entry) => {
                 debug!("registering {:?}", entry.index());
                 let cxn = ServerConn::new(client_socket);
                 entry.insert(cxn).index()
             },
             None => {
                 panic!("failed to insert connection");