77 See https://swift.org/LICENSE.txt for license information
88*/
99
10- #if false && swift(>=5.8) && $MoveOnly && (os(macOS) || os(iOS) || os(watchOS) || os(tvOS))
10+ #if swift(>=5.9) && (os(macOS) || os(iOS) || os(watchOS) || os(tvOS))
1111
1212import Darwin. Mach
1313
@@ -48,11 +48,13 @@ public enum Mach {
4848 ///
4949 /// This initializer makes a syscall to guard the right.
5050 public init ( name: mach_port_name_t ) {
51- precondition ( name != mach_port_name_t ( MACH_PORT_NULL) , " Mach.Port cannot be initialized with MACH_PORT_NULL " )
51+ precondition ( name != mach_port_name_t ( MACH_PORT_NULL) ,
52+ " Mach.Port cannot be initialized with MACH_PORT_NULL " )
5253 self . _name = name
5354
5455 if RightType . self == ReceiveRight . self {
55- precondition ( name != 0xFFFFFFFF /* MACH_PORT_DEAD */, " Receive rights cannot be dead names " )
56+ precondition ( name != 0xFFFFFFFF /* MACH_PORT_DEAD */,
57+ " Receive rights cannot be dead names " )
5658
5759 let secret = mach_port_context_t ( arc4random ( ) )
5860 _machPrecondition ( mach_port_guard ( mach_task_self_, name, secret, 0 ) )
@@ -81,17 +83,18 @@ public enum Mach {
8183 }
8284
8385 deinit {
84- if _name == 0xFFFFFFFF /* MACH_PORT_DEAD */ {
85- precondition ( RightType . self != ReceiveRight . self, " Receive rights cannot be dead names " )
86- _machPrecondition ( mach_port_mod_refs ( mach_task_self_, _name, MACH_PORT_RIGHT_DEAD_NAME, - 1 ) )
86+ if RightType . self == ReceiveRight . self {
87+ precondition ( _name != 0xFFFFFFFF /* MACH_PORT_DEAD */,
88+ " Receive rights cannot be dead names " )
89+ _machPrecondition (
90+ mach_port_destruct ( mach_task_self_, _name, 0 , _context)
91+ )
8792 } else {
88- if RightType . self == ReceiveRight . self {
89- _machPrecondition ( mach_port_destruct ( mach_task_self_, _name, - 1 , _context) )
90- } else if RightType . self == SendRight . self {
91- _machPrecondition ( mach_port_mod_refs ( mach_task_self_, _name, MACH_PORT_RIGHT_SEND, - 1 ) )
92- } else if RightType . self == SendOnceRight . self {
93- _machPrecondition ( mach_port_mod_refs ( mach_task_self_, _name, MACH_PORT_RIGHT_SEND_ONCE, - 1 ) )
94- }
93+ assert (
94+ RightType . self == SendRight . self ||
95+ RightType . self == SendOnceRight . self
96+ )
97+ _machPrecondition ( mach_port_deallocate ( mach_task_self_, _name) )
9598 }
9699 }
97100 }
@@ -135,6 +138,8 @@ extension Mach.Port where RightType == Mach.ReceiveRight {
135138 /// The underlying port right will be automatically deallocated when
136139 /// the Mach.Port object is destroyed.
137140 public init ( name: mach_port_name_t , context: mach_port_context_t ) {
141+ precondition ( name != mach_port_name_t ( MACH_PORT_NULL) ,
142+ " Mach.Port cannot be initialized with MACH_PORT_NULL " )
138143 self . _name = name
139144 self . _context = context
140145 }
@@ -147,9 +152,9 @@ extension Mach.Port where RightType == Mach.ReceiveRight {
147152 @inlinable
148153 public init ( ) {
149154 var storage : mach_port_name_t = mach_port_name_t ( MACH_PORT_NULL)
150- withUnsafeMutablePointer ( to : & storage ) { storage in
151- _machPrecondition ( mach_port_allocate ( mach_task_self_, MACH_PORT_RIGHT_RECEIVE, storage) )
152- }
155+ _machPrecondition (
156+ mach_port_allocate ( mach_task_self_, MACH_PORT_RIGHT_RECEIVE, & storage)
157+ )
153158
154159 // name-only init will guard ReceiveRights
155160 self . init ( name: storage)
@@ -167,9 +172,11 @@ extension Mach.Port where RightType == Mach.ReceiveRight {
167172 /// After this function completes, the Mach.Port is destroyed and no longer
168173 /// usable.
169174 @inlinable
170- public __consuming func relinquish(
175+ public consuming func relinquish(
171176 ) -> ( name: mach_port_name_t , context: mach_port_context_t ) {
172- return ( name: _name, context: _context)
177+ let destructured = ( name: _name, context: _context)
178+ discard self
179+ return destructured
173180 }
174181
175182 /// Remove guard and transfer ownership of the underlying port right to
@@ -187,9 +194,10 @@ extension Mach.Port where RightType == Mach.ReceiveRight {
187194 /// Mach.ReceiveRights. Use relinquish() to avoid the syscall and extract
188195 /// the context value along with the port name.
189196 @inlinable
190- public __consuming func unguardAndRelinquish( ) -> mach_port_name_t {
191- _machPrecondition ( mach_port_unguard ( mach_task_self_, _name, _context) )
192- return _name
197+ public consuming func unguardAndRelinquish( ) -> mach_port_name_t {
198+ let ( name, context) = self . relinquish ( )
199+ _machPrecondition ( mach_port_unguard ( mach_task_self_, name, context) )
200+ return name
193201 }
194202
195203 /// Borrow access to the port name in a block that can perform
@@ -220,17 +228,15 @@ extension Mach.Port where RightType == Mach.ReceiveRight {
220228 var newRight : mach_port_name_t = mach_port_name_t ( MACH_PORT_NULL)
221229 var newRightType : mach_port_type_t = MACH_PORT_TYPE_NONE
222230
223- withUnsafeMutablePointer ( to: & newRight) { newRight in
224- withUnsafeMutablePointer ( to: & newRightType) { newRightType in
225- _machPrecondition (
226- mach_port_extract_right ( mach_task_self_,
227- _name,
228- mach_msg_type_name_t ( MACH_MSG_TYPE_MAKE_SEND_ONCE) ,
229- newRight,
230- newRightType)
231- )
232- }
233- }
231+ _machPrecondition (
232+ mach_port_extract_right (
233+ mach_task_self_,
234+ _name,
235+ mach_msg_type_name_t ( MACH_MSG_TYPE_MAKE_SEND_ONCE) ,
236+ & newRight,
237+ & newRightType
238+ )
239+ )
234240
235241 // The value of newRight is validated by the Mach.Port initializer
236242 precondition ( newRightType == MACH_MSG_TYPE_MOVE_SEND_ONCE)
@@ -249,7 +255,11 @@ extension Mach.Port where RightType == Mach.ReceiveRight {
249255 let how = MACH_MSG_TYPE_MAKE_SEND
250256
251257 // name is the same because send and recv rights are coalesced
252- _machPrecondition ( mach_port_insert_right ( mach_task_self_, _name, _name, mach_msg_type_name_t ( how) ) )
258+ _machPrecondition (
259+ mach_port_insert_right (
260+ mach_task_self_, _name, _name, mach_msg_type_name_t ( how)
261+ )
262+ )
253263
254264 return Mach . Port ( name: _name)
255265 }
@@ -261,11 +271,19 @@ extension Mach.Port where RightType == Mach.ReceiveRight {
261271 public var makeSendCount : mach_port_mscount_t {
262272 get {
263273 var status : mach_port_status = mach_port_status ( )
264- var size : mach_msg_type_number_t = mach_msg_type_number_t ( MemoryLayout < mach_port_status > . size / MemoryLayout < natural_t > . size)
265- withUnsafeMutablePointer ( to: & size) { size in
266- withUnsafeMutablePointer ( to: & status) { status in
267- let info = UnsafeMutableRawPointer ( status) . bindMemory ( to: integer_t. self, capacity: 1 )
268- _machPrecondition ( mach_port_get_attributes ( mach_task_self_, _name, MACH_PORT_RECEIVE_STATUS, info, size) )
274+ var size = mach_msg_type_number_t (
275+ MemoryLayout < mach_port_status > . size / MemoryLayout < natural_t > . size
276+ )
277+
278+ withUnsafeMutablePointer ( to: & status) {
279+ let status = UnsafeMutableBufferPointer ( start: $0, count: 1 )
280+ status. withMemoryRebound ( to: integer_t. self) {
281+ let info = $0. baseAddress
282+ _machPrecondition (
283+ mach_port_get_attributes (
284+ mach_task_self_, _name, MACH_PORT_RECEIVE_STATUS, info, & size
285+ )
286+ )
269287 }
270288 }
271289 return status. mps_mscount
@@ -288,8 +306,10 @@ extension Mach.Port where RightType == Mach.SendRight {
288306 /// After this function completes, the Mach.Port is destroyed and no longer
289307 /// usable.
290308 @inlinable
291- public __consuming func relinquish( ) -> mach_port_name_t {
292- return _name
309+ public consuming func relinquish( ) -> mach_port_name_t {
310+ let name = _name
311+ discard self
312+ return name
293313 }
294314
295315 /// Create another send right from a given send right.
@@ -304,8 +324,10 @@ extension Mach.Port where RightType == Mach.SendRight {
304324 let how = MACH_MSG_TYPE_COPY_SEND
305325
306326 // name is the same because send rights are coalesced
307- let kr = mach_port_insert_right ( mach_task_self_, _name, _name, mach_msg_type_name_t ( how) )
308- if kr == KERN_INVALID_CAPABILITY {
327+ let kr = mach_port_insert_right (
328+ mach_task_self_, _name, _name, mach_msg_type_name_t ( how)
329+ )
330+ if kr == KERN_INVALID_NAME || kr == KERN_INVALID_CAPABILITY {
309331 throw Mach . PortRightError. deadName
310332 }
311333 _machPrecondition ( kr)
@@ -326,8 +348,10 @@ extension Mach.Port where RightType == Mach.SendOnceRight {
326348 /// After this function completes, the Mach.Port is destroyed and no longer
327349 /// usable.
328350 @inlinable
329- public __consuming func relinquish( ) -> mach_port_name_t {
330- return _name
351+ public consuming func relinquish( ) -> mach_port_name_t {
352+ let name = _name
353+ discard self
354+ return name
331355 }
332356}
333357
0 commit comments