From a87984c5cee423adae3d827dc63a65eb7e86b5d1 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Wed, 30 May 2018 15:44:23 -0400 Subject: [PATCH 1/7] macOS: Classify errors returned from mach_port_allocate. --- src/platform/macos/mod.rs | 119 ++++++++++++++++++++++++++++++-------- 1 file changed, 96 insertions(+), 23 deletions(-) diff --git a/src/platform/macos/mod.rs b/src/platform/macos/mod.rs index d97601ab5..279601104 100644 --- a/src/platform/macos/mod.rs +++ b/src/platform/macos/mod.rs @@ -7,7 +7,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use self::mach_sys::{kern_return_t, mach_msg_body_t, mach_msg_header_t}; +use self::mach_sys::{kern_return_t, mach_msg_body_t, mach_msg_header_t, mach_msg_return_t}; use self::mach_sys::{mach_msg_ool_descriptor_t, mach_msg_port_descriptor_t}; use self::mach_sys::{mach_msg_timeout_t, mach_port_limits_t, mach_port_msgcount_t}; use self::mach_sys::{mach_port_right_t, mach_port_t, mach_task_self_, vm_inherit_t}; @@ -37,8 +37,14 @@ static BOOTSTRAP_PREFIX: &'static str = "org.rust-lang.ipc-channel."; const BOOTSTRAP_NAME_IN_USE: kern_return_t = 1101; const BOOTSTRAP_SUCCESS: kern_return_t = 0; +const KERN_NOT_IN_SET: kern_return_t = 12; +const KERN_INVALID_NAME: kern_return_t = 15; const KERN_INVALID_RIGHT: kern_return_t = 17; +const KERN_INVALID_VALUE: kern_return_t = 18; +const KERN_UREFS_OVERFLOW: kern_return_t = 19; +const KERN_INVALID_CAPABILITY: kern_return_t = 20; const KERN_SUCCESS: kern_return_t = 0; +const KERN_NO_SPACE: kern_return_t = 3; const MACH_MSGH_BITS_COMPLEX: u32 = 0x80000000; const MACH_MSG_IPC_KERNEL: kern_return_t = 0x00000800; const MACH_MSG_IPC_SPACE: kern_return_t = 0x00002000; @@ -133,15 +139,20 @@ impl Drop for OsIpcReceiver { } } +fn mach_port_allocate(right: mach_port_right_t) -> Result { + let mut port: mach_port_t = 0; + let os_result = unsafe { + mach_sys::mach_port_allocate(mach_task_self(), right, &mut port) + }; + if os_result == KERN_SUCCESS { + return Ok(port); + } + Err(os_result.into()) +} + impl OsIpcReceiver { fn new() -> Result { - let mut port: mach_port_t = 0; - let os_result = unsafe { - mach_sys::mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mut port) - }; - if os_result != KERN_SUCCESS { - return Err(MachError::from(os_result)) - } + let port = try!(mach_port_allocate(MACH_PORT_RIGHT_RECEIVE)); let limits = mach_port_limits_t { mpl_qlimit: MACH_PORT_QLIMIT_MAX, }; @@ -502,17 +513,10 @@ pub struct OsIpcReceiverSet { impl OsIpcReceiverSet { pub fn new() -> Result { - let mut port: mach_port_t = 0; - let os_result = unsafe { - mach_sys::mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &mut port) - }; - if os_result == KERN_SUCCESS { - Ok(OsIpcReceiverSet { - port: Cell::new(port), - }) - } else { - Err(MachError::from(os_result)) - } + let port = try!(mach_port_allocate(MACH_PORT_RIGHT_PORT_SET)); + Ok(OsIpcReceiverSet { + port: Cell::new(port), + }) } pub fn add(&mut self, receiver: OsIpcReceiver) -> Result { @@ -822,9 +826,39 @@ impl Message { } } +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum KernelError { + Success, + NoSpace, + InvalidName, + InvalidRight, + InvalidValue, + InvalidCapability, + UrefsOverflow, + NotInSet, + Unknown(kern_return_t), +} + +impl From for KernelError { + fn from(code: kern_return_t) -> KernelError { + match code { + KERN_SUCCESS => KernelError::Success, + KERN_NO_SPACE => KernelError::NoSpace, + KERN_INVALID_NAME => KernelError::InvalidName, + KERN_INVALID_RIGHT => KernelError::InvalidRight, + KERN_INVALID_VALUE => KernelError::InvalidValue, + KERN_INVALID_CAPABILITY => KernelError::InvalidCapability, + KERN_UREFS_OVERFLOW => KernelError::UrefsOverflow, + KERN_NOT_IN_SET => KernelError::NotInSet, + code => KernelError::Unknown(code), + } + } +} + #[derive(Clone, Copy, Debug, PartialEq)] pub enum MachError { Success, + Kernel(KernelError), IpcSpace, VmSpace, IpcKernel, @@ -863,7 +897,7 @@ pub enum MachError { SendNoBuffer, SendTimedOut, SendTooLarge, - Unknown(kern_return_t), + Unknown(mach_msg_return_t), } impl MachError { @@ -879,8 +913,8 @@ impl From for bincode::Error { } } -impl From for MachError { - fn from(code: kern_return_t) -> MachError { +impl From for MachError { + fn from(code: mach_msg_return_t) -> MachError { match code { MACH_MSG_SUCCESS => MachError::Success, MACH_MSG_IPC_KERNEL => MachError::IpcKernel, @@ -926,11 +960,50 @@ impl From for MachError { } } +impl From for MachError { + fn from(kernel_error: KernelError) -> MachError { + MachError::Kernel(kernel_error) + } +} + impl From for Error { - /// These error descriptions are from `mach/message.h`. + /// These error descriptions are from `mach/message.h` and `mach/kern_return.h`. fn from(mach_error: MachError) -> Error { match mach_error { MachError::Success => Error::new(ErrorKind::Other, "Success"), + MachError::Kernel(KernelError::Success) => Error::new(ErrorKind::Other, "Success."), + MachError::Kernel(KernelError::NoSpace) => { + Error::new(ErrorKind::Other, + "No room in IPC name space for another right.") + } + MachError::Kernel(KernelError::InvalidName) => { + Error::new(ErrorKind::Other, + "Name doesn't denote a right in the task.") + } + MachError::Kernel(KernelError::InvalidRight) => { + Error::new(ErrorKind::Other, + "Name denotes a right, but not an appropriate right.") + } + MachError::Kernel(KernelError::InvalidValue) => { + Error::new(ErrorKind::Other, + "Blatant range error.") + } + MachError::Kernel(KernelError::InvalidCapability) => { + Error::new(ErrorKind::Other, + "The supplied (port) capability is improper.") + } + MachError::Kernel(KernelError::UrefsOverflow) => { + Error::new(ErrorKind::Other, + "Operation would overflow limit on user-references.") + } + MachError::Kernel(KernelError::NotInSet) => { + Error::new(ErrorKind::Other, + "Receive right is not a member of a port set.") + } + MachError::Kernel(KernelError::Unknown(code)) => { + Error::new(ErrorKind::Other, + format!("Unknown kernel error: {:x}", code)) + } MachError::IpcSpace => { Error::new(ErrorKind::Other, "No room in IPC name space for another capability name.") From eaf7049803118552c8566d9ea0111b8fbc25bce4 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Wed, 30 May 2018 17:06:37 -0400 Subject: [PATCH 2/7] macOS: Avoid leaking ports associated with OsIpcReceiverSet. Ensure that the port allocated for the port set is released when the OsIpcReceiverSet dies, and ensure that ports added to the set are released at the same time. --- src/platform/macos/mod.rs | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/platform/macos/mod.rs b/src/platform/macos/mod.rs index 279601104..9659250f3 100644 --- a/src/platform/macos/mod.rs +++ b/src/platform/macos/mod.rs @@ -176,9 +176,14 @@ impl OsIpcReceiver { } } - fn consume_port(&self) -> mach_port_t { + fn extract_port(&self) -> mach_port_t { let port = self.port.get(); debug_assert!(port != MACH_PORT_NULL); + port + } + + fn consume_port(&self) -> mach_port_t { + let port = self.extract_port(); self.port.set(MACH_PORT_NULL); port } @@ -509,6 +514,7 @@ impl OsOpaqueIpcChannel { pub struct OsIpcReceiverSet { port: Cell, + ports: Vec, } impl OsIpcReceiverSet { @@ -516,15 +522,17 @@ impl OsIpcReceiverSet { let port = try!(mach_port_allocate(MACH_PORT_RIGHT_PORT_SET)); Ok(OsIpcReceiverSet { port: Cell::new(port), + ports: vec![], }) } pub fn add(&mut self, receiver: OsIpcReceiver) -> Result { - let receiver_port = receiver.consume_port(); let os_result = unsafe { - mach_sys::mach_port_move_member(mach_task_self(), receiver_port, self.port.get()) + mach_sys::mach_port_move_member(mach_task_self(), receiver.extract_port(), self.port.get()) }; if os_result == KERN_SUCCESS { + let receiver_port = receiver.consume_port(); + self.ports.push(receiver_port); Ok(receiver_port as u64) } else { Err(MachError::from(os_result)) @@ -536,6 +544,25 @@ impl OsIpcReceiverSet { } } +impl Drop for OsIpcReceiverSet { + fn drop(&mut self) { + unsafe { + for port in &self.ports { + assert_eq!(mach_sys::mach_port_mod_refs(mach_task_self(), + *port, + MACH_PORT_RIGHT_RECEIVE, + -1), + KERN_SUCCESS); + } + let error = mach_sys::mach_port_mod_refs(mach_task_self(), + self.port.get(), + MACH_PORT_RIGHT_PORT_SET, + -1); + assert_eq!(error, KERN_SUCCESS); + } + } +} + pub enum OsIpcSelectionResult { DataReceived(u64, Vec, Vec, Vec), ChannelClosed(u64), From 09e2153d2db2159f23997eaad289b72a349544cd Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Wed, 30 May 2018 17:56:16 -0400 Subject: [PATCH 3/7] macOS: Don't panic when cloning a closed channel. --- src/platform/macos/mod.rs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/platform/macos/mod.rs b/src/platform/macos/mod.rs index 9659250f3..4a88ab8c5 100644 --- a/src/platform/macos/mod.rs +++ b/src/platform/macos/mod.rs @@ -332,6 +332,9 @@ pub struct OsIpcSender { impl Drop for OsIpcSender { fn drop(&mut self) { + if self.port == MACH_PORT_NULL { + return; + } unsafe { let error = mach_sys::mach_port_mod_refs(mach_task_self(), self.port, @@ -348,14 +351,22 @@ impl Drop for OsIpcSender { impl Clone for OsIpcSender { fn clone(&self) -> OsIpcSender { - unsafe { - assert!(mach_sys::mach_port_mod_refs(mach_task_self(), - self.port, - MACH_PORT_RIGHT_SEND, - 1) == KERN_SUCCESS); + let mut cloned_port = self.port; + if cloned_port != MACH_PORT_NULL { + unsafe { + let error = mach_sys::mach_port_mod_refs(mach_task_self(), + cloned_port, + MACH_PORT_RIGHT_SEND, + 1); + if error == KERN_INVALID_RIGHT { + cloned_port = MACH_PORT_NULL; + } else if error != KERN_SUCCESS { + panic!("mach_port_mod_refs(1, {}) failed: {:08x}", cloned_port, error); + } + } } OsIpcSender { - port: self.port, + port: cloned_port, nosync_marker: PhantomData, } } From 4fa1815e697b74a52fedeafbaa9c1d56252901a0 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 31 May 2018 11:57:12 -0400 Subject: [PATCH 4/7] macOS: Wrap refcounting operations in safe APIs. --- src/platform/macos/mod.rs | 68 ++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/src/platform/macos/mod.rs b/src/platform/macos/mod.rs index 4a88ab8c5..53a29c534 100644 --- a/src/platform/macos/mod.rs +++ b/src/platform/macos/mod.rs @@ -129,12 +129,7 @@ impl Drop for OsIpcReceiver { fn drop(&mut self) { let port = self.port.get(); if port != MACH_PORT_NULL { - unsafe { - assert!(mach_sys::mach_port_mod_refs(mach_task_self(), - port, - MACH_PORT_RIGHT_RECEIVE, - -1) == KERN_SUCCESS); - } + mach_port_mod_release(port, MACH_PORT_RIGHT_RECEIVE).unwrap(); } } } @@ -150,6 +145,26 @@ fn mach_port_allocate(right: mach_port_right_t) -> Result Result<(), KernelError> { + let err = unsafe { + mach_sys::mach_port_mod_refs(mach_task_self(), port, right, 1) + }; + if err == KERN_SUCCESS { + return Ok(()); + } + Err(err.into()) +} + +fn mach_port_mod_release(port: mach_port_t, right: mach_port_right_t) -> Result<(), KernelError> { + let err = unsafe { + mach_sys::mach_port_mod_refs(mach_task_self(), port, right, -1) + }; + if err == KERN_SUCCESS { + return Ok(()); + } + Err(err.into()) +} + impl OsIpcReceiver { fn new() -> Result { let port = try!(mach_port_allocate(MACH_PORT_RIGHT_RECEIVE)); @@ -335,16 +350,11 @@ impl Drop for OsIpcSender { if self.port == MACH_PORT_NULL { return; } - unsafe { - let error = mach_sys::mach_port_mod_refs(mach_task_self(), - self.port, - MACH_PORT_RIGHT_SEND, - -1); + match mach_port_mod_release(self.port, MACH_PORT_RIGHT_SEND) { // `KERN_INVALID_RIGHT` is returned if (as far as I can tell) the receiver already shut // down. This is fine. - if error != KERN_SUCCESS && error != KERN_INVALID_RIGHT { - panic!("mach_port_mod_refs(-1, {}) failed: {:08x}", self.port, error) - } + Ok(()) | Err(KernelError::InvalidRight) => (), + Err(error) => panic!("mach_port_mod_refs(-1, {}) failed: {:?}", self.port, error), } } } @@ -353,16 +363,10 @@ impl Clone for OsIpcSender { fn clone(&self) -> OsIpcSender { let mut cloned_port = self.port; if cloned_port != MACH_PORT_NULL { - unsafe { - let error = mach_sys::mach_port_mod_refs(mach_task_self(), - cloned_port, - MACH_PORT_RIGHT_SEND, - 1); - if error == KERN_INVALID_RIGHT { - cloned_port = MACH_PORT_NULL; - } else if error != KERN_SUCCESS { - panic!("mach_port_mod_refs(1, {}) failed: {:08x}", cloned_port, error); - } + match mach_port_mod_addref(cloned_port, MACH_PORT_RIGHT_SEND) { + Ok(()) => (), + Err(KernelError::InvalidRight) => cloned_port = MACH_PORT_NULL, + Err(error) => panic!("mach_port_mod_refs(1, {}) failed: {:?}", cloned_port, error), } } OsIpcSender { @@ -557,20 +561,10 @@ impl OsIpcReceiverSet { impl Drop for OsIpcReceiverSet { fn drop(&mut self) { - unsafe { - for port in &self.ports { - assert_eq!(mach_sys::mach_port_mod_refs(mach_task_self(), - *port, - MACH_PORT_RIGHT_RECEIVE, - -1), - KERN_SUCCESS); - } - let error = mach_sys::mach_port_mod_refs(mach_task_self(), - self.port.get(), - MACH_PORT_RIGHT_PORT_SET, - -1); - assert_eq!(error, KERN_SUCCESS); + for port in &self.ports { + mach_port_mod_release(*port, MACH_PORT_RIGHT_RECEIVE).unwrap(); } + mach_port_mod_release(self.port.get(), MACH_PORT_RIGHT_PORT_SET).unwrap(); } } From fade73dc6f1c3eb31c123cccf05101039f00cea9 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 31 May 2018 12:24:28 -0400 Subject: [PATCH 5/7] macOS: Move more mach APIs behind types with stricter errors. --- src/platform/macos/mod.rs | 83 ++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 40 deletions(-) diff --git a/src/platform/macos/mod.rs b/src/platform/macos/mod.rs index 53a29c534..58e06b1de 100644 --- a/src/platform/macos/mod.rs +++ b/src/platform/macos/mod.rs @@ -8,7 +8,7 @@ // except according to those terms. use self::mach_sys::{kern_return_t, mach_msg_body_t, mach_msg_header_t, mach_msg_return_t}; -use self::mach_sys::{mach_msg_ool_descriptor_t, mach_msg_port_descriptor_t}; +use self::mach_sys::{mach_msg_ool_descriptor_t, mach_msg_port_descriptor_t, mach_msg_type_name_t}; use self::mach_sys::{mach_msg_timeout_t, mach_port_limits_t, mach_port_msgcount_t}; use self::mach_sys::{mach_port_right_t, mach_port_t, mach_task_self_, vm_inherit_t}; @@ -134,7 +134,7 @@ impl Drop for OsIpcReceiver { } } -fn mach_port_allocate(right: mach_port_right_t) -> Result { +fn mach_port_allocate(right: mach_port_right_t) -> Result { let mut port: mach_port_t = 0; let os_result = unsafe { mach_sys::mach_port_allocate(mach_task_self(), right, &mut port) @@ -165,6 +165,34 @@ fn mach_port_mod_release(port: mach_port_t, right: mach_port_right_t) -> Result< Err(err.into()) } +fn mach_port_move_member(port: mach_port_t, set: mach_port_t) -> Result<(), KernelError> { + let error = unsafe { + mach_sys::mach_port_move_member(mach_task_self(), port, set) + }; + if error == KERN_SUCCESS { + return Ok(()); + } + Err(error.into()) +} + +fn mach_port_extract_right( + port: mach_port_t, + message_type: mach_msg_type_name_t +) -> Result<(mach_port_t, mach_msg_type_name_t), KernelError> { + let (mut right, mut acquired_right) = (0, 0); + let error = unsafe { + mach_sys::mach_port_extract_right(mach_task_self(), + port, + message_type, + &mut right, + &mut acquired_right) + }; + if error == KERN_SUCCESS { + return Ok((right, acquired_right)); + } + Err(error.into()) +} + impl OsIpcReceiver { fn new() -> Result { let port = try!(mach_port_allocate(MACH_PORT_RIGHT_RECEIVE)); @@ -181,7 +209,7 @@ impl OsIpcReceiver { if os_result == KERN_SUCCESS { Ok(OsIpcReceiver::from_name(port)) } else { - Err(MachError::from(os_result)) + Err(KernelError::from(os_result).into()) } } @@ -210,20 +238,9 @@ impl OsIpcReceiver { fn sender(&self) -> Result { let port = self.port.get(); debug_assert!(port != MACH_PORT_NULL); - unsafe { - let (mut right, mut acquired_right) = (0, 0); - let os_result = mach_sys::mach_port_extract_right(mach_task_self(), - port, - MACH_MSG_TYPE_MAKE_SEND as u32, - &mut right, - &mut acquired_right); - if os_result == KERN_SUCCESS { - debug_assert!(acquired_right == MACH_MSG_TYPE_PORT_SEND as u32); - Ok(OsIpcSender::from_name(right)) - } else { - Err(MachError::from(os_result)) - } - } + let (right, acquired_right) = mach_port_extract_right(port, MACH_MSG_TYPE_MAKE_SEND as u32)?; + debug_assert!(acquired_right == MACH_MSG_TYPE_PORT_SEND as u32); + Ok(OsIpcSender::from_name(right)) } fn register_bootstrap_name(&self) -> Result { @@ -235,20 +252,12 @@ impl OsIpcReceiver { TASK_BOOTSTRAP_PORT, &mut bootstrap_port); if os_result != KERN_SUCCESS { - return Err(MachError::from(os_result)) + return Err(KernelError::from(os_result).into()) } // FIXME(pcwalton): Does this leak? - let (mut right, mut acquired_right) = (0, 0); - let os_result = mach_sys::mach_port_extract_right(mach_task_self(), - port, - MACH_MSG_TYPE_MAKE_SEND as u32, - &mut right, - &mut acquired_right); - if os_result != KERN_SUCCESS { - return Err(MachError::from(os_result)) - } + let (right, acquired_right) = mach_port_extract_right(port, MACH_MSG_TYPE_MAKE_SEND as u32)?; debug_assert!(acquired_right == MACH_MSG_TYPE_PORT_SEND as u32); let mut os_result; @@ -276,7 +285,7 @@ impl OsIpcReceiver { TASK_BOOTSTRAP_PORT, &mut bootstrap_port); if os_result != KERN_SUCCESS { - return Err(MachError::from(os_result)) + return Err(KernelError::from(os_result).into()) } let c_name = CString::new(name).unwrap(); @@ -305,7 +314,7 @@ impl OsIpcReceiver { MACH_MSG_TYPE_MAKE_SEND_ONCE as u32, &mut 0); if os_result != KERN_SUCCESS { - return Err(MachError::from(os_result)) + return Err(KernelError::from(os_result).into()) } } Ok(()) @@ -391,7 +400,7 @@ impl OsIpcSender { TASK_BOOTSTRAP_PORT, &mut bootstrap_port); if os_result != KERN_SUCCESS { - return Err(MachError::from(os_result)) + return Err(KernelError::from(os_result).into()) } let mut port = 0; @@ -542,16 +551,10 @@ impl OsIpcReceiverSet { } pub fn add(&mut self, receiver: OsIpcReceiver) -> Result { - let os_result = unsafe { - mach_sys::mach_port_move_member(mach_task_self(), receiver.extract_port(), self.port.get()) - }; - if os_result == KERN_SUCCESS { - let receiver_port = receiver.consume_port(); - self.ports.push(receiver_port); - Ok(receiver_port as u64) - } else { - Err(MachError::from(os_result)) - } + mach_port_move_member(receiver.extract_port(), self.port.get())?; + let receiver_port = receiver.consume_port(); + self.ports.push(receiver_port); + Ok(receiver_port as u64) } pub fn select(&mut self) -> Result,MachError> { From d34388055810f2dff9bf20ac941ec6e0a80eb1a3 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 31 May 2018 12:27:48 -0400 Subject: [PATCH 6/7] macOS: Add a test for transferring a closed sender. --- src/test.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test.rs b/src/test.rs index 4894d9081..71f1cbf1e 100644 --- a/src/test.rs +++ b/src/test.rs @@ -428,3 +428,11 @@ fn test_reentrant() { sender.send(null.clone()).unwrap(); assert_eq!(null, receiver.recv().unwrap()); } + +#[test] +fn transfer_closed_sender() { + let (main_tx, main_rx) = ipc::channel().unwrap(); + let (transfer_tx, _) = ipc::channel::<()>().unwrap(); + assert!(main_tx.send(transfer_tx).is_ok()); + let _transferred_tx = main_rx.recv().unwrap(); +} From 08320828a532116d76f06557ac5de616dae6c979 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 31 May 2018 12:31:12 -0400 Subject: [PATCH 7/7] macOS: Remove interior mutability from OsIpcReceiverSet. --- src/platform/macos/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/platform/macos/mod.rs b/src/platform/macos/mod.rs index 58e06b1de..f8c998202 100644 --- a/src/platform/macos/mod.rs +++ b/src/platform/macos/mod.rs @@ -537,7 +537,7 @@ impl OsOpaqueIpcChannel { } pub struct OsIpcReceiverSet { - port: Cell, + port: mach_port_t, ports: Vec, } @@ -545,20 +545,20 @@ impl OsIpcReceiverSet { pub fn new() -> Result { let port = try!(mach_port_allocate(MACH_PORT_RIGHT_PORT_SET)); Ok(OsIpcReceiverSet { - port: Cell::new(port), + port: port, ports: vec![], }) } pub fn add(&mut self, receiver: OsIpcReceiver) -> Result { - mach_port_move_member(receiver.extract_port(), self.port.get())?; + mach_port_move_member(receiver.extract_port(), self.port)?; let receiver_port = receiver.consume_port(); self.ports.push(receiver_port); Ok(receiver_port as u64) } pub fn select(&mut self) -> Result,MachError> { - select(self.port.get(), BlockingMode::Blocking).map(|result| vec![result]) + select(self.port, BlockingMode::Blocking).map(|result| vec![result]) } } @@ -567,7 +567,7 @@ impl Drop for OsIpcReceiverSet { for port in &self.ports { mach_port_mod_release(*port, MACH_PORT_RIGHT_RECEIVE).unwrap(); } - mach_port_mod_release(self.port.get(), MACH_PORT_RIGHT_PORT_SET).unwrap(); + mach_port_mod_release(self.port, MACH_PORT_RIGHT_PORT_SET).unwrap(); } }