Skip to content

Commit

Permalink
Remove UnsafeCell from Unix Awakener
Browse files Browse the repository at this point in the history
Add some impls of Read/Write for `&T` (like the stdlib does) to express that a
mutable borrow isn't needed, allowing removal of the unsafe cells in the
awakener.
  • Loading branch information
alexcrichton authored and carllerche committed Aug 20, 2015
1 parent 80dc73f commit 4dadf21
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 24 deletions.
16 changes: 16 additions & 0 deletions src/net/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,12 @@ impl Read for PipeReader {
}
}

impl<'a> Read for &'a PipeReader {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
(&self.io).read(buf)
}
}

impl Evented for PipeReader {
fn register(&self, selector: &mut Selector, token: Token, interest: EventSet, opts: PollOpt) -> io::Result<()> {
self.io.register(selector, token, interest, opts)
Expand Down Expand Up @@ -232,6 +238,16 @@ impl Write for PipeWriter {
}
}

impl<'a> Write for &'a PipeWriter {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
(&self.io).write(buf)
}

fn flush(&mut self) -> io::Result<()> {
(&self.io).flush()
}
}

impl Evented for PipeWriter {
fn register(&self, selector: &mut Selector, token: Token, interest: EventSet, opts: PollOpt) -> io::Result<()> {
self.io.register(selector, token, interest, opts)
Expand Down
34 changes: 10 additions & 24 deletions src/sys/unix/awakener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ pub use self::pipe::Awakener;
mod pipe {
use {io, Evented, EventSet, PollOpt, Selector, Token, TryRead, TryWrite};
use unix::{self, PipeReader, PipeWriter};
use std::mem;
use std::cell::UnsafeCell;

/*
*
Expand All @@ -14,50 +12,38 @@ mod pipe {
*/

pub struct Awakener {
reader: UnsafeCell<PipeReader>,
writer: UnsafeCell<PipeWriter>,
reader: PipeReader,
writer: PipeWriter,
}

impl Awakener {
pub fn new() -> io::Result<Awakener> {
let (rd, wr) = try!(unix::pipe());

Ok(Awakener {
reader: UnsafeCell::new(rd),
writer: UnsafeCell::new(wr),
reader: rd,
writer: wr,
})
}

pub fn wakeup(&self) -> io::Result<()> {
// A hack, but such is life. PipeWriter is backed by a single FD, which
// is thread safe.
unsafe {
let wr: &mut PipeWriter = mem::transmute(self.writer.get());
wr.try_write(b"0x01").map(|_| ())
}
(&self.writer).try_write(b"0x01").map(|_| ())
}

pub fn cleanup(&self) {
let mut buf = [0; 128];

loop {
// Also a bit hackish. It would be possible to split up the read /
// write sides of the awakener, but that would be a more
// significant refactor. A transmute here is safe.
unsafe {
let rd: &mut PipeReader = mem::transmute(self.reader.get());

// Consume data until all bytes are purged
match rd.try_read(&mut buf) {
Ok(Some(i)) if i > 0 => {},
_ => return,
}
// Consume data until all bytes are purged
match (&self.reader).try_read(&mut buf) {
Ok(Some(i)) if i > 0 => {},
_ => return,
}
}
}

fn reader(&self) -> &PipeReader {
unsafe { mem::transmute(self.reader.get()) }
&self.reader
}
}

Expand Down
16 changes: 16 additions & 0 deletions src/sys/unix/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ impl Evented for Io {
}

impl Read for Io {
fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
<&Io as Read>::read(&mut &*self, dst)
}
}

impl<'a> Read for &'a Io {
fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
use nix::unistd::read;

Expand All @@ -61,6 +67,16 @@ impl Read for Io {
}

impl Write for Io {
fn write(&mut self, src: &[u8]) -> io::Result<usize> {
<&Io as Write>::write(&mut &*self, src)
}

fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}

impl<'a> Write for &'a Io {
fn write(&mut self, src: &[u8]) -> io::Result<usize> {
use nix::unistd::write;

Expand Down

0 comments on commit 4dadf21

Please sign in to comment.