Skip to content

Commit 5cbd305

Browse files
committed
some current process/handle cleanup, use lazy statics for a number of variables
1 parent f14cb31 commit 5cbd305

File tree

1 file changed

+44
-7
lines changed

1 file changed

+44
-7
lines changed

src/platform/windows/mod.rs

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ use winapi::{HANDLE, INVALID_HANDLE_VALUE, LPVOID};
3232
use kernel32;
3333

3434
lazy_static! {
35+
static ref CURRENT_PROCESS_ID: winapi::ULONG = unsafe { kernel32::GetCurrentProcessId() };
36+
static ref CURRENT_PROCESS_HANDLE: intptr_t = unsafe { kernel32::GetCurrentProcess() as intptr_t };
37+
3538
static ref DD_ENABLED: bool = match env::var_os("DD") {
3639
Some(_) => true,
3740
None => false,
@@ -181,7 +184,7 @@ fn dup_handle_to_process_with_flags(handle: HANDLE, other_process: HANDLE, flags
181184

182185
unsafe {
183186
let mut new_handle: HANDLE = INVALID_HANDLE_VALUE;
184-
let ok = kernel32::DuplicateHandle(kernel32::GetCurrentProcess(), handle,
187+
let ok = kernel32::DuplicateHandle(*CURRENT_PROCESS_HANDLE as HANDLE, handle,
185188
other_process, &mut new_handle,
186189
0, winapi::FALSE, flags);
187190
if ok == winapi::FALSE {
@@ -276,6 +279,7 @@ impl WinHandle {
276279
WinHandle { h: h }
277280
}
278281

282+
#[allow(dead_code)]
279283
fn invalid() -> WinHandle {
280284
WinHandle { h: INVALID_HANDLE_VALUE }
281285
}
@@ -436,7 +440,7 @@ impl MessageReader {
436440
return Ok(());
437441
}
438442

439-
Err(WinError::last("ReadFile"))
443+
Err(WinError::from_system(err, "ReadFile"))
440444
} else {
441445
self.read_in_progress = true;
442446
Ok(())
@@ -498,6 +502,11 @@ impl MessageReader {
498502
assert!(msg.channel_is_sender.len() == msg.channel_handles.len());
499503
assert!(msg.shmem_sizes.len() == msg.shmem_handles.len());
500504

505+
dd2!("[$ {:?}:{:?}] msg with total {} bytes, {} channels, {} shmems, big data handle 0x{:x}",
506+
self.iocp, self.handle, data_bytes,
507+
msg.channel_handles.len(), msg.shmem_handles.len(),
508+
msg.big_data_receiver_handle);
509+
501510
for (handle, is_sender) in msg.channel_handles.iter().zip(msg.channel_is_sender.iter()) {
502511
channels.push(OsOpaqueIpcChannel::new(*is_sender, *handle as HANDLE));
503512
}
@@ -507,8 +516,9 @@ impl MessageReader {
507516
}
508517

509518
if msg.big_data_receiver_handle != 0 {
519+
dd2!("[$ {:?}:{:?}] read msg with big data, rec handle {:?}", self.iocp, self.handle, msg.big_data_receiver_handle as HANDLE);
510520
let receiver = OsIpcReceiver::from_handle(msg.big_data_receiver_handle as HANDLE);
511-
let big_msg = try!(receiver.recv().map_err(|_| panic!("Failed to receive subchannel big data")));
521+
let big_msg = try!(receiver.recv().map_err(|err| panic!("Failed to receive subchannel big data: {:?}", err)));
512522
buf_data = big_msg.0;
513523
}
514524
}
@@ -561,6 +571,8 @@ impl Drop for OsIpcReceiver {
561571
}
562572

563573
impl OsIpcReceiver {
574+
// We can't just use an anonymous pipe via CreatePipe(), even though
575+
// that creation is faster -- we a pipe created with FILE_FLAG_OVERLAPPED.
564576
fn new() -> Result<OsIpcReceiver,WinError> {
565577
let mut r = try!(OsIpcReceiver::new_named());
566578
let pipe_id = mem::replace(&mut r.pipe_id, None).unwrap();
@@ -580,6 +592,8 @@ impl OsIpcReceiver {
580592

581593
fn new_named() -> Result<OsIpcReceiver,WinError> {
582594
unsafe {
595+
// FIXME make_pipe_id is a big performance cost. We need
596+
// a more efficient way of generating pipe IDs.
583597
let pipe_id = make_pipe_id();
584598
let pipe_name = make_pipe_name(&pipe_id);
585599

@@ -871,12 +885,26 @@ impl OsIpcSender {
871885
}
872886
}
873887

874-
fn get_pipe_server_process_handle(&self) -> Result<WinHandle,WinError> {
888+
fn get_pipe_server_process_id(&self) -> Result<winapi::ULONG,WinError> {
875889
unsafe {
876890
let mut server_pid: winapi::ULONG = 0;
877891
if kernel32::GetNamedPipeServerProcessId(*self.handle, &mut server_pid) == winapi::FALSE {
878892
return Err(WinError::last("GetNamedPipeServerProcessId"));
879893
}
894+
Ok(server_pid)
895+
}
896+
}
897+
898+
// TODO(vlad): if we could guarantee that a server handle can't be passed
899+
// after it's already been used to start receiving data, we could
900+
// store the server handle instead of needing to look it up each time.
901+
fn get_pipe_server_process_handle(&self) -> Result<WinHandle,WinError> {
902+
unsafe {
903+
let server_pid = try!(self.get_pipe_server_process_id());
904+
if server_pid == *CURRENT_PROCESS_ID {
905+
return Ok(WinHandle::new(*CURRENT_PROCESS_HANDLE as HANDLE));
906+
}
907+
880908
let raw_handle = kernel32::OpenProcess(winapi::PROCESS_DUP_HANDLE,
881909
winapi::FALSE,
882910
server_pid as winapi::DWORD);
@@ -903,12 +931,17 @@ impl OsIpcSender {
903931
// creates.
904932
fn send_unfragmented(&self, data: &[u8]) -> Result<(),WinError> {
905933
assert!(data.len() < INVALID_HEADER_DATA_SIZE as usize);
934+
935+
dd2!("[c {:?}] writing unfragmented to (pid {}->{})", *self.handle, *CURRENT_PROCESS_ID,
936+
try!(self.get_pipe_server_process_id()));
937+
906938
unsafe {
907939
let header: [u32; 2] = [ data.len() as u32, 0 ];
908940
let header_bytes: &[u8] = slice::from_raw_parts(header.as_ptr() as *const u8, HEADER_SIZE);
909941
try!(write_buf(*self.handle, &header_bytes));
910942
try!(write_buf(*self.handle, data));
911943
}
944+
dd2!("[c {:?}] sent unfragmented: {} bytes", *self.handle, data.len());
912945
Ok(())
913946
}
914947

@@ -976,7 +1009,10 @@ impl OsIpcSender {
9761009
unsafe {
9771010
// if we need to use the fragment channel, then we send a 0 as the data size;
9781011
// the receiver will see that there's a big data receiver in the OOB portion
979-
let header: [u32; 2] = [ if big_data_sender.is_some() { 0 } else { data.len() } as u32, oob_data.len() as u32];
1012+
let header: [u32; 2] = [
1013+
if big_data_sender.is_some() { 0 } else { data.len() } as u32,
1014+
oob_data.len() as u32
1015+
];
9801016
let header_bytes: &[u8] = slice::from_raw_parts(header.as_ptr() as *const u8, HEADER_SIZE);
9811017

9821018
// We need to write the main message first, which will indicate to the receiver
@@ -988,6 +1024,8 @@ impl OsIpcSender {
9881024
}
9891025
try!(write_buf(*self.handle, &oob_data));
9901026
if big_data_sender.is_some() {
1027+
dd2!("[c {:?}] sending unfragmented to big-data channel: {} bytes",
1028+
*self.handle, data.len());
9911029
try!(big_data_sender.unwrap().send_unfragmented(data));
9921030
}
9931031
}
@@ -1435,7 +1473,6 @@ impl From<WinError> for DeserializeError {
14351473

14361474
impl From<WinError> for Error {
14371475
fn from(mpsc_error: WinError) -> Error {
1438-
//Error::new(ErrorKind::Other, format!("Win channel error ({} from {})", mpsc_error.0, mpsc_error.1))
1439-
Error::new(ErrorKind::Other, format!("Win channel error ({})", mpsc_error.0))
1476+
Error::new(ErrorKind::Other, format!("Win channel error ({}=0x{:x})", mpsc_error.0, mpsc_error.0))
14401477
}
14411478
}

0 commit comments

Comments
 (0)