summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/files.rs119
-rw-r--r--src/handlers.rs22
-rw-r--r--src/main.rs2
-rw-r--r--src/msg.fbs8
-rw-r--r--src/resources.rs126
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 })
+}