mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 09:31:22 -05:00
Rename FdTable to ResourceTable.
Add docs to src/resources.rs.
This commit is contained in:
parent
393f751a27
commit
42c5b103ec
6 changed files with 146 additions and 139 deletions
|
@ -47,7 +47,7 @@ export async function open(
|
|||
assert(fbs.Any.OpenRes === baseRes!.msgType());
|
||||
const res = new fbs.OpenRes();
|
||||
assert(baseRes!.msg(res) != null);
|
||||
const fd = res.fd();
|
||||
const fd = res.rid();
|
||||
return new File(fd);
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ export async function read(
|
|||
): Promise<ReadResult> {
|
||||
const builder = new flatbuffers.Builder();
|
||||
fbs.Read.startRead(builder);
|
||||
fbs.Read.addFd(builder, fd);
|
||||
fbs.Read.addRid(builder, fd);
|
||||
const msg = fbs.Read.endRead(builder);
|
||||
const baseRes = await dispatch.sendAsync(builder, fbs.Any.Read, msg, p);
|
||||
assert(baseRes != null);
|
||||
|
@ -70,7 +70,7 @@ export async function read(
|
|||
export async function write(fd: number, p: ArrayBufferView): Promise<number> {
|
||||
const builder = new flatbuffers.Builder();
|
||||
fbs.Write.startWrite(builder);
|
||||
fbs.Write.addFd(builder, fd);
|
||||
fbs.Write.addRid(builder, fd);
|
||||
const msg = fbs.Write.endWrite(builder);
|
||||
const baseRes = await dispatch.sendAsync(builder, fbs.Any.Write, msg, p);
|
||||
assert(baseRes != null);
|
||||
|
@ -83,7 +83,7 @@ export async function write(fd: number, p: ArrayBufferView): Promise<number> {
|
|||
export function close(fd: number): void {
|
||||
const builder = new flatbuffers.Builder();
|
||||
fbs.Close.startClose(builder);
|
||||
fbs.Close.addFd(builder, fd);
|
||||
fbs.Close.addRid(builder, fd);
|
||||
const msg = fbs.Close.endClose(builder);
|
||||
dispatch.sendSync(builder, fbs.Any.Close, msg);
|
||||
}
|
||||
|
|
119
src/files.rs
119
src/files.rs
|
@ -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 })
|
||||
}
|
|
@ -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| {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
126
src/resources.rs
Normal file
126
src/resources.rs
Normal file
|
@ -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 })
|
||||
}
|
Loading…
Add table
Reference in a new issue