Fix usage of libuv for windows
This commit is contained in:
parent
c5fdd69d3e
commit
e38a89d0b0
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -4,7 +4,7 @@
|
||||
branch = master
|
||||
[submodule "src/libuv"]
|
||||
path = src/libuv
|
||||
url = https://github.com/joyent/libuv.git
|
||||
url = https://github.com/alexcrichton/libuv.git
|
||||
branch = master
|
||||
[submodule "src/gyp"]
|
||||
path = src/gyp
|
||||
|
@ -883,6 +883,7 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore(cfg(windows))] // FIXME(#10102) server never sees second packet
|
||||
fn test_udp_twice() {
|
||||
let server_addr = next_test_ip4();
|
||||
let client_addr = next_test_ip4();
|
||||
|
@ -251,6 +251,7 @@ mod tests {
|
||||
use super::super::local_loop;
|
||||
|
||||
#[test]
|
||||
#[ignore(cfg(windows))] // FIXME(#10386): how windows pipes work
|
||||
fn connect_err() {
|
||||
match PipeWatcher::connect(local_loop(), &"path/to/nowhere".to_c_str()) {
|
||||
Ok(*) => fail!(),
|
||||
@ -259,6 +260,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore(cfg(windows))] // FIXME(#10386): how windows pipes work
|
||||
fn bind_err() {
|
||||
match PipeListener::bind(local_loop(), &"path/to/nowhere".to_c_str()) {
|
||||
Ok(*) => fail!(),
|
||||
@ -267,6 +269,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore(cfg(windows))] // FIXME(#10386): how windows pipes work
|
||||
fn bind() {
|
||||
let p = next_test_unix().to_c_str();
|
||||
match PipeListener::bind(local_loop(), &p) {
|
||||
@ -276,6 +279,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test] #[should_fail]
|
||||
#[ignore(cfg(windows))] // FIXME(#10386): how windows pipes work
|
||||
fn bind_fail() {
|
||||
let p = next_test_unix().to_c_str();
|
||||
let _w = PipeListener::bind(local_loop(), &p).unwrap();
|
||||
@ -283,6 +287,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore(cfg(windows))] // FIXME(#10386): how windows pipes work
|
||||
fn connect() {
|
||||
let path = next_test_unix();
|
||||
let path2 = path.clone();
|
||||
@ -308,6 +313,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test] #[should_fail]
|
||||
#[ignore(cfg(windows))] // FIXME(#10386): how windows pipes work
|
||||
fn connect_fail() {
|
||||
let path = next_test_unix();
|
||||
let path2 = path.clone();
|
||||
|
@ -232,6 +232,6 @@ impl Drop for Process {
|
||||
fn drop(&mut self) {
|
||||
let _m = self.fire_homing_missile();
|
||||
assert!(self.to_wake.is_none());
|
||||
self.close_async_();
|
||||
self.close();
|
||||
}
|
||||
}
|
||||
|
@ -30,26 +30,21 @@ pub struct SignalWatcher {
|
||||
impl SignalWatcher {
|
||||
pub fn new(loop_: &mut Loop, signum: Signum,
|
||||
channel: SharedChan<Signum>) -> Result<~SignalWatcher, UvError> {
|
||||
let handle = UvHandle::alloc(None::<SignalWatcher>, uvll::UV_SIGNAL);
|
||||
let s = ~SignalWatcher {
|
||||
handle: UvHandle::alloc(None::<SignalWatcher>, uvll::UV_SIGNAL),
|
||||
home: get_handle_to_current_scheduler!(),
|
||||
channel: channel,
|
||||
signal: signum,
|
||||
};
|
||||
assert_eq!(unsafe {
|
||||
uvll::uv_signal_init(loop_.handle, handle)
|
||||
|
||||
uvll::uv_signal_init(loop_.handle, s.handle)
|
||||
}, 0);
|
||||
|
||||
match unsafe { uvll::uv_signal_start(handle, signal_cb, signum as c_int) } {
|
||||
0 => {
|
||||
let s = ~SignalWatcher {
|
||||
handle: handle,
|
||||
home: get_handle_to_current_scheduler!(),
|
||||
channel: channel,
|
||||
signal: signum,
|
||||
};
|
||||
Ok(s.install())
|
||||
}
|
||||
n => {
|
||||
unsafe { uvll::free_handle(handle) }
|
||||
Err(UvError(n))
|
||||
}
|
||||
match unsafe {
|
||||
uvll::uv_signal_start(s.handle, signal_cb, signum as c_int)
|
||||
} {
|
||||
0 => Ok(s.install()),
|
||||
n => Err(UvError(n)),
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -67,12 +67,27 @@ impl UvHandle<uvll::uv_timer_t> for TimerWatcher {
|
||||
|
||||
impl RtioTimer for TimerWatcher {
|
||||
fn sleep(&mut self, msecs: u64) {
|
||||
let (_m, sched) = self.fire_homing_missile_sched();
|
||||
// As with all of the below functions, we must be extra careful when
|
||||
// destroying the previous action. If the previous action was a channel,
|
||||
// destroying it could invoke a context switch. For these situtations,
|
||||
// we must temporarily un-home ourselves, then destroy the action, and
|
||||
// then re-home again.
|
||||
let missile = self.fire_homing_missile();
|
||||
self.stop();
|
||||
let _missile = match util::replace(&mut self.action, None) {
|
||||
None => missile, // no need to do a homing dance
|
||||
Some(action) => {
|
||||
util::ignore(missile); // un-home ourself
|
||||
util::ignore(action); // destroy the previous action
|
||||
self.fire_homing_missile() // re-home ourself
|
||||
}
|
||||
};
|
||||
|
||||
// If the descheduling operation unwinds after the timer has been
|
||||
// started, then we need to call stop on the timer.
|
||||
let _f = ForbidUnwind::new("timer");
|
||||
|
||||
let sched: ~Scheduler = Local::take();
|
||||
do sched.deschedule_running_task_and_then |_sched, task| {
|
||||
self.action = Some(WakeTask(task));
|
||||
self.start(msecs, 0);
|
||||
@ -87,6 +102,7 @@ impl RtioTimer for TimerWatcher {
|
||||
// of the homing missile
|
||||
let _prev_action = {
|
||||
let _m = self.fire_homing_missile();
|
||||
self.stop();
|
||||
self.start(msecs, 0);
|
||||
util::replace(&mut self.action, Some(SendOnce(chan)))
|
||||
};
|
||||
@ -97,12 +113,11 @@ impl RtioTimer for TimerWatcher {
|
||||
fn period(&mut self, msecs: u64) -> Port<()> {
|
||||
let (port, chan) = stream();
|
||||
|
||||
let _m = self.fire_homing_missile();
|
||||
|
||||
// similarly to the destructor, we must drop the previous action outside
|
||||
// of the homing missile
|
||||
let _prev_action = {
|
||||
let _m = self.fire_homing_missile();
|
||||
self.stop();
|
||||
self.start(msecs, msecs);
|
||||
util::replace(&mut self.action, Some(SendMany(chan)))
|
||||
};
|
||||
@ -236,6 +251,18 @@ mod test {
|
||||
|
||||
timer.oneshot(1);
|
||||
}
|
||||
#[test]
|
||||
fn reset_doesnt_switch_tasks2() {
|
||||
// similar test to the one above.
|
||||
let mut timer = TimerWatcher::new(local_loop());
|
||||
let timer_port = Cell::new(timer.period(1000));
|
||||
|
||||
do spawn {
|
||||
timer_port.take().try_recv();
|
||||
}
|
||||
|
||||
timer.sleep(1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sender_goes_away_oneshot() {
|
||||
|
@ -113,6 +113,6 @@ impl HomingIO for TtyWatcher {
|
||||
impl Drop for TtyWatcher {
|
||||
fn drop(&mut self) {
|
||||
let _m = self.fire_homing_missile();
|
||||
self.close();
|
||||
self.close_async_();
|
||||
}
|
||||
}
|
||||
|
@ -47,14 +47,14 @@ pub static UNKNOWN: c_int = -4094;
|
||||
pub mod errors {
|
||||
use std::libc::c_int;
|
||||
|
||||
pub static EACCES: c_int = -4093;
|
||||
pub static ECONNREFUSED: c_int = -4079;
|
||||
pub static ECONNRESET: c_int = -4078;
|
||||
pub static ENOTCONN: c_int = -4054;
|
||||
pub static EPIPE: c_int = -4048;
|
||||
pub static ECONNABORTED: c_int = -4080;
|
||||
pub static ECANCELED: c_int = -4082;
|
||||
pub static EBADF: c_int = -4084;
|
||||
pub static EACCES: c_int = -4092;
|
||||
pub static ECONNREFUSED: c_int = -4078;
|
||||
pub static ECONNRESET: c_int = -4077;
|
||||
pub static ENOTCONN: c_int = -4053;
|
||||
pub static EPIPE: c_int = -4047;
|
||||
pub static ECONNABORTED: c_int = -4079;
|
||||
pub static ECANCELED: c_int = -4081;
|
||||
pub static EBADF: c_int = -4083;
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
pub mod errors {
|
||||
@ -87,19 +87,19 @@ pub static STDIO_WRITABLE_PIPE: c_int = 0x20;
|
||||
#[cfg(unix)]
|
||||
pub type uv_buf_len_t = libc::size_t;
|
||||
#[cfg(windows)]
|
||||
pub type uv_buf_len_t = u32;
|
||||
pub type uv_buf_len_t = libc::c_ulong;
|
||||
|
||||
// see libuv/include/uv-unix.h
|
||||
#[cfg(unix)]
|
||||
pub struct uv_buf_t {
|
||||
base: *u8,
|
||||
len: libc::size_t,
|
||||
len: uv_buf_len_t,
|
||||
}
|
||||
|
||||
// see libuv/include/uv-win.h
|
||||
#[cfg(windows)]
|
||||
pub struct uv_buf_t {
|
||||
len: u32,
|
||||
len: uv_buf_len_t,
|
||||
base: *u8,
|
||||
}
|
||||
|
||||
@ -544,7 +544,19 @@ pub unsafe fn guess_handle(handle: c_int) -> c_int {
|
||||
|
||||
|
||||
// uv_support is the result of compiling rust_uv.cpp
|
||||
//
|
||||
// Note that this is in a cfg'd block so it doesn't get linked during testing.
|
||||
// There's a bit of a conundrum when testing in that we're actually assuming
|
||||
// that the tests are running in a uv loop, but they were created from the
|
||||
// statically linked uv to the original rustuv crate. When we create the test
|
||||
// executable, on some platforms if we re-link against uv, it actually creates
|
||||
// second copies of everything. We obviously don't want this, so instead of
|
||||
// dying horribly during testing, we allow all of the test rustuv's references
|
||||
// to get resolved to the original rustuv crate.
|
||||
#[link_args = "-luv_support -luv"]
|
||||
#[cfg(not(test))]
|
||||
extern {}
|
||||
|
||||
extern {
|
||||
fn rust_uv_loop_new() -> *c_void;
|
||||
|
||||
|
@ -33,7 +33,8 @@ use result::{Ok, Err};
|
||||
use rt::io::buffered::LineBufferedWriter;
|
||||
use rt::rtio::{IoFactory, RtioTTY, RtioFileStream, with_local_io,
|
||||
CloseAsynchronously};
|
||||
use super::{Reader, Writer, io_error, IoError, OtherIoError};
|
||||
use super::{Reader, Writer, io_error, IoError, OtherIoError,
|
||||
standard_error, EndOfFile};
|
||||
|
||||
// And so begins the tale of acquiring a uv handle to a stdio stream on all
|
||||
// platforms in all situations. Our story begins by splitting the world into two
|
||||
@ -203,6 +204,15 @@ impl Reader for StdReader {
|
||||
File(ref mut file) => file.read(buf).map(|i| i as uint),
|
||||
};
|
||||
match ret {
|
||||
// When reading a piped stdin, libuv will return 0-length reads when
|
||||
// stdin reaches EOF. For pretty much all other streams it will
|
||||
// return an actual EOF error, but apparently for stdin it's a
|
||||
// little different. Hence, here we convert a 0 length read to an
|
||||
// end-of-file indicator so the caller knows to stop reading.
|
||||
Ok(0) => {
|
||||
io_error::cond.raise(standard_error(EndOfFile));
|
||||
None
|
||||
}
|
||||
Ok(amt) => Some(amt as uint),
|
||||
Err(e) => {
|
||||
io_error::cond.raise(e);
|
||||
|
@ -142,14 +142,10 @@ mod test {
|
||||
fn oneshot_twice() {
|
||||
do run_in_mt_newsched_task {
|
||||
let mut timer = Timer::new().unwrap();
|
||||
let port1 = timer.oneshot(100000000000);
|
||||
let port1 = timer.oneshot(10000);
|
||||
let port = timer.oneshot(1);
|
||||
port.recv();
|
||||
let port1 = Cell::new(port1);
|
||||
let ret = do task::try {
|
||||
port1.take().recv();
|
||||
};
|
||||
assert!(ret.is_err());
|
||||
assert_eq!(port1.try_recv(), None);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit c6ecf97aafc858c2ad1089fb78da6c586d61d8b6
|
||||
Subproject commit 7ac7e0248b34732e9963cdb8e31f7e612d23d14b
|
Loading…
x
Reference in New Issue
Block a user