1

I'm experiencing a deadlock inside one of the operations in the NSUrlSession delegate queue when using Alamofire.

it happens when i'm doing at least one download and one upload simultaneously (all requests are done through the default Alamofire manager). Is there any problem doing so from multiple threads? (either in NSUrlSession or Alamofire)

it seems to be stuck on __psynch_mutexwait in one of the operations in the NSURLSession delegate queue, and it completely shuts down the app's ability to make network requests through Alamofire (because the delegate won't be called ever).

as I said the download and upload called simultaneously on 2 different queues (one of them is usually called on the main thread)

upload example :

        Alamofire.upload(.POST, uploadURL,
        multipartFormData: { multipartFormData in
                multipartFormData.appendBodyPart(data: x.dataUsingEncoding(NSUTF8StringEncoding)!, name: "X")
                multipartFormData.appendBodyPart(data: fileData, name: "file", fileName: "Y", mimeType: "application/octet-stream")
            }
        },
        encodingCompletion: { encodingResult in
            switch encodingResult {
            case .Success(let upload, _, _):
                upload.response { (request, response, data, error) -> Void in
                    if let error = error {
                        callback("Failure", "\(error)")
                    } else {
                        callback("SUCCESS", nil)
                    }
                }
            case .Failure(let encodingError):
                callback(nil, "Failed due to \(encodingError)")
            }
        }
    )

download example :

    Alamofire.download(.GET, downloadUrl, parameters: ["a": "a", "b": "b"], destination:
        {
            tempURL, response in
            return path
    }).response {
        (request, response, _, error) in
        let data = NSData(contentsOfURL: path)
        doSomeStuffWithDownloadedData(data)
        // make another request after download completed
        Alamofire.request(.GET, requestUrl, parameters: ["c":"c", "d":"d"]).response {
            request, response, data, error in
            if let e = error {
                log.error("request failed, \(e)")
            }
        }
    }

stack trace

yeps
  • 31
  • 1
  • 6

1 Answers1

1

After commenting most of my code I isolated the code causing the problem and it does not related at all to alamofire or NSURLSession.

I have in my own code a call to objc_sync_enter on an array (of objects), it always has a matching objc_sync_exit call on the same array. after changing this call to be on self instead of this array, the deadlock inside NSBlockOperation is gone. It may be related to the fact that an array is not an object but a struct. So if you experience very strange deadlock in your code, I suggest that before you try anything else, make sure you don't have calls of objc_sync_enter on structs.

yeps
  • 31
  • 1
  • 6