Skip to content

URLSessionTask retain cycle and memory leak fix - all Linuxies #1195

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 6, 2017

Conversation

johnno1962
Copy link
Contributor

@johnno1962 johnno1962 commented Aug 30, 2017

HI Apple,

I’ve noticed a memory leak using NSURLSessionTasks to fetch a URL in Swift 4 that wasn’t present in Swift 3.1.1. This is for Vanilla Linux as well as Android. This PR seems to resolve it.

There was a retain cycle between the URLSessionTask and its protocol handler resulting in it never being deinit’d and the internal data container never being freed up. This PR nils out the pointer to the protocol handler when the task completes, breaking the retain cycle and allowing both to deinit.

Fixes SR-5472

@johnno1962
Copy link
Contributor Author

johnno1962 commented Aug 31, 2017

Sorry, I couldn’t resist fixing the many unnesssesary files created in /tmp for data tasks which will eventually slow a server using apis down. I don’t think this warranted another PR as I was looking at URLSession anyway and it was such a minor change to do so. Tested using a foundation test run.

@parkera
Copy link
Contributor

parkera commented Aug 31, 2017

Seems like we could leave it as the IUO, causing a crash if the protocol is ever unset in the other places (which seems like a precondition failure).

@itaiferber
Copy link
Contributor

@swift-ci Please test

@johnno1962
Copy link
Contributor Author

johnno1962 commented Sep 1, 2017

@parkera are you sure you want _protocol as a IUO?? It effectively makes cancel, suspend, resume unusable as they will crash now that _protocol can be nil if the request happens to have completed.

@parkera
Copy link
Contributor

parkera commented Sep 1, 2017

I'm not sure about the behavior on Darwin here, but that's what we should attempt to match.

The reason I was asking about removing the IUO here was that this leak fix also results in a behavior change to a silent failure if _protocol is nil, whereas as the IUO it would previously crash, right?

@johnno1962
Copy link
Contributor Author

The leak fix doesn't change behaviour relative to darwin in itself. After the patch and using an IUO it does introduce a race condition where if you start a request but decide to cancel/suspend/resume after the request has already completed (and _protocol nil'd out) there will be a crash as opposed to just ignoring the cancel which is I image what the Darwin implementation would do.

@johnno1962
Copy link
Contributor Author

Just checked. Darwin behaviour on resume for invalid protocol is call completion handler with error:
2017-09-01 19:54:15.646020+0100 zproto[13718:4235341] Fetch -1 nil Optional(Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSUnderlyingError=0x608000248ac0 {Error Domain=kCFErrorDomainCFNetwork Code=-1002 "(null)"}, NSErrorFailingURLStringKey=john://www.bbc.co.uk/news, NSErrorFailingURLKey=john://www.bbc.co.uk/news, NSLocalizedDescription=unsupported URL})

@johnno1962
Copy link
Contributor Author

I think I’ve converged. Over to you @parkera

@alblue
Copy link
Contributor

alblue commented Sep 4, 2017

@swift-ci please test

@pushkarnk
Copy link
Member

The retain cycle was expected to be broken as done in this PR. Looks like we missed this during the refactoring in #968 The creation of temp files only when required (by download tasks) also looks good to me.

@pushkarnk
Copy link
Member

@swift-ci please test

@parkera
Copy link
Contributor

parkera commented Sep 5, 2017

@pushkarnk if you're happy with this, go ahead and merge

@pushkarnk
Copy link
Member

@swift-ci test and merge

@pushkarnk
Copy link
Member

@swift-ci please test and merge

@swift-ci swift-ci merged commit 9c08115 into swiftlang:master Sep 6, 2017
@johnno1962
Copy link
Contributor Author

Thanks @pushkarnk 👍 Did this fix make Swit-4.0?

@ianpartridge
Copy link
Contributor

No, it'll need a separate PR against swift-4.0-branch.

@johnno1962
Copy link
Contributor Author

I can do a PR but Is it still open?

@ianpartridge
Copy link
Contributor

@parkera knows for sure. Even if 4.0 is closed though, I think it is quite possible there will be a 4.0.1 release soon after, cut from the same branch. There was a 3.0.1 and 3.0.2 last year.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants