Coverage for src\zapy\utils\singleton.py: 100%
11 statements
« prev ^ index » next coverage.py v7.3.4, created at 2023-12-20 14:17 -0500
« prev ^ index » next coverage.py v7.3.4, created at 2023-12-20 14:17 -0500
1from threading import Lock
4class SingletonMeta(type):
5 """
6 This is a thread-safe implementation of Singleton.
7 """
9 _instances = {}
11 _lock: Lock = Lock()
12 """
13 We now have a lock object that will be used to synchronize threads during
14 first access to the Singleton.
15 """
17 def __call__(cls, *args, **kwargs):
18 """
19 Possible changes to the value of the `__init__` argument do not affect
20 the returned instance.
21 """
22 # Now, imagine that the program has just been launched. Since there's no
23 # Singleton instance yet, multiple threads can simultaneously pass the
24 # previous conditional and reach this point almost at the same time. The
25 # first of them will acquire lock and will proceed further, while the
26 # rest will wait here.
27 with cls._lock:
28 # The first thread to acquire the lock, reaches this conditional,
29 # goes inside and creates the Singleton instance. Once it leaves the
30 # lock block, a thread that might have been waiting for the lock
31 # release may then enter this section. But since the Singleton field
32 # is already initialized, the thread won't create a new object.
33 if cls not in cls._instances:
34 instance = super().__call__(*args, **kwargs)
35 cls._instances[cls] = instance
36 return cls._instances[cls]