-
Notifications
You must be signed in to change notification settings - Fork 716
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Redox OS support #844
Redox OS support #844
Conversation
Oof, seems like our net2 patch breaks windows support. Thank you AppVeyor :) |
Sometimes I really wish cargo would let you apply a patch to all dependencies |
We are currently trying to get net2 and other deps upstreamed. You might want to hold on to this PR until we're done :) |
Thanks for doing this work. Currently, adding additional platform support requires time from me that I do not have. I have written up an issue proposing how to address this here: #853. Thoughts? To get this going, someone would have to step up to be the maintainer of Mio + Redox. Next, the PR would need to be updated to only impact redox. I noticed that dependencies Cargo.toml were updated, etc... these should be submitted as separate PRs. Also, all tests would need to pass. |
Initially I thought the version bumps were necessary to get miow to use the latest version of dependencies and therefore support redox. But Cargo is nice enough that Making the platform unstable for a while does not work very well with tokio since people would then indirectly use mio and can't control the features. I guess I'll need to step up as maintainer for this. |
We can continue the details of the process (stable vs. unstable) here: #853 |
Bump? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've left a good number of small comments, mostly just small fixes. I have no idea if the code actually works, as I don't have Redox running. I think it would be nice if it could be tested on Travis.
Also I think the commits could be cleaned up.
Other then that this look good.
@@ -26,18 +26,21 @@ with-deprecated = [] | |||
default = ["with-deprecated"] | |||
|
|||
[dependencies] | |||
lazycell = "1" | |||
iovec = "0.1.2" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some dependencies are downgraded, such lazycell and libc.
src/deprecated/redox.rs
Outdated
*/ | ||
|
||
pub fn pipe() -> io::Result<(PipeReader, PipeWriter)> { | ||
let (rd, wr) = try!(sys::pipe()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use sys::pipe()?
. ?
is prefered over try!
.
src/deprecated/redox.rs
Outdated
|
||
pub fn pipe() -> io::Result<(PipeReader, PipeWriter)> { | ||
let (rd, wr) = try!(sys::pipe()); | ||
Ok((From::from(rd), From::from(wr))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also use rd.into()
, slightly smaller.
src/deprecated/redox.rs
Outdated
|
||
impl PipeReader { | ||
pub fn from_stdout(stdout: process::ChildStdout) -> io::Result<Self> { | ||
match sys::set_nonblock(stdout.as_raw_fd()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use sys::set_nonblock(stdout.as_raw_fd())?
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like most of this file was a copy paste of the unix code. Perhaps that should be cleaned up as well 😛
_ => {}, | ||
} | ||
return Ok(PipeReader::from(unsafe { Io::from_raw_fd(stdout.into_raw_fd()) })); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add new empty line.
unsafe { | ||
let bytes = (&self.efd).read(slice::from_raw_parts_mut( | ||
evts.events.as_mut_ptr() as *mut u8, | ||
evts.events.capacity() * mem::size_of::<syscall::Event>() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is incorrect. You're going beyond the bounds of the slice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
???
I'm taking the full vector, including the uninitialized contents, as a byte slice.
Then depending on how much the operating system read I set_len
to update the vector's length.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry, you're right. The code is fine I missed the fact that the type of the slice is changed to bytes.
src/sys/redox/selector.rs
Outdated
pub struct Selector { | ||
id: usize, | ||
efd: File, | ||
tokens: Mutex<BTreeMap<RawFd, BTreeSet<Token>>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use HashMap
and HashSet
? Just curious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No idea, I just went with what Jeremy did. I heard someone mention you for some reason couldn't use HashMaps inside the redox kernel, so perhaps he just got used to BTrees...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, well then it's fine to leave it.
} | ||
|
||
pub fn try_clone(&self) -> io::Result<TcpStream> { | ||
self.inner.try_clone().map(|s| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.inner.try_clone().map(TcpStream::from_stream)
?
} | ||
} | ||
|
||
impl<'a> Read for &'a TcpStream { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As with other Read
/Write
implementations on references; this is ok to do in Redox?
src/sys/redox/udp.rs
Outdated
|
||
pub fn set_only_v6(&self, _only_v6: bool) -> io::Result<()> { | ||
//self.io.set_only_v6(only_v6) | ||
Err(io::Error::new(io::ErrorKind::Other, "Not implemented")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe unimplemented!()
? Since I would like to know this while developing, but I'm not sure about this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea is that an application can fall back to something else
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. So I would be correct to assum it's not implemented in Redox?
Thank you for taking a look!
Anyway, if you want the commits squashed you're welcome to do so. I'd prefer that the pull request itself keeps the history |
Could you restart the appveyor test? I really doubt I affected that 😛 |
} | ||
} | ||
|
||
impl<'a> Read for &'a PipeReader { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, then this looks good to me.
src/deprecated/redox.rs
Outdated
|
||
impl From<Io> for PipeReader { | ||
fn from(io: Io) -> PipeReader { | ||
PipeReader { io: io } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PipeReader { io }
works here.
src/deprecated/redox.rs
Outdated
|
||
impl From<Io> for PipeWriter { | ||
fn from(io: Io) -> PipeWriter { | ||
PipeWriter { io: io } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PipeWriter { io }
src/net/tcp.rs
Outdated
@@ -7,12 +7,16 @@ | |||
//! | |||
/// [portability guidelines]: ../struct.Poll.html#portability | |||
|
|||
#[cfg(windows)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your right I was look at TcpStream::connect
, but it uses SocketAddr::V4
.
|
||
#[derive(Debug)] | ||
pub struct Selector { | ||
id: usize, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, nevermind then.
pub fn select(&self, evts: &mut Events, awakener: Token, timeout: Option<Duration>) -> io::Result<bool> { | ||
let mut timeout_fd = None; | ||
if let Some(timeout) = timeout { | ||
let mut file = File::open(format!("time:{}", CLOCK_MONOTONIC))?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't know about File::open
allocating. Then lets leave this for a future pr.
A lot of things are resolved, good job. But is there a way to test this in CI? That would really ensure that the code keeps working in the future as well. |
I'd love to add CI support, but the policy for adding new platforms has not yet been completely resolved, and @asomers' suggested changes would imply that redox starts off without a CI until it gets a lower tier. |
At the very least, it would be nice if there was some sort of cross compilation test to ensure that it compiled at the very least. |
@hawkw could you review this? I would not focus on any of the implementation details. The only thing of import is that no existing code is impacted short of mod declarations & |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@carllerche I've commented on a few changes in this branch that seem unrelated to adding Redox support.
src/sys/unix/tcp.rs
Outdated
inner: s, | ||
} | ||
}) | ||
self.inner.try_clone().map(Self::from_stream) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change seems unrelated from the rest of this branch?
src/net/tcp.rs
Outdated
if cfg!(windows) { | ||
sock.bind(&inaddr_any(addr))?; | ||
} | ||
#[cfg(windows)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change from if cfg!(windows) { ... }
to #[cfg(windows)]
is probably better, but seems unrelated to adding Redox support.
src/net/tcp.rs
Outdated
@@ -389,6 +401,7 @@ impl TcpStream { | |||
} | |||
} | |||
|
|||
#[cfg(windows)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, this seems unrelated to Redox support.
src/net/tcp.rs
Outdated
if cfg!(unix) { | ||
sock.reuse_address(true)?; | ||
} | ||
#[cfg(unix)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change from if cfg!(...)
to #[cfg(...)]
attribute seems unrelated.
src/net/tcp.rs
Outdated
@@ -7,12 +7,16 @@ | |||
//! | |||
/// [portability guidelines]: ../struct.Poll.html#portability | |||
|
|||
#[cfg(windows)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like an unrelated change?
[target.'cfg(unix)'.dependencies] | ||
libc = "0.2.42" | ||
libc = "0.2.42" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated formatting change (though, this did need to be fixed, I think).
lazycell = "1" | ||
log = "0.4" | ||
net2 = "0.2.33" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Were the dependency version bumps necessary for adding Redox support?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, net2 only recently has redox support
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, thanks for clearing that up!
@carllerche Didn't want to set up a CI until I got thumbs up, especially with @asomers' proposed platform policy (which would only allow a CI at tier 2). With your permission I shall do so now. |
31a1372
to
0a4b663
Compare
Guessing the current CI issue is unrelated? |
@jD91mZM2, yeah, the iOS CI job is busted (#863). I have a PR open (#865) to fix it which should hopefully be merged soon. BTW, thanks for backing out the unrelated changes for now. I think several of them (such as using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I added some inline comments. I think we can get this to a point where it can be merged soon.
src/lib.rs
Outdated
@@ -198,12 +201,13 @@ pub use poll::Iter as EventsIter; | |||
#[doc(hidden)] | |||
pub use io::deprecated::would_block; | |||
|
|||
#[cfg(all(unix, not(target_os = "fuchsia")))] | |||
#[cfg(any(all(unix, not(target_os = "fuchsia")), target_os = "redox"))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to move this to a separate block? So, split out the cfg(redox)
and have a separate pub mod unix
? It would make it easier to manage IMO.
src/net/tcp.rs
Outdated
@@ -7,12 +7,16 @@ | |||
//! | |||
/// [portability guidelines]: ../struct.Poll.html#portability | |||
|
|||
#[cfg(not(target_os = "redox"))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain on why this file needs changes?
I would prefer to avoid adding platform cfg guards in src/net/tcp
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Back when I wrote this, I would argue that "redox doesn't support creating non-blocking sockets before an address is bound". I am extremely certain that I tried it, but... I've seen the source code of redox' libc now, and it seems to disagree.
It's still always better to use native rust where possible (redox' backend doesn't use libc), but I cannot safely say the old code won't wory. I'll try it again, later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just double checked, also checked the code. There are unbound sockets implemented, but they don't support fcntl. I'll ask in the community chat what they'd like to do here.
@@ -683,24 +709,24 @@ impl fmt::Debug for TcpListener { | |||
* | |||
*/ | |||
|
|||
#[cfg(all(unix, not(target_os = "fuchsia")))] | |||
#[cfg(any(all(unix, not(target_os = "fuchsia")), target_os = "redox"))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if these impls should be moved out of this file in order to maintain the goal of "no cfgs" in this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that a question or an order? Personally I think it makes sense to keep them here since they're all identical content-wise (apart from fuschia), it's just a bummer redox doesn't count as unix
for some reason
The latest changes separate stuff into their respective platforms. This obviously also affects unix/windows, but not more than strictly necessary. I might be able to revert and keep redox consistent to unix if the redox netstack team gives me thumbs up to implement fcntl for unbound sockets |
Ok, here is the plan. Lets get this in the 0.7 release of Mio. I commented with a proposed implementation strategy for adding new platforms here. This proposal is based on how this PR needs to touch so many files. I want to avoid this. So, if my proposed strategy is accepted, the contents of wdyt? |
I appreciate the idea, it sounds pretty great! I'm afraid, however, I might just drop this PR in its entirety as rust-lang/rust#60139 is merging. Redox is moving its focus away from updating the world to rely directly on Redox APIs, and instead making the C API cover everything. So I am sorry if I made you figure out this policy for smaller gain than expected, but I hope you can still use it for the other platforms as it sounds like a great idea in general. |
Sorry about all that. The policy is still going to be valuable I think. However, even w/ redox targettng |
That's true, someone will probably open a small PR to add redox to the linux |
@jD91mZM2 this is likely not the place for it, but I would recommend |
@Thomasdezeeuw I will look up EDIT: This will require kernel support to be any better than a compatibility layer around epoll. |
This was a part of my RSoC project of porting tokio and I think it's complete now :)
Tested:
0.0.0.0:0
straight from rust which indicates this is a problem with either my setup or rust itself)web_api
is trying to connect to itself, which I think is generally broken - you can't even communicate between two netcat instances running on redox)