-
Notifications
You must be signed in to change notification settings - Fork 131
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
Implement ipc-channel on Windows #108
Conversation
af63d10
to
686f358
Compare
Cargo.toml
Outdated
[target.'cfg(target_os = "windows")'.dependencies] | ||
winapi = "*" | ||
user32-sys = "*" | ||
kernel32-sys = "*" |
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.
Uh... Aren't wildcard dependencies considered evil?
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.
Yeah, remove the wildcard dependencies. crates.io will reject them.
Great work! Before starting a proper review, I'd ask you to actually test Servo first though, to avoid extra effort in case further changes turn out necessary... BTW, you could also try running the benchmarks. While these are not really intended to test functionality, the extra coverage can't hurt -- and it would actually be interesting to see how this implementation stacks up against the others... You could in fact include the results in the commit message, so we get an idea as well :-) |
Ok, I'll admit, I forgot that 32-bit was a thing that existed. I'll fix that up D: Servo worked first time around in non-multiprocess mode (using the Windows channels). In multiprocess mode (with modifications to constellation that I'm going to put in a PR), I get a panic about some subchannel data that I'm going to debug. But I think we can start reviews and even landing, and keep non-multiprocess as the default until that's tracked down in parallel. Benchmark results below -- I don't have linux/OSX running on the same hardware so I can't compare directly, but this is on a Core i7-4770K. I haven't done any performance work or even profiling on it, so there's probably some easy wins.
|
@vvuk it's on my list... Sorry for being slow :-( |
No problem! Just making sure it wasn't blocked on anything. On Oct 13, 2016 9:28 AM, "Olaf Buddenhagen" notifications@github.com
|
src/platform/windows/mod.rs
Outdated
static ref DD_ENABLED: bool = match env::var_os("DD") { | ||
Some(_) => true, | ||
None => false, | ||
}; |
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 can just be env::var_os("DD").is_some()
src/platform/windows/mod.rs
Outdated
static ref DD2_ENABLED: bool = match env::var_os("DD2") { | ||
Some(_) => true, | ||
None => false, | ||
}; |
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.
Likewise
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 not an IOCP expert so I'll defer to @antrik for that, but I just had a few nits.
Very glad to see that this actually works in Win32 :)
src/platform/windows/mod.rs
Outdated
// When we create the pipe, how big of a write buffer do we specify? | ||
// This is reserved in the nonpaged pool. | ||
// | ||
// This is 80k because a lot of the test assume that we can write a |
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.
uber-nit: "tests"
src/platform/windows/mod.rs
Outdated
|
||
// if the remote end closed... | ||
if err != winapi::ERROR_SUCCESS { | ||
panic!("[$ {:?}:{:?}] *** notify_completion: need to handle error! {}", self.iocp, self.handle, err); |
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 guess add a FIXME
here?
src/platform/windows/mod.rs
Outdated
let more = | ||
if buf_cap == 0 { READ_BUFFER_SIZE } | ||
else if buf_cap < READ_BUFFER_MAX_GROWTH { buf_cap } | ||
else { READ_BUFFER_MAX_GROWTH }; |
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 be:
match buf_cap {
0 => READ_BUFFER_SIZE,
1...READ_BUFFER_MAX_GROWTH => buf_cap,
_ => READ_BUFFER_MAX_GROWTH,
}
src/platform/windows/mod.rs
Outdated
|
||
// Err(false) -> something really failed | ||
// Err(true) -> no message | ||
// XXX This is dumb, we should return |
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.
nit: use FIXME
src/platform/windows/mod.rs
Outdated
return Ok(()); | ||
} | ||
let mut nwritten: u32 = 0; | ||
//dd!("[c {:?}] writing: {:?}", handle, bytes); |
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.
Uncomment or remove
src/platform/windows/mod.rs
Outdated
} | ||
nwritten += nwrote; | ||
ntowrite -= nwrote; | ||
//dd!("[c {:?}] ... wrote {} bytes, total {}/{} err {}", handle, nwrote, nwritten, bytes.len(), GetLastError()); |
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.
Ditto
src/platform/windows/mod.rs
Outdated
}); | ||
|
||
// if we had prematurely closed elements, just process them first | ||
if selection_results.len() > 0 { |
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.
(BTW, there is .is_empty()
if you'd like to use it for stuff like this; up to you)
src/platform/windows/mod.rs
Outdated
// function call itself failed or timed out. | ||
// Otherwise, the async IO operation failed, and | ||
// we want to hand io_err to notify_completion below. | ||
if ov_ptr == ptr::null_mut() { |
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 be .is_null()
src/platform/windows/mod.rs
Outdated
|
||
impl From<WinError> for Error { | ||
fn from(mpsc_error: WinError) -> Error { | ||
//Error::new(ErrorKind::Other, format!("Win channel error ({} from {})", mpsc_error.0, mpsc_error.1)) |
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.
Uncomment or remove
src/platform/windows/mod.rs
Outdated
// if the buffer is full, add more space | ||
let buf_len = self.read_buf.len(); | ||
let mut buf_cap = self.read_buf.capacity(); | ||
if buf_cap == buf_len { |
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.
nit: could do
if buf_cap == buf_len {
return
}
and save a level of indentation
Awesome, thanks! Will look in detail later, but I like the nits - I'm still About the debug output - I was going to strip that, but I think I'll clean On Oct 13, 2016 6:08 PM, "Patrick Walton" notifications@github.com wrote:
|
I put in a fixme comment for this, but -- do I need to protect against simultaneous |
Fixed the issue that was causing a problem with servo. With these fixes, multiprocess servo runs on Windows. |
@vvuk when you find an issue that was not caught by the test suite, can you please try to create a new test case to cover it?... Regarding your question about concurrent |
Regarding the benchmark results, these do not look too bad indeed. For comparison, here is what I get from a typical run on my (somewhat old) 32 bit GNU/Linux system:
I once did a few runs on a more modern system, which was about as fast as yours I guess. While I haven't published the results, IIRC they were mostly about 2 - 2.5x faster than the ones you get; except for medium sizes (around 128k - 512k or so), where the Linux implementation suffers less severely from fragmentation. (Even less on the modern system.) Channel creation also looks significantly faster on Linux. From a quick glance, it looks like you do shuffle data around quite a bit in the Does Windows have a simple way to see how much time is spent in system calls vs. userspace code (like the |
@vvuk it seems you accidentally dropped the "Fix win32 nits" commit while pushing further changes?... |
Whoops. Quite. And re the tests -- in my hurry I convinced myself that there weren't already cross-process tests, but that's very dumb. They were if cfg'd out. They do use fork() unfortunately, which won't work on Windows, but I'll make them work tomorrow and clean up the branch a bit. |
Any ideas on how I can build a second binary that the tests will depend on? Or, alternatively, a way to give the test binary itself main() or something where I can control the args? |
You can see an example here: https://github.com/servo/html5ever/blob/master/Cargo.toml |
That's better. Any final comments, and do you want to see this squashed? |
@vvuk I'm still in the process of looking through the code (I'm trying to be thorough); but squashing is fine with me, as I haven't looked at the earlier version much, so I don't need to see what changed in the fix-up commits. (The include change and the new test cases should remain separate commits, of course.) |
@vvuk I think you can make a Let me see if I find an example in the Servo repos. On Fri, Oct 21, 2016 at 10:38:20AM -0700, Vladimir Vukicevic wrote:
|
☔ The latest upstream changes (presumably #102) made this pull request unmergeable. Please resolve the merge conflicts. |
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.
So, uh... This is a shitload of questions, nitpicks, and assorted other remarks... Sorry for that: since I'm horribly perfectionist, I tend to comment an important things an minor details alike -- I hope you don't mind too much :-)
My major concern with this implementation is that sending descriptors along with data is not atomic, which I fear might cause serious problems... But I don't know whether a different approach is possible, since I actually have no clue about Windows programming. Maybe we need to summon a domain wizard? ;-)
Other than that, there are few other points that I'd consider quite important, though less fundamental -- while a lot of the remaining remarks are rather stylistic issues, which you might or might not agree with :-) (Though I'd love to hear what @pcwalton and others think of them...)
src/platform/mod.rs
Outdated
#[cfg(any(feature = "force-inprocess", target_os = "android"))] | ||
pub use self::inprocess::{OsIpcChannel, OsIpcOneShotServer, OsIpcReceiver, | ||
OsIpcReceiverSet, OsIpcSelectionResult, OsIpcSender, | ||
OsIpcSharedMemory, OsOpaqueIpcChannel, channel}; |
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 makes it more similar again in some ways to what it was before b3386e3 . Can you please explain why you consider this an improvement?...
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.
Without it, it's impossible to debug without doing a -Z debug-macros
build -- all code goes to the include!()
statement (see rust-lang/rust#36382).
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.
Ugh, I see...
Why don't you just do pub use self::inprocess::*
etc. though?
Also, this should be a separate PR I'd say?...
} | ||
|
||
unsafe impl Send for WinHandle { } | ||
unsafe impl Sync for WinHandle { } |
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 take it the Windows API guarantees thread safety when using HANDLE
s, i.e. running several system calls on the same HANDLE
at the same time will never ever trigger undefined behaviour?
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.
They are, though obviously what you do with them has to make sense in a multi-threading context.
src/platform/windows/mod.rs
Outdated
} | ||
|
||
unsafe impl Send for OsIpcReceiver { } | ||
unsafe impl Sync for OsIpcReceiver { } |
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 explicit Send
declaration should not be necessary: as far as I can see, all the types used in this structure are automatically Send
.
It's quite a different story for Sync
though: since reader
is a RefCell
, which is not Sync
, the containing structure isn't automatically Sync
either -- and for good reasons, too! While I haven't tried understanding the implications 100%, it seems to me that attempting concurrent recv()
calls would indeed race wildly with the current implementation... To actually make this thread-safe, you'd need to use some kind of mutex I guess.
In this specific case however you do not need to do this; but rather just drop the Sync
claim: OsIpcReceiver
should indeed not be Sync
!
(There was a bug about this in the inprocess
back-end -- see #107 )
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.
HANDLE
is neither Send
nor Sync
, which is still incredibly annoying. This needs to be marked Send
. Should not be Sync
, as you say.
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.
Oh right, I forgot that you do have a raw HANDLE
in there... Though as explained above, I think it would be better to get rid of it -- this is just one more reason :-)
src/platform/windows/mod.rs
Outdated
} | ||
|
||
unsafe impl Send for OsIpcSender { } | ||
unsafe impl Sync for OsIpcSender { } |
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 need to declare these explicitly -- it will automatically inherit these properties from the inner type.
(Actually, I even believe the ipc-channel
senders should not be Sync
at all, just as the mpsc
senders aren't -- but that will have to happen separately as a major API change...)
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 guess you have seen that I went ahead with this change in #115 ...
src/platform/windows/mod.rs
Outdated
unsafe { | ||
if self.handle.is_valid() { | ||
kernel32::UnmapViewOfFile(self.ptr as LPVOID); | ||
} |
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 don't know whether the descriptor is actually relevant for removing the mapping; but regardless, this condition seems weird: as far as I can see, there is no valid way to create or leave behind an OsIpcSharedMemory
object without a valid descriptor? I'd say this should be an assert()
at most...
src/platform/windows/mod.rs
Outdated
} | ||
|
||
impl From<WinError> for DeserializeError { | ||
fn from(mpsc_error: WinError) -> DeserializeError { |
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 you want win_error
here, not mpsc_error
:-)
src/platform/windows/mod.rs
Outdated
|
||
impl From<WinError> for Error { | ||
fn from(mpsc_error: WinError) -> Error { | ||
Error::new(ErrorKind::Other, format!("Win channel error ({}=0x{:x})", mpsc_error.0, mpsc_error.0)) |
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.
Now that is very lazy :-P
It seems to me that you should special-case "channel closed" at the very least, like the mpsc
back-end does.
Also, as far as I can see you should be able to use from_raw_os_error()
for the real system error codes, just like the unix
back-end?...
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 didn't actually know how Error::from_raw_os_error and friends worked :) Fixed
src/platform/windows/mod.rs
Outdated
|
||
// A pipe_id; if None, then this isn't a named | ||
// pipe server (or is no longer one), and accept() will fail | ||
pipe_id: Option<Uuid>, |
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.
See my remark about sender
above: I don't think this really belongs here...
src/platform/windows/mod.rs
Outdated
} | ||
|
||
impl From<WinError> for Error { | ||
fn from(mpsc_error: WinError) -> Error { |
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.
Ditto.
src/platform/windows/mod.rs
Outdated
} | ||
|
||
pub fn get_max_fragment_size() -> usize { | ||
MAX_FRAGMENT_SIZE |
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.
Only having a lower bound here is a bit unfortunate, as some of the test cases rely on the precise amount for testing corner cases... (I was actually considering a scheme where this method would take the OOB item counts, in order to dynamically calculate the exact value -- before I realised that for the unix
implementation this is actually orthogonal...)
Having said that, since this implementation works quite a bit differently, I'm not sure how relevant these particular corner cases actually are here...
So, the non-atomic writes due to the header are definitely an issue, and I somehow managed to completely gloss over that. I'm going to write a test for that first and then probably need to memcpy the send data buffer unless it gets fragmented. |
Seems like the only missing bit to land this is a rebase? |
@emilio I'm very ashamed to say that I still haven't managed to finish going through the reworked code... |
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 finally managed to look though the newest code -- sorry it took so long again...
The good news is that I didn't find any new fundamental problems :-) I did find a few issues I consider pretty important (so at least the extra delay wasn't useless...) -- but these should all be pretty easy to fix without any major changes I believe...
I like the various improvements you did very much -- including those that do not seem to be in direct response to my comments :-)
It's a bit unfortunate that you squashed the test additions together with the new back-end implementation -- since the tests are actually independent of the new platform, I usually prefer them in a separate commit before the main one. (And only adding platform-specific conditionals in the main commit.) Not a serious problem though I'd say.
static ref DEBUG_TRACE_ENABLED: bool = { env::var_os("IPC_CHANNEL_WIN_DEBUG_TRACE").is_some() }; | ||
} | ||
|
||
// some debug bump macros to better track what's going on in case of errors |
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.
Nitpick: still got that typo here... ("bump" should be "dump".)
// passing, though that process would need to be global to any processes | ||
// amongst which you want to share channels or connect one-shot servers to. | ||
// There may be a system process that we could use for this purpose, but | ||
// I haven't foundone -- and in the system process case, we'd need to ensure |
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.
Nitpick: "foundone"
} | ||
|
||
// duplicate a handle to the target process, closing the source handle | ||
fn move_handle_to_process(handle: &mut WinHandle, other_process: &WinHandle) -> Result<WinHandle,WinError> { |
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 wonder whether handle
could be passed by value here? If so, it would make it more explicit that it's actually consumed...
(But even then, it's not a deal-breaker -- just a missed opportunity ;-) )
// FIXME this is not correct! We need to compare the object | ||
// the handles refer to. On Windows 10, we have: | ||
// unsafe { kernel32::CompareObjectHandles(self.h, other.h) == winapi::TRUE } | ||
// But that |
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.
Seems the comment got truncated?...
} | ||
|
||
enum GetMessageResult { | ||
NoMessage, |
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.
Nitpick: there is trailing white space on this line.
(Git should give you a warning about this on commit I believe?... Or at least git diff
displays such errors prominently if coloured output is enabled.)
// We limit the max size we can send here; we can fix this | ||
// just by upping the header to be 2x u64 if we really want | ||
// to. | ||
assert!(data.len() < u32::max_value() as 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.
Shouldn't that be <=
?
|
||
unsafe { | ||
let in_band_data_len = if big_data_sender.is_none() { data.len() } else { 0 }; | ||
let full_in_band_len = MessageHeader::size() + in_band_data_len + oob_data.len(); |
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.
These do not need to be inside the unsafe
block, since the buffer is dereferenced safely (through slices) in the following code -- so a miscalculation here could cause a panic at worst.
(Not entirely sure about the following assert... What is the worst that could happen if the pipe buffer size is exceeded?)
impl Drop for OsIpcSharedMemory { | ||
fn drop(&mut self) { | ||
unsafe { | ||
kernel32::UnmapViewOfFile(self.ptr as LPVOID); |
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 we need to check for errors here?
(Conditionally, to avoid double panics -- see Unix implementation for reference...)
fn new(length: usize) -> Result<OsIpcSharedMemory,WinError> { | ||
unsafe { | ||
assert!(length < u32::max_value() as usize); | ||
let (lhigh, llow) = (0 as u32, (length & 0xffffffffusize) as u32); |
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 fear there must have been some kind of misunderstanding here? We certainly do not want to limit the size of mappings to 32 bits -- I just said that there is no need to special-case for 32 bit systems, since the bit shift for lhigh
naturally produces the correct effect with #[allow(exceeding_bitshifts)]
...
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 read up on the exceeding bitshifts situation (ugh); and I see now that we do indeed need some kind of explicit handling here -- sorry for this.
Still, I think the original approach with #[allow(exceeding_bitshifts)]
was pretty fragile and confusing. I'd vote for more explicit conditional compilation, like this:
#[cfg(target_pointer_width = "64")]
let (lhigh, llow) = ((length >> 32) as u32, (length & 0xffffffff) as u32);
#[cfg(target_pointer_width = "32")]
let (lhigh, llow) = (0, length as u32);
As an additional advantage, if we ever encounter a different pointer size, this will fail at compile time, rather than producing something unexpected. (Might be a hypothetical case -- but better safe than sorry...)
Yet another option is using checked_shr()
:
let (lhigh, llow) = (length.checked_shr(32).unwrap_or(0) as u32, (length & 0xffffffff) as u32);
This seems the simplest and cleanest option by far. It might result in a branch being performed at run time, unless the compiler is smart enough to elide it -- but the overhead should be insignificant (especially since it's a predictable branch); and I'd say the simplification justifies it...
match *self { | ||
WinError::ChannelClosed => true, | ||
_ => false, | ||
} |
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.
If you derive PartailEq
on WinError
, you could just use an ordinary comparison here, like in the inprocess
back-end.
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.
… due to Mach error
c36049a
to
1b014ce
Compare
Hey all, just curious what the state of this PR is? It looks like @antrik's feedback was addressed and the PR was rebased. I could carry this PR across the finish line if there's something else needed - this is something we need in the habitat project and I'd love to get it out of the way. Appreciate all the hard work that's gone into this PR both in the code and the review! |
@reset great to see other users of I hadn't seen the latest update. However, unless I'm missing something, it doesn't seem to address my latest review at all?... Admittedly, many of these remarks are nitpicks, that I only brought up for completeness, and probably wouldn't have mentioned if there was nothing else to warrant commenting. Another batch however are code robustness concerns, which are (hopefully) not actual bugs right now -- but bearing a risk of producing soundness issues when related code is modified in the future... Personally, I'm not very comfortable committing such things. Last but not least, I believe there are a few genuine (though admittedly minor) defects. None of these are real show-stoppers -- if someone decides to merge as is (after squashing), I wouldn't be outraged... Only somewhat disappointed ;-) As these are all pretty straightforward to fix I believe, it would be a pity IMHO not to do so... Frankly, since they seem so straightforward to me, I'm seriously considering just making the changes myself... My only concern is that if I don't get it right on the first try, it would be pretty much impossible for me to debug it, without actually having a Windows system at hand. |
You're right, there was so much content here that I assumed the last push
addressed your remarks. I'm very ok with doing that work as well if you're
busy!
Super grateful that you all did all this work already. We are about to make
a largish change to our process supervisor and need the IPC channel for all
three platforms. Thank you so much for all this work!
Let me know if you'd like me to do the cleanup or if you'll handle it.
Either way is very cool with me!
…On Sat, May 27, 2017 at 2:10 PM Olaf Buddenhagen ***@***.***> wrote:
@reset <https://github.com/reset> great to see other users of ipc-channel
beside Servo itself :-)
I hadn't seen the latest update. However, unless I'm missing something, it
doesn't seem to address my latest review at all?...
Admittedly, many of these remarks are nitpicks, that I only brought up for
completeness, and probably wouldn't have mentioned if there was nothing
else to warrant commenting. Another batch however are code robustness
concerns, which are (hopefully) not actual bugs right now -- but bearing a
risk of producing soundness issues when related code is modified in the
future... Personally, I'm not very comfortable committing such things. Last
but not least, I believe there are a few genuine (though admittedly minor)
defects.
None of these are real show-stoppers -- if someone decides to merge as is
(after squashing), I wouldn't be outraged... Only somewhat disappointed ;-)
As these are all pretty straightforward to fix I believe, it would be a
pity IMHO not to do so...
Frankly, since they seem so straightforward to me, I'm seriously
considering just making the changes myself... My only concern is that if I
don't get it right on the first try, it would be pretty much impossible for
me to debug it, without actually having a Windows system at hand.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#108 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AADTFA0rg7NKxGk7M69CkFdZ4EjTY5dtks5r-JFKgaJpZM4KOU0X>
.
|
Jamie, I'm happy to help as well with advice etc - my feeling here was that
it was in good enough shape to merge, perhaps with a note saying that there
are some outstanding issues and maybe a non-default feature and then fix up
issues as they come up over time instead of blocking the bulk of the work.
I just can't commit to doing the rest of the work at this point.
I'll double check my laptop to make sure I don't have any outstanding work
here and make sure my win32 branch is up to date.
|
@reset thanks for the offer -- though TBH, most of the time I'm not really all that busy, but rather distracted... Since I have already thought about this stuff a lot, and know exactly what I'm after, I think it would probably be more efficient if I give it a try myself first, and only ask for assistance if I need help debugging?... If however I fail to follow up within a week or so, feel free to push for this being merged as-is (after squashing), and/or to pick up from here yourself. (BTW, does anyone happen to know whether there is a simple way to "cargo check" for a different target platform?...) |
That sounds great to me @antrik. I'll follow up in about a week or so! There's no |
I created a new WIP PR in #166 . It doesn't actually contain the proposed code changes yet; however, it refactors the original commits -- which should make it a better starting point for further work, and/or final merging. (Also, leaving behind the giant existing discussion thread here, should reduce incidents of angry unicorn...) |
☔ The latest upstream changes (presumably #167) made this pull request unmergeable. Please resolve the merge conflicts. |
@antrik the Habitat project has been using this branch to get Windows support since late May/early June without a hitch. We'd love to be able to receive updates from master but we're on this branch until it's merged. I'd love to help see this over the finish line or at the very least push up some changes which fix the conflicting files so we can branch this branch and maintain a separate master branch until this is merged in. @antrik would you be alright with that or do you want me to hold off? |
@reset I've been working on this on-and-off over the past months -- making improvements, as well as rebasing on master regularly -- over in #166 ; in fact I made some pretty good progress just recently :-) The top commit in this branch is often broken though, since I'm trying new stuff I can't test locally... However, it would be easy for me to maintain a separate BTW, I'd prefer all new discussion to happen in #166 (not least because my browser seriously struggles with this overly long discussion thread...) -- in fact, it would probably be best to close this obsolete PR now in favour of the active one... |
Let's go ahead and close this, in that case. |
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. I learned a lot about Windows IO doing this, more than I wanted to :)
All the current tests pass. I have not tried actually running servo with multiprocess ipc -- that's next, but I wanted to get this up for review first. There's a branch (win32-unsquashed) that has a large sequence of commits that led to this, in case that's interesting to anyone... it contains a couple of abandoned approaches early on though.