Skip to content

Conversation

sylvainlaurent
Copy link

This PR fixes some threading issues with the library mainly caused by the incorrect assumption that Swift variables are atomic.
With this fix, the lock introduced by #68 is no longer useful, assuming that KeyChain is thread-safe as Apple docs say so. Besides, the ConcurrencyTests run fine without the lock (with a fix in the tests themselves).

@sylvainlaurent
Copy link
Author

This should fix #63

@evgenyneu
Copy link
Owner

Thanks for the fix, @sylvainlaurent.

caused by the incorrect assumption that Swift variables are atomic.

Sorry, I don't understand this, I'm too dumb. Which line in code was causing the issue?

@sylvainlaurent
Copy link
Author

Here are the threading problem I saw:

  1. assigning values to lastQueryParameters in several places : lines 108, 188, 254, 278. When a value is assigned and replaces a previous one, this decreases the reference count of the old reference. Also, when the method exits there's a decrease of reference count too. Decreasing reference counts IS atomic with swift, but when the count reaches 0, the deallocation is NOT atomic as explained here https://github.com/apple/swift/blob/master/docs/proposals/Concurrency.rst (paragraph that contains This program crashes very quickly when it tries to deallocate an already deallocated class instance

  2. lastResultCode is also not atomic, though there's probably no crash because there's no reference counting involved

  3. In the ConcurrencyTests itself: there are several occurrences of writes = writes + 1. Increasing an int this way is not atomic, and after I removed the NSLock and fixed the lastQueryParameters problem, I saw test errors about having only 998 writes instead of 1000...
    Here, instead of making the writes variable atomic, I just moved the increment operation in the same thread (queue) for all occurrences...

hope it helps
Sylvain

@evgenyneu
Copy link
Owner

@sylvainlaurent, thanks for explaining.

assigning values to lastQueryParameters in several places : lines 108, 188, 254, 278.

We assign lastQueryParameters variable after lock.lock(). So it should only be ran by one thread at a time, right? Why does it crash there?

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.

3 participants