Skip to content

Commit 309265a

Browse files
vvukantrik
authored andcommitted
Implement ipc-channel on Windows
This implementation uses named pipes on Windows, with auto-generated uuid names. It takes advantage of DuplicateHandle to clone handles to target processes when sending handles cross-process. Shared memory is implemented using anonymous file mappings. select() and friends are implemented using IO Completion Ports.
1 parent 0480579 commit 309265a

File tree

6 files changed

+1538
-21
lines changed

6 files changed

+1538
-21
lines changed

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ repository = "https://github.com/servo/ipc-channel"
1010
force-inprocess = []
1111
memfd = ["syscall"]
1212
unstable = []
13+
win32-trace = []
1314

1415
[dependencies]
1516
bincode = "0.8"
@@ -27,3 +28,7 @@ syscall = { version = "0.2.1", optional = true }
2728

2829
[dev-dependencies]
2930
crossbeam = "0.2"
31+
32+
[target.'cfg(target_os = "windows")'.dependencies]
33+
winapi = "0.2"
34+
kernel32-sys = "0.2"

src/lib.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// option. This file may not be copied, modified, or distributed
88
// except according to those terms.
99

10-
#![cfg_attr(any(feature = "force-inprocess", target_os = "windows", target_os = "android"),
10+
#![cfg_attr(any(feature = "force-inprocess", target_os = "android"),
1111
feature(mpsc_select))]
1212
#![cfg_attr(all(feature = "unstable", test), feature(specialization))]
1313

@@ -18,6 +18,7 @@ extern crate bincode;
1818
extern crate libc;
1919
extern crate rand;
2020
extern crate serde;
21+
2122
#[cfg(any(feature = "force-inprocess", target_os = "windows", target_os = "android"))]
2223
extern crate uuid;
2324
#[cfg(all(not(feature = "force-inprocess"), any(target_os = "linux",
@@ -32,6 +33,11 @@ extern crate fnv;
3233
extern crate syscall;
3334

3435

36+
#[cfg(all(not(feature = "force-inprocess"), target_os = "windows"))]
37+
extern crate winapi;
38+
#[cfg(all(not(feature = "force-inprocess"), target_os = "windows"))]
39+
extern crate kernel32;
40+
3541
pub mod ipc;
3642
pub mod platform;
3743
pub mod router;

src/platform/mod.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,16 @@ mod os {
4343
pub use super::macos::*;
4444
}
4545

46-
#[cfg(any(feature = "force-inprocess", target_os = "windows", target_os = "android"))]
46+
#[cfg(all(not(feature = "force-inprocess"), target_os = "windows"))]
47+
mod windows;
48+
#[cfg(all(not(feature = "force-inprocess"), target_os = "windows"))]
49+
mod os {
50+
pub use super::windows::*;
51+
}
52+
53+
#[cfg(any(feature = "force-inprocess", target_os = "android"))]
4754
mod inprocess;
48-
#[cfg(any(feature = "force-inprocess", target_os = "windows", target_os = "android"))]
55+
#[cfg(any(feature = "force-inprocess", target_os = "android"))]
4956
mod os {
5057
pub use super::inprocess::*;
5158
}

src/platform/test.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ use std::sync::Arc;
1414
use std::time::{Duration, Instant};
1515
use std::thread;
1616

17-
#[cfg(not(any(feature = "force-inprocess", target_os = "windows", target_os = "android")))]
17+
#[cfg(not(any(feature = "force-inprocess", target_os = "android")))]
1818
use libc;
1919
use platform::{OsIpcSender, OsIpcOneShotServer};
2020
#[cfg(not(any(feature = "force-inprocess", target_os = "windows", target_os = "android")))]
2121
use libc::{kill, SIGSTOP, SIGCONT};
2222
#[cfg(not(any(feature = "force-inprocess", target_os = "windows", target_os = "android")))]
2323
use test::{fork, Wait};
24-
#[cfg(not(any(feature = "force-inprocess", target_os = "windows", target_os = "android")))]
24+
#[cfg(not(any(feature = "force-inprocess", target_os = "android")))]
2525
use test::{get_channel_name_arg, spawn_server};
2626

2727
#[test]
@@ -200,7 +200,8 @@ fn with_n_fds(n: usize, size: usize) {
200200

201201
// These tests only apply to platforms that need fragmentation.
202202
#[cfg(all(not(feature = "force-inprocess"), any(target_os = "linux",
203-
target_os = "freebsd")))]
203+
target_os = "freebsd",
204+
target_os = "windows")))]
204205
mod fragment_tests {
205206
use platform;
206207
use super::with_n_fds;
@@ -648,7 +649,7 @@ fn server_connect_first() {
648649
(data, vec![], vec![]));
649650
}
650651

651-
#[cfg(not(any(feature = "force-inprocess", target_os = "windows", target_os = "android")))]
652+
#[cfg(not(any(feature = "force-inprocess", target_os = "android")))]
652653
#[test]
653654
fn cross_process_spawn() {
654655
let data: &[u8] = b"1234567";
@@ -689,7 +690,7 @@ fn cross_process_fork() {
689690
(data, vec![], vec![]));
690691
}
691692

692-
#[cfg(not(any(feature = "force-inprocess", target_os = "windows", target_os = "android")))]
693+
#[cfg(not(any(feature = "force-inprocess", target_os = "android")))]
693694
#[test]
694695
fn cross_process_sender_transfer_spawn() {
695696
let channel_name = get_channel_name_arg("server");
@@ -916,10 +917,16 @@ mod sync_test {
916917
}
917918
}
918919

919-
// TODO -- this fails on OSX with a MACH_SEND_INVALID_RIGHT!
920-
// Needs investigation.
921-
#[cfg(not(any(feature = "force-inprocess", target_os = "windows", target_os = "android")))]
922-
#[cfg_attr(target_os = "macos", ignore)]
920+
// This test panics on Windows, because the other process will panic
921+
// when it detects that it receives handles that are intended for another
922+
// process. It's marked as ignore/known-fail on Windows for this reason.
923+
//
924+
// TODO -- this fails on OSX as well with a MACH_SEND_INVALID_RIGHT!
925+
// Needs investigation. It may be a similar underlying issue, just done by
926+
// the kernel instead of explicitly (ports in a message that's already
927+
// buffered are intended for only one process).
928+
#[cfg(not(any(feature = "force-inprocess", target_os = "android")))]
929+
#[cfg_attr(any(target_os = "windows", target_os = "macos"), ignore)]
923930
#[test]
924931
fn cross_process_two_step_transfer_spawn() {
925932
let cookie: &[u8] = b"cookie";

0 commit comments

Comments
 (0)