diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/examples/http_bench.rs | 29 | ||||
-rw-r--r-- | core/resources.rs | 58 |
2 files changed, 53 insertions, 34 deletions
diff --git a/core/examples/http_bench.rs b/core/examples/http_bench.rs index a6cc6d548..764e04303 100644 --- a/core/examples/http_bench.rs +++ b/core/examples/http_bench.rs @@ -15,6 +15,8 @@ extern crate lazy_static; use deno::*; use futures::future::lazy; use std::env; +use std::io::Error; +use std::io::ErrorKind; use std::net::SocketAddr; use std::sync::Mutex; use std::sync::MutexGuard; @@ -182,13 +184,25 @@ fn main() { } } +pub fn bad_resource() -> Error { + Error::new(ErrorKind::NotFound, "bad resource id") +} + struct TcpListener(tokio::net::TcpListener); -impl Resource for TcpListener {} +impl Resource for TcpListener { + fn inspect_repr(&self) -> &str { + "tcpListener" + } +} struct TcpStream(tokio::net::TcpStream); -impl Resource for TcpStream {} +impl Resource for TcpStream { + fn inspect_repr(&self) -> &str { + "tcpStream" + } +} lazy_static! { static ref RESOURCE_TABLE: Mutex<ResourceTable> = @@ -204,7 +218,8 @@ fn op_accept(record: Record, _zero_copy_buf: Option<PinnedBuf>) -> Box<HttpOp> { debug!("accept {}", rid); let fut = futures::future::poll_fn(move || { let mut table = lock_resource_table(); - let listener = table.get_mut::<TcpListener>(rid)?; + let listener = + table.get_mut::<TcpListener>(rid).ok_or_else(bad_resource)?; listener.0.poll_accept() }) .and_then(move |(stream, addr)| { @@ -233,8 +248,8 @@ fn op_close(record: Record, _zero_copy_buf: Option<PinnedBuf>) -> Box<HttpOp> { let rid = record.arg as u32; let mut table = lock_resource_table(); let fut = match table.close(rid) { - Ok(_) => futures::future::ok(0), - Err(e) => futures::future::err(e), + Some(_) => futures::future::ok(0), + None => futures::future::err(bad_resource()), }; Box::new(fut) } @@ -245,7 +260,7 @@ fn op_read(record: Record, zero_copy_buf: Option<PinnedBuf>) -> Box<HttpOp> { let mut zero_copy_buf = zero_copy_buf.unwrap(); let fut = futures::future::poll_fn(move || { let mut table = lock_resource_table(); - let stream = table.get_mut::<TcpStream>(rid)?; + let stream = table.get_mut::<TcpStream>(rid).ok_or_else(bad_resource)?; stream.0.poll_read(&mut zero_copy_buf) }) .and_then(move |nread| { @@ -261,7 +276,7 @@ fn op_write(record: Record, zero_copy_buf: Option<PinnedBuf>) -> Box<HttpOp> { let zero_copy_buf = zero_copy_buf.unwrap(); let fut = futures::future::poll_fn(move || { let mut table = lock_resource_table(); - let stream = table.get_mut::<TcpStream>(rid)?; + let stream = table.get_mut::<TcpStream>(rid).ok_or_else(bad_resource)?; stream.0.poll_write(&zero_copy_buf) }) .and_then(move |nwritten| { diff --git a/core/resources.rs b/core/resources.rs index c3d8b7107..368f83454 100644 --- a/core/resources.rs +++ b/core/resources.rs @@ -10,8 +10,6 @@ use downcast_rs::Downcast; use std; use std::any::Any; use std::collections::HashMap; -use std::io::Error; -use std::io::ErrorKind; /// ResourceId is Deno's version of a file descriptor. ResourceId is also referred /// to as rid in the code base. @@ -23,24 +21,27 @@ type ResourceMap = HashMap<ResourceId, Box<dyn Resource>>; #[derive(Default)] pub struct ResourceTable { - map: ResourceMap, + // TODO(bartlomieju): remove pub modifier, it is used by + // `get_file` method in CLI + pub map: ResourceMap, next_id: u32, } impl ResourceTable { - pub fn get<T: Resource>(&self, rid: ResourceId) -> Result<&T, Error> { - let resource = self.map.get(&rid).ok_or_else(bad_resource)?; - let resource = &resource.downcast_ref::<T>().ok_or_else(bad_resource)?; - Ok(resource) + pub fn get<T: Resource>(&self, rid: ResourceId) -> Option<&T> { + if let Some(resource) = self.map.get(&rid) { + return resource.downcast_ref::<T>(); + } + + None } - pub fn get_mut<T: Resource>( - &mut self, - rid: ResourceId, - ) -> Result<&mut T, Error> { - let resource = self.map.get_mut(&rid).ok_or_else(bad_resource)?; - let resource = resource.downcast_mut::<T>().ok_or_else(bad_resource)?; - Ok(resource) + pub fn get_mut<T: Resource>(&mut self, rid: ResourceId) -> Option<&mut T> { + if let Some(resource) = self.map.get_mut(&rid) { + return resource.downcast_mut::<T>(); + } + + None } // TODO: resource id allocation should probably be randomized for security. @@ -57,13 +58,23 @@ impl ResourceTable { rid } + pub fn entries(&self) -> Vec<(ResourceId, String)> { + self + .map + .iter() + .map(|(key, value)| (*key, value.inspect_repr().to_string())) + .collect() + } + // close(2) is done by dropping the value. Therefore we just need to remove // the resource from the RESOURCE_TABLE. - pub fn close(&mut self, rid: ResourceId) -> Result<(), Error> { - let repr = self.map.remove(&rid).ok_or_else(bad_resource)?; - // Give resource a chance to cleanup (notify tasks, etc.) - repr.close(); - Ok(()) + pub fn close(&mut self, rid: ResourceId) -> Option<()> { + if let Some(resource) = self.map.remove(&rid) { + resource.close(); + return Some(()); + } + + None } } @@ -72,13 +83,6 @@ pub trait Resource: Downcast + Any + Send { /// Method that allows to cleanup resource. fn close(&self) {} - fn inspect_repr(&self) -> &str { - unimplemented!(); - } + fn inspect_repr(&self) -> &str; } impl_downcast!(Resource); - -// TODO: probably bad error kind -pub fn bad_resource() -> Error { - Error::new(ErrorKind::NotFound, "bad resource id") -} |