Fix 163: make credentials save/load thread safe #164
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #163
The reason for the bug in #163 is here:
https://github.com/iterative/PyDrive2/blob/master/pydrive2/auth.py#L396-L398
The problem is that every time any thread runs
SaveCredentialsFile
when token is being refreshed it sets the new Storage object, each storage object defines theLock
that is being used later forput
,get
, and other operations that are being done with the storage (clearly we don't want multiple threads writing and / or reading the same file again).The following situation was possible:
T1 - acquires lock A from the Storage A
T2 - waits to acquire the same lock A
T1 - saves credentials, releases lock A, and updates Storage A to Storage B and the same happens with lock, now it's lock B
(it's already not thread safe since T1 now can do some stuff in parallel with T2 since they use different locks)
T2 - acquires lock A
T2 - reads credentials
T2 - get's to the point where it needs to release lock, but credentials object now points to Storage B and it's trying to release lock B (thus "release unlocked lock" exception)
It's a critical MT bug and it's strange that it was working at all before.
TODO: