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
Fix race in ThreadSafeSingleton #322
Conversation
Hey @rda-dev , Thanks for the PR. This looks very good. A cosmetic question before merging - do we need If it's not required, can you, please, remove it in favour of ```self.__storage``? |
Hi @rmk135 , Yes, the first |
@rda-dev I like to avoid temporary variables when possible. Here is what I meant: if self.__storage is None:
with self.__storage_lock:
if self.__storage is None:
self.__storage = __factory_call(self.__instantiator,
args, kwargs)
return self.__storage It will work the same way, right? |
No, it's not the same. In your example, when you release the lock, the parallel thread may set the |
Heh, that's tricky. I got the difference finally. Didn't consider |
I will cythonize the code and make a release in a couple of hours. |
@rda-dev I have released fix in version I have also added you to the list of contributors https://github.com/ets-labs/python-dependency-injector/blob/master/CONTRIBUTORS.rst. It is distributed with every copy of Dependency Injector. Thank you again for the fix and for explaining how it works. Best, |
The
self.__storage
attribute may be overwritten by theThreadSafeSingleton.reset()
method and thus will return a None from the_provide(...)
method.Additionally, we should place a return statement inside the lock to prevent reading the shared variable. A more efficient solution is 'double-checked locking optimization.'