firmware: eliminate uses of std_artiq::io::{Read,Write} from runtime.

This commit is contained in:
whitequark 2018-05-14 19:06:54 +00:00
parent cf33ba748d
commit 5ead27f2e1
12 changed files with 118 additions and 132 deletions

View File

@ -111,7 +111,6 @@ name = "io"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"std_artiq 0.0.0",
] ]
[[package]] [[package]]

View File

@ -9,7 +9,6 @@ path = "lib.rs"
[dependencies] [dependencies]
byteorder = { version = "1.0", default-features = false, optional = true } byteorder = { version = "1.0", default-features = false, optional = true }
std_artiq = { path = "../libstd_artiq", optional = true }
[features] [features]
alloc = [] alloc = []

View File

@ -8,9 +8,6 @@ extern crate alloc;
#[cfg(feature = "byteorder")] #[cfg(feature = "byteorder")]
extern crate byteorder; extern crate byteorder;
#[cfg(feature = "std_artiq")]
extern crate std_artiq;
use core::result; use core::result;
use core::fmt; use core::fmt;
@ -67,6 +64,14 @@ pub trait Read {
} }
} }
impl<'a, T: Read> Read for &'a mut T {
type ReadError = T::ReadError;
fn read(&mut self, buf: &mut [u8]) -> result::Result<usize, Self::ReadError> {
T::read(self, buf)
}
}
pub trait Write { pub trait Write {
type WriteError; type WriteError;
type FlushError; type FlushError;
@ -99,7 +104,23 @@ pub trait Write {
fn size_hint(&mut self, _min: usize, _max: Option<usize>) {} fn size_hint(&mut self, _min: usize, _max: Option<usize>) {}
} }
#[cfg(not(feature = "std_artiq"))] impl<'a, T: Write> Write for &'a mut T {
type WriteError = T::WriteError;
type FlushError = T::FlushError;
fn write(&mut self, buf: &[u8]) -> result::Result<usize, Self::WriteError> {
T::write(self, buf)
}
fn flush(&mut self) -> result::Result<(), Self::FlushError> {
T::flush(self)
}
fn size_hint(&mut self, min: usize, max: Option<usize>) {
T::size_hint(self, min, max)
}
}
impl<'a> Write for &'a mut [u8] { impl<'a> Write for &'a mut [u8] {
type WriteError = !; type WriteError = !;
type FlushError = !; type FlushError = !;
@ -116,6 +137,22 @@ impl<'a> Write for &'a mut [u8] {
} }
} }
#[cfg(feature = "alloc")]
impl<'a> Write for alloc::Vec<u8> {
type WriteError = !;
type FlushError = !;
fn write(&mut self, buf: &[u8]) -> result::Result<usize, Self::WriteError> {
self.extend_from_slice(buf);
Ok(buf.len())
}
#[inline]
fn flush(&mut self) -> result::Result<(), Self::FlushError> {
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CursorError { pub enum CursorError {
EndOfBuffer EndOfBuffer
@ -196,7 +233,7 @@ impl Write for Cursor<::alloc::Vec<u8>> {
#[inline] #[inline]
fn write(&mut self, buf: &[u8]) -> result::Result<usize, Self::WriteError> { fn write(&mut self, buf: &[u8]) -> result::Result<usize, Self::WriteError> {
self.inner.extend(buf); self.inner.extend_from_slice(buf);
Ok(buf.len()) Ok(buf.len())
} }
@ -205,44 +242,3 @@ impl Write for Cursor<::alloc::Vec<u8>> {
Ok(()) Ok(())
} }
} }
#[cfg(feature = "std_artiq")]
impl<T> Read for T where T: std_artiq::io::Read + ?Sized {
type ReadError = std_artiq::io::Error;
fn read(&mut self, buf: &mut [u8]) -> result::Result<usize, Self::ReadError> {
std_artiq::io::Read::read(self, buf)
}
}
#[cfg(feature = "std_artiq")]
impl<T> Write for T where T: std_artiq::io::Write + ?Sized {
type WriteError = std_artiq::io::Error;
type FlushError = std_artiq::io::Error;
fn write(&mut self, buf: &[u8]) -> result::Result<usize, Self::WriteError> {
std_artiq::io::Write::write(self, buf)
}
fn flush(&mut self) -> result::Result<(), Self::WriteError> {
std_artiq::io::Write::flush(self)
}
}
#[cfg(feature = "std_artiq")]
impl<T> From<Error<T>> for std_artiq::io::Error
where T: Into<std_artiq::io::Error>
{
fn from(value: Error<T>) -> std_artiq::io::Error {
match value {
Error::UnexpectedEof =>
std_artiq::io::Error::new(std_artiq::io::ErrorKind::UnexpectedEof,
"unexpected end of stream"),
Error::Unrecognized =>
std_artiq::io::Error::new(std_artiq::io::ErrorKind::InvalidData,
"unrecognized data"),
Error::Other(err) =>
err.into()
}
}
}

View File

@ -36,21 +36,6 @@ impl<T> From<ReadStringError<IoError<T>>> for IoError<T>
} }
} }
#[cfg(feature = "alloc")]
#[cfg(feature = "std_artiq")]
impl<T> From<ReadStringError<T>> for ::std_artiq::io::Error
where T: Into<::std_artiq::io::Error>
{
fn from(value: ReadStringError<T>) -> ::std_artiq::io::Error {
match value {
ReadStringError::Utf8Error(_) =>
::std_artiq::io::Error::new(::std_artiq::io::ErrorKind::InvalidData,
"invalid UTF-8"),
ReadStringError::Other(err) => err.into()
}
}
}
pub trait ProtoRead { pub trait ProtoRead {
type ReadError; type ReadError;

View File

@ -19,7 +19,7 @@ cslice = { version = "0.3" }
log = { version = "0.4", default-features = false } log = { version = "0.4", default-features = false }
managed = { version = "0.6", default-features = false, features = ["alloc", "map"] } managed = { version = "0.6", default-features = false, features = ["alloc", "map"] }
unwind_backtrace = { path = "../libunwind_backtrace" } unwind_backtrace = { path = "../libunwind_backtrace" }
io = { path = "../libio", features = ["byteorder", "std_artiq"] } io = { path = "../libio", features = ["byteorder"] }
alloc_list = { path = "../liballoc_list" } alloc_list = { path = "../liballoc_list" }
board_misoc = { path = "../libboard_misoc", features = ["uart_console", "smoltcp"] } board_misoc = { path = "../libboard_misoc", features = ["uart_console", "smoltcp"] }
std_artiq = { path = "../libstd_artiq", features = ["alloc", "io_error_alloc"] } std_artiq = { path = "../libstd_artiq", features = ["alloc", "io_error_alloc"] }

View File

@ -1,4 +1,4 @@
use std::io::{self, Write}; use io::{self, Write};
use board_misoc::{csr, cache}; use board_misoc::{csr, cache};
use sched::{Io, TcpListener, TcpStream}; use sched::{Io, TcpListener, TcpStream};
use analyzer_proto::*; use analyzer_proto::*;
@ -35,7 +35,7 @@ fn disarm() {
} }
} }
fn worker(stream: &mut TcpStream) -> io::Result<()> { fn worker(stream: &mut TcpStream) -> io::Result<(), ::std::io::Error> {
let data = unsafe { &BUFFER.data[..] }; let data = unsafe { &BUFFER.data[..] };
let overflow_occurred = unsafe { csr::rtio_analyzer::message_encoder_overflow_read() != 0 }; let overflow_occurred = unsafe { csr::rtio_analyzer::message_encoder_overflow_read() != 0 };
let total_byte_count = unsafe { csr::rtio_analyzer::dma_byte_count_read() }; let total_byte_count = unsafe { csr::rtio_analyzer::dma_byte_count_read() };

View File

@ -1,4 +1,4 @@
use std::io; use io;
use kernel_proto as kern; use kernel_proto as kern;
use sched::Io; use sched::Io;
use session::{kern_acknowledge, kern_send}; use session::{kern_acknowledge, kern_send};
@ -291,7 +291,7 @@ mod spi {
} }
} }
pub fn process_kern_hwreq(io: &Io, request: &kern::Message) -> io::Result<bool> { pub fn process_kern_hwreq(io: &Io, request: &kern::Message) -> io::Result<bool, ::std::io::Error> {
match request { match request {
#[cfg(has_rtio_core)] #[cfg(has_rtio_core)]
&kern::RtioInitRequest => { &kern::RtioInitRequest => {

View File

@ -1,27 +1,26 @@
use std::io::{self, Read, Write};
use log::{self, LevelFilter}; use log::{self, LevelFilter};
use io::{self, Read, Write, proto::ProtoWrite};
use board_misoc::boot; use board_misoc::boot;
use io::proto::ProtoWrite;
use logger_artiq::BufferLogger; use logger_artiq::BufferLogger;
use sched::Io; use sched::Io;
use sched::{TcpListener, TcpStream}; use sched::{TcpListener, TcpStream};
use mgmt_proto::*; use mgmt_proto::*;
use profiler; use profiler;
fn check_magic(stream: &mut TcpStream) -> io::Result<()> { fn check_magic(stream: &mut TcpStream) -> io::Result<(), ::std::io::Error> {
const MAGIC: &'static [u8] = b"ARTIQ management\n"; const MAGIC: &'static [u8] = b"ARTIQ management\n";
let mut magic: [u8; 17] = [0; 17]; let mut magic: [u8; 17] = [0; 17];
stream.read_exact(&mut magic)?; stream.read_exact(&mut magic)?;
if magic != MAGIC { if magic != MAGIC {
Err(io::Error::new(io::ErrorKind::InvalidData, "unrecognized magic")) Err(io::Error::Unrecognized)
} else { } else {
Ok(()) Ok(())
} }
} }
fn worker(io: &Io, stream: &mut TcpStream) -> io::Result<()> { fn worker(io: &Io, stream: &mut TcpStream) -> io::Result<(), ::std::io::Error> {
check_magic(stream)?; check_magic(stream)?;
info!("new connection from {}", stream.remote_endpoint()); info!("new connection from {}", stream.remote_endpoint());
@ -35,7 +34,7 @@ fn worker(io: &Io, stream: &mut TcpStream) -> io::Result<()> {
} }
Request::ClearLog => { Request::ClearLog => {
BufferLogger::with(|logger| -> io::Result<()> { BufferLogger::with(|logger| -> io::Result<(), ::std::io::Error> {
let mut buffer = io.until_ok(|| logger.buffer())?; let mut buffer = io.until_ok(|| logger.buffer())?;
Ok(buffer.clear()) Ok(buffer.clear())
})?; })?;
@ -44,7 +43,7 @@ fn worker(io: &Io, stream: &mut TcpStream) -> io::Result<()> {
} }
Request::PullLog => { Request::PullLog => {
BufferLogger::with(|logger| -> io::Result<()> { BufferLogger::with(|logger| -> io::Result<(), ::std::io::Error> {
loop { loop {
// Do this *before* acquiring the buffer, since that sets the log level // Do this *before* acquiring the buffer, since that sets the log level
// to OFF. // to OFF.
@ -166,8 +165,7 @@ pub fn thread(io: Io) {
let mut stream = TcpStream::from_handle(&io, stream); let mut stream = TcpStream::from_handle(&io, stream);
match worker(&io, &mut stream) { match worker(&io, &mut stream) {
Ok(()) => (), Ok(()) => (),
Err(ref err) if err.kind() == io::ErrorKind::UnexpectedEof => (), Err(io::Error::UnexpectedEof) => (),
Err(ref err) if err.kind() == io::ErrorKind::WriteZero => (),
Err(err) => error!("aborted: {}", err) Err(err) => error!("aborted: {}", err)
} }
}); });

View File

@ -1,6 +1,6 @@
use alloc::btree_map::BTreeMap; use alloc::btree_map::BTreeMap;
use std::io::{self, Read}; use io::{self, Read};
use sched::Io; use sched::Io;
use sched::{TcpListener, TcpStream}; use sched::{TcpListener, TcpStream};
use board_misoc::{clock, csr}; use board_misoc::{clock, csr};
@ -9,13 +9,13 @@ use drtioaux;
use moninj_proto::*; use moninj_proto::*;
fn check_magic(stream: &mut TcpStream) -> io::Result<()> { fn check_magic(stream: &mut TcpStream) -> io::Result<(), ::std::io::Error> {
const MAGIC: &'static [u8] = b"ARTIQ moninj\n"; const MAGIC: &'static [u8] = b"ARTIQ moninj\n";
let mut magic: [u8; 13] = [0; 13]; let mut magic: [u8; 13] = [0; 13];
stream.read_exact(&mut magic)?; stream.read_exact(&mut magic)?;
if magic != MAGIC { if magic != MAGIC {
Err(io::Error::new(io::ErrorKind::InvalidData, "unrecognized magic")) Err(io::Error::Unrecognized)
} else { } else {
Ok(()) Ok(())
} }
@ -159,7 +159,7 @@ fn read_injection_status(channel: u32, probe: u8) -> u8 {
0 0
} }
fn connection_worker(io: &Io, mut stream: &mut TcpStream) -> io::Result<()> { fn connection_worker(io: &Io, mut stream: &mut TcpStream) -> io::Result<(), ::std::io::Error> {
let mut watch_list = BTreeMap::new(); let mut watch_list = BTreeMap::new();
let mut next_check = 0; let mut next_check = 0;

View File

@ -1,7 +1,7 @@
use core::mem; use core::mem;
use alloc::{Vec, String, BTreeMap}; use alloc::{Vec, String, BTreeMap};
use std::io::Write; use io::Write;
const ALIGNMENT: usize = 64; const ALIGNMENT: usize = 64;

View File

@ -9,8 +9,9 @@ use fringe::generator::{Generator, Yielder, State as GeneratorState};
use smoltcp::wire::IpEndpoint; use smoltcp::wire::IpEndpoint;
use smoltcp::socket::{SocketHandle, SocketRef}; use smoltcp::socket::{SocketHandle, SocketRef};
use io::{Read, Write};
use board_misoc::clock; use board_misoc::clock;
use std::io::{Read, Write, Result, Error, ErrorKind}; use std::io::{Result, Error, ErrorKind};
use urc::Urc; use urc::Urc;
type SocketSet = ::smoltcp::socket::SocketSet<'static, 'static, 'static>; type SocketSet = ::smoltcp::socket::SocketSet<'static, 'static, 'static>;
@ -446,6 +447,8 @@ impl<'a> TcpStream<'a> {
} }
impl<'a> Read for TcpStream<'a> { impl<'a> Read for TcpStream<'a> {
type ReadError = Error;
fn read(&mut self, buf: &mut [u8]) -> Result<usize> { fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
// Only borrow the underlying socket for the span of the next statement. // Only borrow the underlying socket for the span of the next statement.
let result = self.with_lower(|mut s| s.recv_slice(buf)); let result = self.with_lower(|mut s| s.recv_slice(buf));
@ -470,6 +473,9 @@ impl<'a> Read for TcpStream<'a> {
} }
impl<'a> Write for TcpStream<'a> { impl<'a> Write for TcpStream<'a> {
type WriteError = Error;
type FlushError = Error;
fn write(&mut self, buf: &[u8]) -> Result<usize> { fn write(&mut self, buf: &[u8]) -> Result<usize> {
// Only borrow the underlying socket for the span of the next statement. // Only borrow the underlying socket for the span of the next statement.
let result = self.with_lower(|mut s| s.send_slice(buf)); let result = self.with_lower(|mut s| s.send_slice(buf));

View File

@ -2,8 +2,8 @@ use core::{mem, str, cell::{Cell, RefCell}, fmt::Write as FmtWrite};
use alloc::{Vec, String}; use alloc::{Vec, String};
use byteorder::{ByteOrder, NetworkEndian}; use byteorder::{ByteOrder, NetworkEndian};
use io::{self, Read, Write};
use board_misoc::{ident, cache, config}; use board_misoc::{ident, cache, config};
use std::io::{self, Read, Write};
use {mailbox, rpc_queue, kernel}; use {mailbox, rpc_queue, kernel};
use urc::Urc; use urc::Urc;
use sched::{ThreadHandle, Io}; use sched::{ThreadHandle, Io};
@ -23,13 +23,13 @@ macro_rules! unexpected {
($($arg:tt)*) => { ($($arg:tt)*) => {
{ {
error!($($arg)*); error!($($arg)*);
return Err(io::Error::new(io::ErrorKind::InvalidData, "protocol error")) return Err(io::Error::Unrecognized)
} }
}; };
} }
fn io_error(msg: &str) -> io::Error { fn io_error(msg: &str) -> io::Error<::std::io::Error> {
io::Error::new(io::ErrorKind::Other, msg) io::Error::Other(::std::io::Error::new(::std::io::ErrorKind::Other, msg))
} }
// Persistent state // Persistent state
@ -102,19 +102,19 @@ impl<'a> Drop for Session<'a> {
} }
} }
fn check_magic(stream: &mut TcpStream) -> io::Result<()> { fn check_magic(stream: &mut TcpStream) -> io::Result<(), ::std::io::Error> {
const MAGIC: &'static [u8] = b"ARTIQ coredev\n"; const MAGIC: &'static [u8] = b"ARTIQ coredev\n";
let mut magic: [u8; 14] = [0; 14]; let mut magic: [u8; 14] = [0; 14];
stream.read_exact(&mut magic)?; stream.read_exact(&mut magic)?;
if magic != MAGIC { if magic != MAGIC {
Err(io::Error::new(io::ErrorKind::InvalidData, "unrecognized magic")) Err(io::Error::Unrecognized)
} else { } else {
Ok(()) Ok(())
} }
} }
fn host_read(stream: &mut TcpStream) -> io::Result<host::Request> { fn host_read(stream: &mut TcpStream) -> io::Result<host::Request, ::std::io::Error> {
let request = host::Request::read_from(stream)?; let request = host::Request::read_from(stream)?;
match &request { match &request {
&host::Request::LoadKernel(_) => debug!("comm<-host LoadLibrary(...)"), &host::Request::LoadKernel(_) => debug!("comm<-host LoadLibrary(...)"),
@ -123,12 +123,12 @@ fn host_read(stream: &mut TcpStream) -> io::Result<host::Request> {
Ok(request) Ok(request)
} }
fn host_write(stream: &mut Write, reply: host::Reply) -> io::Result<()> { fn host_write(stream: &mut TcpStream, reply: host::Reply) -> io::Result<(), ::std::io::Error> {
debug!("comm->host {:?}", reply); debug!("comm->host {:?}", reply);
Ok(reply.write_to(stream)?) reply.write_to(stream)
} }
pub fn kern_send(io: &Io, request: &kern::Message) -> io::Result<()> { pub fn kern_send(io: &Io, request: &kern::Message) -> io::Result<(), ::std::io::Error> {
match request { match request {
&kern::LoadRequest(_) => debug!("comm->kern LoadRequest(...)"), &kern::LoadRequest(_) => debug!("comm->kern LoadRequest(...)"),
&kern::DmaRetrieveReply { trace, duration } => { &kern::DmaRetrieveReply { trace, duration } => {
@ -141,15 +141,15 @@ pub fn kern_send(io: &Io, request: &kern::Message) -> io::Result<()> {
_ => debug!("comm->kern {:?}", request) _ => debug!("comm->kern {:?}", request)
} }
unsafe { mailbox::send(request as *const _ as usize) } unsafe { mailbox::send(request as *const _ as usize) }
io.until(mailbox::acknowledged) Ok(io.until(mailbox::acknowledged)?)
} }
fn kern_recv_notrace<R, F>(io: &Io, f: F) -> io::Result<R> fn kern_recv_notrace<R, F>(io: &Io, f: F) -> io::Result<R, ::std::io::Error>
where F: FnOnce(&kern::Message) -> io::Result<R> { where F: FnOnce(&kern::Message) -> io::Result<R, ::std::io::Error> {
io.until(|| mailbox::receive() != 0)?; io.until(|| mailbox::receive() != 0)?;
if !kernel::validate(mailbox::receive()) { if !kernel::validate(mailbox::receive()) {
let message = format!("invalid kernel CPU pointer 0x{:x}", mailbox::receive()); let message = format!("invalid kernel CPU pointer 0x{:x}", mailbox::receive());
return Err(io::Error::new(io::ErrorKind::InvalidData, message)) return Err(io::Error::Other(::std::io::Error::new(::std::io::ErrorKind::InvalidData, message)))
} }
f(unsafe { &*(mailbox::receive() as *const kern::Message) }) f(unsafe { &*(mailbox::receive() as *const kern::Message) })
@ -171,20 +171,20 @@ fn kern_recv_dotrace(reply: &kern::Message) {
} }
#[inline(always)] #[inline(always)]
fn kern_recv<R, F>(io: &Io, f: F) -> io::Result<R> fn kern_recv<R, F>(io: &Io, f: F) -> io::Result<R, ::std::io::Error>
where F: FnOnce(&kern::Message) -> io::Result<R> { where F: FnOnce(&kern::Message) -> io::Result<R, ::std::io::Error> {
kern_recv_notrace(io, |reply| { kern_recv_notrace(io, |reply| {
kern_recv_dotrace(reply); kern_recv_dotrace(reply);
f(reply) f(reply)
}) })
} }
pub fn kern_acknowledge() -> io::Result<()> { pub fn kern_acknowledge() -> io::Result<(), ::std::io::Error> {
mailbox::acknowledge(); mailbox::acknowledge();
Ok(()) Ok(())
} }
unsafe fn kern_load(io: &Io, session: &mut Session, library: &[u8]) -> io::Result<()> { unsafe fn kern_load(io: &Io, session: &mut Session, library: &[u8]) -> io::Result<(), ::std::io::Error> {
if session.running() { if session.running() {
unexpected!("attempted to load a new kernel while a kernel was running") unexpected!("attempted to load a new kernel while a kernel was running")
} }
@ -200,8 +200,8 @@ unsafe fn kern_load(io: &Io, session: &mut Session, library: &[u8]) -> io::Resul
} }
&kern::LoadReply(Err(ref error)) => { &kern::LoadReply(Err(ref error)) => {
kernel::stop(); kernel::stop();
Err(io::Error::new(io::ErrorKind::Other, Err(io::Error::Other(::std::io::Error::new(::std::io::ErrorKind::Other,
format!("cannot load kernel: {}", error))) format!("cannot load kernel: {}", error))))
} }
other => other =>
unexpected!("unexpected reply from kernel CPU: {:?}", other) unexpected!("unexpected reply from kernel CPU: {:?}", other)
@ -209,7 +209,7 @@ unsafe fn kern_load(io: &Io, session: &mut Session, library: &[u8]) -> io::Resul
}) })
} }
fn kern_run(session: &mut Session) -> io::Result<()> { fn kern_run(session: &mut Session) -> io::Result<(), ::std::io::Error> {
if session.kernel_state != KernelState::Loaded { if session.kernel_state != KernelState::Loaded {
unexpected!("attempted to run a kernel while not in Loaded state") unexpected!("attempted to run a kernel while not in Loaded state")
} }
@ -221,7 +221,7 @@ fn kern_run(session: &mut Session) -> io::Result<()> {
fn process_host_message(io: &Io, fn process_host_message(io: &Io,
stream: &mut TcpStream, stream: &mut TcpStream,
session: &mut Session) -> io::Result<()> { session: &mut Session) -> io::Result<(), ::std::io::Error> {
match host_read(stream)? { match host_read(stream)? {
host::Request::SystemInfo => { host::Request::SystemInfo => {
host_write(stream, host::Reply::SystemInfo { host_write(stream, host::Reply::SystemInfo {
@ -359,7 +359,7 @@ fn process_host_message(io: &Io,
} }
fn process_kern_message(io: &Io, mut stream: Option<&mut TcpStream>, fn process_kern_message(io: &Io, mut stream: Option<&mut TcpStream>,
session: &mut Session) -> io::Result<bool> { session: &mut Session) -> io::Result<bool, ::std::io::Error> {
kern_recv_notrace(io, |request| { kern_recv_notrace(io, |request| {
match (request, session.kernel_state) { match (request, session.kernel_state) {
(&kern::LoadReply(_), KernelState::Loaded) | (&kern::LoadReply(_), KernelState::Loaded) |
@ -516,7 +516,7 @@ fn process_kern_message(io: &Io, mut stream: Option<&mut TcpStream>,
} }
fn process_kern_queued_rpc(stream: &mut TcpStream, fn process_kern_queued_rpc(stream: &mut TcpStream,
_session: &mut Session) -> io::Result<()> { _session: &mut Session) -> io::Result<(), ::std::io::Error> {
rpc_queue::dequeue(|slice| { rpc_queue::dequeue(|slice| {
debug!("comm<-kern (async RPC)"); debug!("comm<-kern (async RPC)");
let length = NetworkEndian::read_u32(slice) as usize; let length = NetworkEndian::read_u32(slice) as usize;
@ -529,7 +529,7 @@ fn process_kern_queued_rpc(stream: &mut TcpStream,
fn host_kernel_worker(io: &Io, fn host_kernel_worker(io: &Io,
stream: &mut TcpStream, stream: &mut TcpStream,
congress: &mut Congress) -> io::Result<()> { congress: &mut Congress) -> io::Result<(), ::std::io::Error> {
let mut session = Session::new(congress); let mut session = Session::new(congress);
loop { loop {
@ -568,7 +568,7 @@ fn host_kernel_worker(io: &Io,
fn flash_kernel_worker(io: &Io, fn flash_kernel_worker(io: &Io,
congress: &mut Congress, congress: &mut Congress,
config_key: &str) -> io::Result<()> { config_key: &str) -> io::Result<(), ::std::io::Error> {
let mut session = Session::new(congress); let mut session = Session::new(congress);
config::read(config_key, |result| { config::read(config_key, |result| {
@ -578,7 +578,8 @@ fn flash_kernel_worker(io: &Io,
// so make a copy. // so make a copy.
kern_load(io, &mut session, Vec::from(kernel).as_ref()) kern_load(io, &mut session, Vec::from(kernel).as_ref())
}, },
_ => Err(io::Error::new(io::ErrorKind::NotFound, "kernel not found")), _ => Err(io::Error::Other(::std::io::Error::new(::std::io::ErrorKind::NotFound,
"kernel not found"))),
} }
})?; })?;
kern_run(&mut session)?; kern_run(&mut session)?;
@ -639,13 +640,12 @@ pub fn thread(io: Io) {
info!("running startup kernel"); info!("running startup kernel");
match flash_kernel_worker(&io, &mut congress, "startup_kernel") { match flash_kernel_worker(&io, &mut congress, "startup_kernel") {
Ok(()) => info!("startup kernel finished"), Ok(()) => info!("startup kernel finished"),
Err(io::Error::Other(ref err)) if err.kind() == ::std::io::ErrorKind::NotFound => {
info!("no startup kernel found")
}
Err(err) => { Err(err) => {
if err.kind() == io::ErrorKind::NotFound { congress.finished_cleanly.set(false);
info!("no startup kernel found") error!("startup kernel aborted: {}", err);
} else {
congress.finished_cleanly.set(false);
error!("startup kernel aborted: {}", err);
}
} }
} }
}) })
@ -674,15 +674,16 @@ pub fn thread(io: Io) {
let mut stream = TcpStream::from_handle(&io, stream); let mut stream = TcpStream::from_handle(&io, stream);
match host_kernel_worker(&io, &mut stream, &mut *congress) { match host_kernel_worker(&io, &mut stream, &mut *congress) {
Ok(()) => (), Ok(()) => (),
Err(io::Error::UnexpectedEof) => {
info!("connection closed");
}
Err(io::Error::Other(ref err))
if err.kind() == ::std::io::ErrorKind::Interrupted => {
info!("kernel interrupted");
}
Err(err) => { Err(err) => {
if err.kind() == io::ErrorKind::UnexpectedEof { congress.finished_cleanly.set(false);
info!("connection closed"); error!("session aborted: {}", err);
} else if err.kind() == io::ErrorKind::Interrupted {
info!("kernel interrupted");
} else {
congress.finished_cleanly.set(false);
error!("session aborted: {}", err);
}
} }
} }
}); });
@ -697,15 +698,17 @@ pub fn thread(io: Io) {
match flash_kernel_worker(&io, &mut *congress, "idle_kernel") { match flash_kernel_worker(&io, &mut *congress, "idle_kernel") {
Ok(()) => Ok(()) =>
info!("idle kernel finished, standing by"), info!("idle kernel finished, standing by"),
Err(io::Error::Other(ref err))
if err.kind() == ::std::io::ErrorKind::Interrupted => {
info!("idle kernel interrupted");
}
Err(io::Error::Other(ref err))
if err.kind() == ::std::io::ErrorKind::NotFound => {
info!("no idle kernel found");
while io.relinquish().is_ok() {}
}
Err(err) => { Err(err) => {
if err.kind() == io::ErrorKind::Interrupted { error!("idle kernel aborted: {}", err);
info!("idle kernel interrupted");
} else if err.kind() == io::ErrorKind::NotFound {
info!("no idle kernel found");
while io.relinquish().is_ok() {}
} else {
error!("idle kernel aborted: {}", err);
}
} }
} }
}) })