1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-22 15:06:54 -05:00

Remove CoreResource::inspect_repr method (#3274)

Towards simplifying (or better removing entirely) the CoreResource
trait. Resources should be any bit of privileged heap allocated memory
that needs to be referenced from JS, not very specific trait
implementations. Therefore CoreResource should be pushed towards being
as general as possible.
This commit is contained in:
Ry Dahl 2019-11-06 12:17:28 -05:00 committed by GitHub
parent 92b8674162
commit 5c1deac0cf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 52 additions and 70 deletions

View file

@ -24,11 +24,7 @@ pub fn init(i: &mut Isolate, s: &ThreadSafeState) {
struct ReplResource(Arc<Mutex<Repl>>); struct ReplResource(Arc<Mutex<Repl>>);
impl CoreResource for ReplResource { impl CoreResource for ReplResource {}
fn inspect_repr(&self) -> &str {
"repl"
}
}
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
@ -49,7 +45,7 @@ fn op_repl_start(
let repl = repl::Repl::new(history_path); let repl = repl::Repl::new(history_path);
let resource = ReplResource(Arc::new(Mutex::new(repl))); let resource = ReplResource(Arc::new(Mutex::new(repl)));
let mut table = resources::lock_resource_table(); let mut table = resources::lock_resource_table();
let rid = table.add(Box::new(resource)); let rid = table.add("repl", Box::new(resource));
Ok(JsonOp::Sync(json!(rid))) Ok(JsonOp::Sync(json!(rid)))
} }

View file

@ -49,9 +49,9 @@ lazy_static! {
let mut table = ResourceTable::default(); let mut table = ResourceTable::default();
// TODO Load these lazily during lookup? // TODO Load these lazily during lookup?
table.add(Box::new(CliResource::Stdin(tokio::io::stdin()))); table.add("stdin", Box::new(CliResource::Stdin(tokio::io::stdin())));
table.add(Box::new(CliResource::Stdout({ table.add("stdout", Box::new(CliResource::Stdout({
#[cfg(not(windows))] #[cfg(not(windows))]
let stdout = unsafe { std::fs::File::from_raw_fd(1) }; let stdout = unsafe { std::fs::File::from_raw_fd(1) };
#[cfg(windows)] #[cfg(windows)]
@ -62,7 +62,7 @@ lazy_static! {
tokio::fs::File::from_std(stdout) tokio::fs::File::from_std(stdout)
}))); })));
table.add(Box::new(CliResource::Stderr(tokio::io::stderr()))); table.add("stderr", Box::new(CliResource::Stderr(tokio::io::stderr())));
table table
}); });
} }
@ -98,6 +98,9 @@ enum CliResource {
} }
impl CoreResource for CliResource { impl CoreResource for CliResource {
// TODO(ry) These task notifications are hacks to workaround various behaviors
// in Tokio. They should not influence the overall design of Deno. The
// CoreResource::close should be removed in favor of the drop trait.
fn close(&self) { fn close(&self) {
match self { match self {
CliResource::TcpListener(_, Some(t)) => { CliResource::TcpListener(_, Some(t)) => {
@ -109,25 +112,6 @@ impl CoreResource for CliResource {
_ => {} _ => {}
} }
} }
fn inspect_repr(&self) -> &str {
match self {
CliResource::Stdin(_) => "stdin",
CliResource::Stdout(_) => "stdout",
CliResource::Stderr(_) => "stderr",
CliResource::FsFile(_) => "fsFile",
CliResource::TcpListener(_, _) => "tcpListener",
CliResource::TlsListener(_, _, _) => "tlsListener",
CliResource::TcpStream(_) => "tcpStream",
CliResource::ClientTlsStream(_) => "clientTlsStream",
CliResource::ServerTlsStream(_) => "serverTlsStream",
CliResource::HttpBody(_) => "httpBody",
CliResource::Child(_) => "child",
CliResource::ChildStdin(_) => "childStdin",
CliResource::ChildStdout(_) => "childStdout",
CliResource::ChildStderr(_) => "childStderr",
}
}
} }
pub fn lock_resource_table<'a>() -> MutexGuard<'a, ResourceTable> { pub fn lock_resource_table<'a>() -> MutexGuard<'a, ResourceTable> {
@ -319,13 +303,16 @@ impl DenoAsyncWrite for Resource {
pub fn add_fs_file(fs_file: tokio::fs::File) -> Resource { pub fn add_fs_file(fs_file: tokio::fs::File) -> Resource {
let mut table = lock_resource_table(); let mut table = lock_resource_table();
let rid = table.add(Box::new(CliResource::FsFile(fs_file))); let rid = table.add("fsFile", Box::new(CliResource::FsFile(fs_file)));
Resource { rid } Resource { rid }
} }
pub fn add_tcp_listener(listener: tokio::net::TcpListener) -> Resource { pub fn add_tcp_listener(listener: tokio::net::TcpListener) -> Resource {
let mut table = lock_resource_table(); let mut table = lock_resource_table();
let rid = table.add(Box::new(CliResource::TcpListener(listener, None))); let rid = table.add(
"tcpListener",
Box::new(CliResource::TcpListener(listener, None)),
);
Resource { rid } Resource { rid }
} }
@ -334,33 +321,41 @@ pub fn add_tls_listener(
acceptor: TlsAcceptor, acceptor: TlsAcceptor,
) -> Resource { ) -> Resource {
let mut table = lock_resource_table(); let mut table = lock_resource_table();
let rid = let rid = table.add(
table.add(Box::new(CliResource::TlsListener(listener, acceptor, None))); "tlsListener",
Box::new(CliResource::TlsListener(listener, acceptor, None)),
);
Resource { rid } Resource { rid }
} }
pub fn add_tcp_stream(stream: tokio::net::TcpStream) -> Resource { pub fn add_tcp_stream(stream: tokio::net::TcpStream) -> Resource {
let mut table = lock_resource_table(); let mut table = lock_resource_table();
let rid = table.add(Box::new(CliResource::TcpStream(stream))); let rid = table.add("tcpStream", Box::new(CliResource::TcpStream(stream)));
Resource { rid } Resource { rid }
} }
pub fn add_tls_stream(stream: ClientTlsStream<TcpStream>) -> Resource { pub fn add_tls_stream(stream: ClientTlsStream<TcpStream>) -> Resource {
let mut table = lock_resource_table(); let mut table = lock_resource_table();
let rid = table.add(Box::new(CliResource::ClientTlsStream(Box::new(stream)))); let rid = table.add(
"clientTlsStream",
Box::new(CliResource::ClientTlsStream(Box::new(stream))),
);
Resource { rid } Resource { rid }
} }
pub fn add_server_tls_stream(stream: ServerTlsStream<TcpStream>) -> Resource { pub fn add_server_tls_stream(stream: ServerTlsStream<TcpStream>) -> Resource {
let mut table = lock_resource_table(); let mut table = lock_resource_table();
let rid = table.add(Box::new(CliResource::ServerTlsStream(Box::new(stream)))); let rid = table.add(
"serverTlsStream",
Box::new(CliResource::ServerTlsStream(Box::new(stream))),
);
Resource { rid } Resource { rid }
} }
pub fn add_reqwest_body(body: ReqwestDecoder) -> Resource { pub fn add_reqwest_body(body: ReqwestDecoder) -> Resource {
let body = HttpBody::from(body); let body = HttpBody::from(body);
let mut table = lock_resource_table(); let mut table = lock_resource_table();
let rid = table.add(Box::new(CliResource::HttpBody(body))); let rid = table.add("httpBody", Box::new(CliResource::HttpBody(body)));
Resource { rid } Resource { rid }
} }
@ -383,21 +378,23 @@ pub fn add_child(mut child: tokio_process::Child) -> ChildResources {
if child.stdin().is_some() { if child.stdin().is_some() {
let stdin = child.stdin().take().unwrap(); let stdin = child.stdin().take().unwrap();
let rid = table.add(Box::new(CliResource::ChildStdin(stdin))); let rid = table.add("childStdin", Box::new(CliResource::ChildStdin(stdin)));
resources.stdin_rid = Some(rid); resources.stdin_rid = Some(rid);
} }
if child.stdout().is_some() { if child.stdout().is_some() {
let stdout = child.stdout().take().unwrap(); let stdout = child.stdout().take().unwrap();
let rid = table.add(Box::new(CliResource::ChildStdout(stdout))); let rid =
table.add("childStdout", Box::new(CliResource::ChildStdout(stdout)));
resources.stdout_rid = Some(rid); resources.stdout_rid = Some(rid);
} }
if child.stderr().is_some() { if child.stderr().is_some() {
let stderr = child.stderr().take().unwrap(); let stderr = child.stderr().take().unwrap();
let rid = table.add(Box::new(CliResource::ChildStderr(stderr))); let rid =
table.add("childStderr", Box::new(CliResource::ChildStderr(stderr)));
resources.stderr_rid = Some(rid); resources.stderr_rid = Some(rid);
} }
let rid = table.add(Box::new(CliResource::Child(Box::new(child)))); let rid = table.add("child", Box::new(CliResource::Child(Box::new(child))));
resources.child_rid = Some(rid); resources.child_rid = Some(rid);
resources resources
@ -440,7 +437,7 @@ pub fn get_file(rid: ResourceId) -> Result<std::fs::File, ErrBox> {
let mut table = lock_resource_table(); let mut table = lock_resource_table();
// We take ownership of File here. // We take ownership of File here.
// It is put back below while still holding the lock. // It is put back below while still holding the lock.
let repr = table.map.remove(&rid).ok_or_else(bad_resource)?; let (_name, repr) = table.map.remove(&rid).ok_or_else(bad_resource)?;
let repr = repr let repr = repr
.downcast::<CliResource>() .downcast::<CliResource>()
.or_else(|_| Err(bad_resource()))?; .or_else(|_| Err(bad_resource()))?;
@ -460,7 +457,10 @@ pub fn get_file(rid: ResourceId) -> Result<std::fs::File, ErrBox> {
// Insert the entry back with the same rid. // Insert the entry back with the same rid.
table.map.insert( table.map.insert(
rid, rid,
(
"fsFile".to_string(),
Box::new(CliResource::FsFile(tokio_fs::File::from_std(std_file))), Box::new(CliResource::FsFile(tokio_fs::File::from_std(std_file))),
),
); );
maybe_std_file_copy.map_err(ErrBox::from) maybe_std_file_copy.map_err(ErrBox::from)

View file

@ -196,7 +196,7 @@ impl ThreadSafeState {
}; };
let mut table = resources::lock_resource_table(); let mut table = resources::lock_resource_table();
let rid = table.add(Box::new(external_channels)); let rid = table.add("worker", Box::new(external_channels));
let import_map: Option<ImportMap> = let import_map: Option<ImportMap> =
match global_state.flags.import_map_path.as_ref() { match global_state.flags.import_map_path.as_ref() {

View file

@ -31,11 +31,7 @@ pub struct WorkerChannels {
pub receiver: mpsc::Receiver<Buf>, pub receiver: mpsc::Receiver<Buf>,
} }
impl CoreResource for WorkerChannels { impl CoreResource for WorkerChannels {}
fn inspect_repr(&self) -> &str {
"worker"
}
}
/// Wraps deno::Isolate to provide source maps, ops for the CLI, and /// Wraps deno::Isolate to provide source maps, ops for the CLI, and
/// high-level module loading. /// high-level module loading.

View file

@ -190,19 +190,11 @@ pub fn bad_resource() -> Error {
struct TcpListener(tokio::net::TcpListener); struct TcpListener(tokio::net::TcpListener);
impl Resource for TcpListener { impl Resource for TcpListener {}
fn inspect_repr(&self) -> &str {
"tcpListener"
}
}
struct TcpStream(tokio::net::TcpStream); struct TcpStream(tokio::net::TcpStream);
impl Resource for TcpStream { impl Resource for TcpStream {}
fn inspect_repr(&self) -> &str {
"tcpStream"
}
}
lazy_static! { lazy_static! {
static ref RESOURCE_TABLE: Mutex<ResourceTable> = static ref RESOURCE_TABLE: Mutex<ResourceTable> =
@ -225,7 +217,7 @@ fn op_accept(record: Record, _zero_copy_buf: Option<PinnedBuf>) -> Box<HttpOp> {
.and_then(move |(stream, addr)| { .and_then(move |(stream, addr)| {
debug!("accept success {}", addr); debug!("accept success {}", addr);
let mut table = lock_resource_table(); let mut table = lock_resource_table();
let rid = table.add(Box::new(TcpStream(stream))); let rid = table.add("tcpStream", Box::new(TcpStream(stream)));
Ok(rid as i32) Ok(rid as i32)
}); });
Box::new(fut) Box::new(fut)
@ -239,7 +231,7 @@ fn op_listen(
let addr = "127.0.0.1:4544".parse::<SocketAddr>().unwrap(); let addr = "127.0.0.1:4544".parse::<SocketAddr>().unwrap();
let listener = tokio::net::TcpListener::bind(&addr).unwrap(); let listener = tokio::net::TcpListener::bind(&addr).unwrap();
let mut table = lock_resource_table(); let mut table = lock_resource_table();
let rid = table.add(Box::new(TcpListener(listener))); let rid = table.add("tcpListener", Box::new(TcpListener(listener)));
Box::new(futures::future::ok(rid as i32)) Box::new(futures::future::ok(rid as i32))
} }

View file

@ -17,7 +17,7 @@ pub type ResourceId = u32;
/// These store Deno's file descriptors. These are not necessarily the operating /// These store Deno's file descriptors. These are not necessarily the operating
/// system ones. /// system ones.
type ResourceMap = HashMap<ResourceId, Box<dyn Resource>>; type ResourceMap = HashMap<ResourceId, (String, Box<dyn Resource>)>;
#[derive(Default)] #[derive(Default)]
pub struct ResourceTable { pub struct ResourceTable {
@ -29,7 +29,7 @@ pub struct ResourceTable {
impl ResourceTable { impl ResourceTable {
pub fn get<T: Resource>(&self, rid: ResourceId) -> Option<&T> { pub fn get<T: Resource>(&self, rid: ResourceId) -> Option<&T> {
if let Some(resource) = self.map.get(&rid) { if let Some((_name, resource)) = self.map.get(&rid) {
return resource.downcast_ref::<T>(); return resource.downcast_ref::<T>();
} }
@ -37,7 +37,7 @@ impl ResourceTable {
} }
pub fn get_mut<T: Resource>(&mut self, rid: ResourceId) -> Option<&mut T> { pub fn get_mut<T: Resource>(&mut self, rid: ResourceId) -> Option<&mut T> {
if let Some(resource) = self.map.get_mut(&rid) { if let Some((_name, resource)) = self.map.get_mut(&rid) {
return resource.downcast_mut::<T>(); return resource.downcast_mut::<T>();
} }
@ -51,9 +51,9 @@ impl ResourceTable {
next_rid as ResourceId next_rid as ResourceId
} }
pub fn add(&mut self, resource: Box<dyn Resource>) -> ResourceId { pub fn add(&mut self, name: &str, resource: Box<dyn Resource>) -> ResourceId {
let rid = self.next_rid(); let rid = self.next_rid();
let r = self.map.insert(rid, resource); let r = self.map.insert(rid, (name.to_string(), resource));
assert!(r.is_none()); assert!(r.is_none());
rid rid
} }
@ -62,18 +62,17 @@ impl ResourceTable {
self self
.map .map
.iter() .iter()
.map(|(key, value)| (*key, value.inspect_repr().to_string())) .map(|(key, (name, _resource))| (*key, name.clone()))
.collect() .collect()
} }
// close(2) is done by dropping the value. Therefore we just need to remove // close(2) is done by dropping the value. Therefore we just need to remove
// the resource from the RESOURCE_TABLE. // the resource from the RESOURCE_TABLE.
pub fn close(&mut self, rid: ResourceId) -> Option<()> { pub fn close(&mut self, rid: ResourceId) -> Option<()> {
if let Some(resource) = self.map.remove(&rid) { if let Some((_name, resource)) = self.map.remove(&rid) {
resource.close(); resource.close();
return Some(()); return Some(());
} }
None None
} }
} }
@ -81,8 +80,7 @@ impl ResourceTable {
/// Abstract type representing resource in Deno. /// Abstract type representing resource in Deno.
pub trait Resource: Downcast + Any + Send { pub trait Resource: Downcast + Any + Send {
/// Method that allows to cleanup resource. /// Method that allows to cleanup resource.
// TODO(ry) remove this method. Resources should rely on drop trait instead.
fn close(&self) {} fn close(&self) {}
fn inspect_repr(&self) -> &str;
} }
impl_downcast!(Resource); impl_downcast!(Resource);