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 the Lock that is being used later for put, 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:
[x] First #165 should be merged, this one will be rebased
[x] run pre-commit
[x] I still need to run some tests and may be even add some unit tests to safe guard this for the future.
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: