How to pass parameter in Swift Async call

How to pass a parameter to an async call in swift. In a function when i try to pass a stack local auto variable to an async block, in some scenario I could see the passed parameter has changed in below code. The possible reason I could think of is that as soon as the function (handleNewFlow) is returned, the stack memory location (for supportedFlow) is freed to be taken by other functions:


// The TCP flows are actually run through the flow copying process
  override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool {
    // See the doc comment for `canHandleNewFlow(_:)` for an explanation of
    // why the code below is structured this way.
    let (supportedFlow, proxyServer, proxyPort, shouldBlock) = self.core.supportedFlowForFlow(flow, remote_endpoint: nil )
    // os_log(.debug, log: self.log, "Provider did handle flow with server :: %{public}@ and port :: %{public}@", proxyServer!, proxyPort!)
    if (supportedFlow != nil) {
      self.queue.async {
        if (shouldBlock == true) {
          // TODO with proper handling of flow
          os_log(.debug, log: self.log, "TransparentProxy Provider want to block this TCP flow, flow: 0x%zx", flow.osLogID)
          let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey : "Connection Refused"])
          flow.closeReadWithError(error)
          flow.closeWriteWithError(error)
           
        } else {
          self.core.handleNewSupportedFlow(supportedFlow!, proxyServer!, proxyPort!)
        }
      }
      os_log(.debug, log: self.log, "Provider did handle new flow, flow: 0x%zx", flow.osLogID)
      return true
    } else {
      os_log(.debug, log: self.log, "Provider did not handle new flow, flow: 0x%zx", flow.osLogID)
      return false
    }
  }

In above code I could see the value 'supportedFlow' is not correct always when 'self.core.handleNewSupportedFlow()' is called:

          self.core.handleNewSupportedFlow(supportedFlow!, proxyServer!, proxyPort!)

Can someone help me in passing 'supportedFlow' as thread function parameter in async block?

Answered by freefire in 726562022

Found the fix for this. The sample testbed project for TransparentProxyProvider has synchronisation issue and is causing 'fatalError()' in 'extension Network.NWEndpoint', which causes crash of network extension. Fix for this synchronisation is to pass 'SupportFlow' as async argument:


    if (supportedFlow != nil) {
      self.queue.async { **[supportedFlow] in**
        if (shouldBlock == true) {
          // TODO with proper handling of flow
          os_log(.debug, log: self.log, "TransparentProxy Provider want to block this TCP flow, flow: 0x%zx", flow.osLogID)
          let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey : "Connection Refused"])
          flow.closeReadWithError(error)
          flow.closeWriteWithError(error)
           
        } else {
          self.core.handleNewSupportedFlow(supportedFlow!, proxyServer!, proxyPort!)
        }
      }
      os_log(.debug, log: self.log, "Provider did handle new flow, flow: 0x%zx", flow.osLogID)
      return true
    } 
Accepted Answer

Found the fix for this. The sample testbed project for TransparentProxyProvider has synchronisation issue and is causing 'fatalError()' in 'extension Network.NWEndpoint', which causes crash of network extension. Fix for this synchronisation is to pass 'SupportFlow' as async argument:


    if (supportedFlow != nil) {
      self.queue.async { **[supportedFlow] in**
        if (shouldBlock == true) {
          // TODO with proper handling of flow
          os_log(.debug, log: self.log, "TransparentProxy Provider want to block this TCP flow, flow: 0x%zx", flow.osLogID)
          let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey : "Connection Refused"])
          flow.closeReadWithError(error)
          flow.closeWriteWithError(error)
           
        } else {
          self.core.handleNewSupportedFlow(supportedFlow!, proxyServer!, proxyPort!)
        }
      }
      os_log(.debug, log: self.log, "Provider did handle new flow, flow: 0x%zx", flow.osLogID)
      return true
    } 
How to pass parameter in Swift Async call
 
 
Q