diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2018-10-01 19:37:18 -0400 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2018-10-01 22:30:57 -0400 |
commit | 42c5b103ec0c0fc52b868b0824807c0ad358a2e3 (patch) | |
tree | 001220438c547d9fcf346de239e94370e7a5c4ff /src | |
parent | 393f751a274c338db1c4f675f796257106e9d579 (diff) |
Rename FdTable to ResourceTable.
Add docs to src/resources.rs.
Diffstat (limited to 'src')
-rw-r--r-- | src/files.rs | 119 | ||||
-rw-r--r-- | src/handlers.rs | 22 | ||||
-rw-r--r-- | src/main.rs | 2 | ||||
-rw-r--r-- | src/msg.fbs | 8 | ||||
-rw-r--r-- | src/resources.rs | 126 |
5 files changed, 142 insertions, 135 deletions
diff --git a/src/files.rs b/src/files.rs deleted file mode 100644 index 64160bb84..000000000 --- a/src/files.rs +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. - -use futures; -use futures::Poll; -use std; -use std::collections::HashMap; -use std::io::Error; -use std::io::{Read, Write}; -use std::sync::atomic::AtomicIsize; -use std::sync::atomic::Ordering; -use std::sync::Mutex; -use tokio; -use tokio::io::{AsyncRead, AsyncWrite}; - -// These store Deno's file descriptors. These are not necessarally the operating -// system ones. -type FdTable = HashMap<i32, Repr>; - -lazy_static! { - // Starts at 3 because stdio is [0-2]. - static ref NEXT_FD: AtomicIsize = AtomicIsize::new(3); - static ref FD_TABLE: Mutex<FdTable> = Mutex::new({ - let mut m = HashMap::new(); - // TODO Load these lazily during lookup? - m.insert(0, Repr::Stdin(tokio::io::stdin())); - m.insert(1, Repr::Stdout(tokio::io::stdout())); - m.insert(2, Repr::Stderr(tokio::io::stderr())); - m - }); -} - -// Internal representation of DFile. -enum Repr { - Stdin(tokio::io::Stdin), - Stdout(tokio::io::Stdout), - Stderr(tokio::io::Stderr), - FsFile(tokio::fs::File), -} - -// Abstract async file interface. -// fd does not necessarally correspond to an OS fd. -// Ideally in unix, if DFile represents an OS fd, it will be the same. -pub struct DFile { - pub fd: i32, -} - -impl Read for DFile { - fn read(&mut self, _buf: &mut [u8]) -> std::io::Result<usize> { - unimplemented!(); - } -} - -impl AsyncRead for DFile { - fn poll_read(&mut self, buf: &mut [u8]) -> Poll<usize, Error> { - let mut table = FD_TABLE.lock().unwrap(); - let maybe_repr = table.get_mut(&self.fd); - match maybe_repr { - None => panic!("bad fd"), - Some(repr) => match repr { - Repr::FsFile(ref mut f) => f.poll_read(buf), - Repr::Stdin(ref mut f) => f.poll_read(buf), - Repr::Stdout(_) | Repr::Stderr(_) => { - panic!("Cannot read from stdout/stderr") - } - }, - } - } -} - -impl Write for DFile { - fn write(&mut self, _buf: &[u8]) -> std::io::Result<usize> { - unimplemented!() - } - - fn flush(&mut self) -> std::io::Result<()> { - unimplemented!() - } -} - -impl AsyncWrite for DFile { - fn poll_write(&mut self, buf: &[u8]) -> Poll<usize, Error> { - let mut table = FD_TABLE.lock().unwrap(); - let maybe_repr = table.get_mut(&self.fd); - match maybe_repr { - None => panic!("bad fd"), - Some(repr) => match repr { - Repr::FsFile(ref mut f) => f.poll_write(buf), - Repr::Stdout(ref mut f) => f.poll_write(buf), - Repr::Stderr(ref mut f) => f.poll_write(buf), - Repr::Stdin(_) => panic!("Cannot write to stdin"), - }, - } - } - - fn shutdown(&mut self) -> futures::Poll<(), std::io::Error> { - unimplemented!() - } -} - -fn new_fd() -> i32 { - // TODO If on unix, just extract the real FD of fs_file. - // let fd = AsRawFd::as_raw_fd(fs_file.std()); - let next_fd = NEXT_FD.fetch_add(1, Ordering::SeqCst); - next_fd as i32 -} - -pub fn add_fs_file(fs_file: tokio::fs::File) -> DFile { - let fd = new_fd(); - let mut tg = FD_TABLE.lock().unwrap(); - match tg.insert(fd, Repr::FsFile(fs_file)) { - Some(_) => panic!("There is already a file with that fd"), - None => DFile { fd }, - } -} - -pub fn lookup(fd: i32) -> Option<DFile> { - let table = FD_TABLE.lock().unwrap(); - table.get(&fd).map(|_| DFile { fd }) -} diff --git a/src/handlers.rs b/src/handlers.rs index 1f861f000..db464f407 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -9,7 +9,6 @@ use isolate::IsolateState; use isolate::Op; use msg; -use files; use flatbuffers::FlatBufferBuilder; use futures; use futures::future::poll_fn; @@ -19,6 +18,7 @@ use hyper; use hyper::rt::{Future, Stream}; use hyper::Client; use remove_dir_all::remove_dir_all; +use resources; use std; use std::fs; #[cfg(any(unix))] @@ -575,12 +575,12 @@ fn handle_open( let op = tokio::fs::File::open(filename) .map_err(|err| DenoError::from(err)) .and_then(move |fs_file| -> OpResult { - let dfile = files::add_fs_file(fs_file); + let resource = resources::add_fs_file(fs_file); let builder = &mut FlatBufferBuilder::new(); let msg = msg::OpenRes::create( builder, &msg::OpenResArgs { - fd: dfile.fd, + rid: resource.rid, ..Default::default() }, ); @@ -604,16 +604,16 @@ fn handle_read( ) -> Box<Op> { let cmd_id = base.cmd_id(); let msg = base.msg_as_read().unwrap(); - let fd = msg.fd(); + let rid = msg.rid(); - match files::lookup(fd) { + match resources::lookup(rid) { None => odd_future(errors::new( errors::ErrorKind::BadFileDescriptor, String::from("Bad File Descriptor"), )), - Some(mut dfile) => { + Some(mut resource) => { let op = futures::future::poll_fn(move || { - let poll = dfile.poll_read(data); + let poll = resource.poll_read(data); poll }).map_err(|err| DenoError::from(err)) .and_then(move |nread: usize| { @@ -648,16 +648,16 @@ fn handle_write( ) -> Box<Op> { let cmd_id = base.cmd_id(); let msg = base.msg_as_write().unwrap(); - let fd = msg.fd(); + let rid = msg.rid(); - match files::lookup(fd) { + match resources::lookup(rid) { None => odd_future(errors::new( errors::ErrorKind::BadFileDescriptor, String::from("Bad File Descriptor"), )), - Some(mut dfile) => { + Some(mut resource) => { let op = futures::future::poll_fn(move || { - let poll = dfile.poll_write(data); + let poll = resource.poll_write(data); poll }).map_err(|err| DenoError::from(err)) .and_then(move |bytes_written: usize| { diff --git a/src/main.rs b/src/main.rs index 01be538e1..d07eb5b07 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,13 +23,13 @@ extern crate ring; mod deno_dir; mod errors; -mod files; mod flags; mod fs; pub mod handlers; mod http; mod isolate; mod libdeno; +mod resources; mod tokio_util; mod version; diff --git a/src/msg.fbs b/src/msg.fbs index ef2f4946b..b9989c330 100644 --- a/src/msg.fbs +++ b/src/msg.fbs @@ -265,11 +265,11 @@ table Open { } table OpenRes { - fd: int; + rid: int; } table Read { - fd: int; + rid: int; // (ptr, len) is passed as second parameter to libdeno.send(). } @@ -279,7 +279,7 @@ table ReadRes { } table Write { - fd: int; + rid: int; } table WriteRes { @@ -287,7 +287,7 @@ table WriteRes { } table Close { - fd: int; + rid: int; } root_type Base; diff --git a/src/resources.rs b/src/resources.rs new file mode 100644 index 000000000..940b14d21 --- /dev/null +++ b/src/resources.rs @@ -0,0 +1,126 @@ +// Copyright 2018 the Deno authors. All rights reserved. MIT license. + +// Think of Resources as File Descriptors. They are integers that are allocated +// by the privlaged side of Deno to refer to various resources. The simplest +// example are standard file system files and stdio - but there will be other +// resources added in the future that might not correspond to operating system +// level File Descriptors. To avoid confusion we call them "resources" not "file +// descriptors". This module implements a global resource table. Ops (AKA +// handlers) look up resources by their integer id here. + +use futures; +use futures::Poll; +use std; +use std::collections::HashMap; +use std::io::Error; +use std::io::{Read, Write}; +use std::sync::atomic::AtomicIsize; +use std::sync::atomic::Ordering; +use std::sync::Mutex; +use tokio; +use tokio::io::{AsyncRead, AsyncWrite}; + +pub type ResourceId = i32; // Sometimes referred to RID. + +// These store Deno's file descriptors. These are not necessarily the operating +// system ones. +type ResourceTable = HashMap<ResourceId, Repr>; + +lazy_static! { + // Starts at 3 because stdio is [0-2]. + static ref NEXT_RID: AtomicIsize = AtomicIsize::new(3); + static ref RESOURCE_TABLE: Mutex<ResourceTable> = Mutex::new({ + let mut m = HashMap::new(); + // TODO Load these lazily during lookup? + m.insert(0, Repr::Stdin(tokio::io::stdin())); + m.insert(1, Repr::Stdout(tokio::io::stdout())); + m.insert(2, Repr::Stderr(tokio::io::stderr())); + m + }); +} + +// Internal representation of Resource. +enum Repr { + Stdin(tokio::io::Stdin), + Stdout(tokio::io::Stdout), + Stderr(tokio::io::Stderr), + FsFile(tokio::fs::File), +} + +// Abstract async file interface. +// Ideally in unix, if Resource represents an OS rid, it will be the same. +pub struct Resource { + pub rid: ResourceId, +} + +impl Read for Resource { + fn read(&mut self, _buf: &mut [u8]) -> std::io::Result<usize> { + unimplemented!(); + } +} + +impl AsyncRead for Resource { + fn poll_read(&mut self, buf: &mut [u8]) -> Poll<usize, Error> { + let mut table = RESOURCE_TABLE.lock().unwrap(); + let maybe_repr = table.get_mut(&self.rid); + match maybe_repr { + None => panic!("bad rid"), + Some(repr) => match repr { + Repr::FsFile(ref mut f) => f.poll_read(buf), + Repr::Stdin(ref mut f) => f.poll_read(buf), + Repr::Stdout(_) | Repr::Stderr(_) => { + panic!("Cannot read from stdout/stderr") + } + }, + } + } +} + +impl Write for Resource { + fn write(&mut self, _buf: &[u8]) -> std::io::Result<usize> { + unimplemented!() + } + + fn flush(&mut self) -> std::io::Result<()> { + unimplemented!() + } +} + +impl AsyncWrite for Resource { + fn poll_write(&mut self, buf: &[u8]) -> Poll<usize, Error> { + let mut table = RESOURCE_TABLE.lock().unwrap(); + let maybe_repr = table.get_mut(&self.rid); + match maybe_repr { + None => panic!("bad rid"), + Some(repr) => match repr { + Repr::FsFile(ref mut f) => f.poll_write(buf), + Repr::Stdout(ref mut f) => f.poll_write(buf), + Repr::Stderr(ref mut f) => f.poll_write(buf), + Repr::Stdin(_) => panic!("Cannot write to stdin"), + }, + } + } + + fn shutdown(&mut self) -> futures::Poll<(), std::io::Error> { + unimplemented!() + } +} + +fn new_rid() -> ResourceId { + let next_rid = NEXT_RID.fetch_add(1, Ordering::SeqCst); + next_rid as ResourceId +} + +pub fn add_fs_file(fs_file: tokio::fs::File) -> Resource { + let rid = new_rid(); + let mut tg = RESOURCE_TABLE.lock().unwrap(); + match tg.insert(rid, Repr::FsFile(fs_file)) { + Some(_) => panic!("There is already a file with that rid"), + None => Resource { rid }, + } +} + +pub fn lookup(rid: ResourceId) -> Option<Resource> { + let table = RESOURCE_TABLE.lock().unwrap(); + table.get(&rid).map(|_| Resource { rid }) +} |