You will need to take full control over allocation and deallocation.

Here is a piece of code from my project SwifterSockets (on github, see the link 
in my signature)

public func tipReceiverLoop(
    socket: Int32,
    bufferSize: Int,
    duration: TimeInterval,
    receiver: ReceiverProtocol?) {
    
...    
    
    // Allocate the data buffer
    
    let buffer = UnsafeMutableRawPointer.allocate(bytes: bufferSize, alignedTo: 
1)
    
    
    // 
===============================================================================
    // This loop stays active as long as the consumer wants more and no error 
occured.
    // 
===============================================================================
    
    var cont = true
    repeat {
        
...        
        // ================================================
        // Wait until select signals incoming data activity
        // ================================================
        
        let selres = waitForSelect(socket: socket, timeout: timeout, forRead: 
true, forWrite: false)
        
        switch selres {
            
...            
        case .ready:
            
            
            // =============
            // Call the recv
            // =============
            
            let bytesRead = Darwin.recv(socket, buffer.assumingMemoryBound(to: 
UInt8.self), bufferSize, 0)
            
            switch bytesRead {
                
...                
            case 1 ... Int.max: // Callback for the received data
                cont = receiver?.receiverData(UnsafeBufferPointer<UInt8>(start: 
buffer.assumingMemoryBound(to: UInt8.self), count: bytesRead)) ?? true
                
...            }
        }
        
    } while cont
    
    
    // Deallocate the data buffer
    
    buffer.deallocate(bytes: bufferSize, alignedTo: 1)
}


Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl - A server for websites build in Swift






> On 28 Apr 2017, at 08:02, Rick Mann <rm...@latencyzero.com> wrote:
> 
> Yeah, okay. So: how do I do this in a way that is safe?
> 
> -- 
> Rick Mann
> rm...@latencyzero.com
> 
>> On Apr 27, 2017, at 23:00, Rien <r...@balancingrock.nl> wrote:
>> 
>> To address your question:
>> 
>> https://developer.apple.com/reference/foundation/data/1779823-withunsafemutablebytes
>> 
>> "Warning
>> The byte pointer argument should not be stored and used outside of the 
>> lifetime of the call to the closure."
>> 
>> Which is exactly what you are doing, hence the code is unsafe (no pun 
>> intended).
>> 
>> Regards,
>> Rien
>> 
>> Site: http://balancingrock.nl
>> Blog: http://swiftrien.blogspot.com
>> Github: http://github.com/Balancingrock
>> Project: http://swiftfire.nl - A server for websites build in Swift
>> 
>> 
>> 
>> 
>> 
>> 
>>> On 28 Apr 2017, at 01:38, Rick Mann <rm...@latencyzero.com> wrote:
>>> 
>>> 
>>>> On Apr 27, 2017, at 01:48 , Alex Blewitt <alb...@apple.com> wrote:
>>>> 
>>> ...
>>> 
>>>> The let constant may not even be stored in a single place; if it's known 
>>>> to be constant it can be in-lined at the point of use and potentially 
>>>> unpacked and dead code elimination throw away the unused members, for 
>>>> example.
>>>> 
>>>> If you want to pass in a let constant into the pointer, you can create a 
>>>> copy of it locally in a local variable and then use that instead. However 
>>>> this will be in the local scope, so the pointer isn't valid after it 
>>>> returns.
>>> 
>>> Ah, so this brings up another issue, then. Many of the calls in the C 
>>> library take a pointer to some memory and hang on to it, filling it in at a 
>>> later point (they make network requests). I've been doing it like this, and 
>>> it's been working, but I wonder if this is fragile:
>>> 
>>> class
>>> MyClass
>>> {
>>>  func
>>>  execute()
>>>  {
>>>      self.dataBuffer = Data(count: kLGSImageDataSize)
>>>      precondition(self.dataBuffer != nil, "Unable to allocate image buffer 
>>> (\(kLGSImageDataSize) bytes)")
>>> 
>>>      var params = c_library_params_t()
>>>      params.data_capacity = self.dataBuffer!.count
>>> 
>>>      self.dataBuffer?.withUnsafeMutableBytes
>>>          { (inBuffer) -> Void in
>>>              //  This call returns immediately, but assumes
>>>              //  it can write to inBuffer later…
>>> 
>>>              self.request = c_library_call(&params, inBuffer)
>>>          }
>>> 
>>>      if self.request == nil
>>>      {
>>>          //  Error
>>>      }
>>>  }
>>> 
>>>  var             dataBuffer:     Data?
>>> }
>>> 
>>> 
>>> -- 
>>> Rick Mann
>>> rm...@latencyzero.com
>>> 
>>> 
>> 
> 

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to