@@ -39,6 +39,7 @@ def _new_module(name):
39
39
# Module-level locking ########################################################
40
40
41
41
# A dict mapping module names to weakrefs of _ModuleLock instances
42
+ # Dictionary protected by the global import lock
42
43
_module_locks = {}
43
44
# A dict mapping thread ids to _ModuleLock instances
44
45
_blocking_on = {}
@@ -144,10 +145,7 @@ def __init__(self, name):
144
145
self ._lock = None
145
146
146
147
def __enter__ (self ):
147
- try :
148
- self ._lock = _get_module_lock (self ._name )
149
- finally :
150
- _imp .release_lock ()
148
+ self ._lock = _get_module_lock (self ._name )
151
149
self ._lock .acquire ()
152
150
153
151
def __exit__ (self , * args , ** kwargs ):
@@ -159,31 +157,37 @@ def __exit__(self, *args, **kwargs):
159
157
def _get_module_lock (name ):
160
158
"""Get or create the module lock for a given module name.
161
159
162
- Should only be called with the import lock taken."""
163
- lock = None
160
+ Acquire/release internally the global import lock to protect
161
+ _module_locks."""
162
+
163
+ _imp .acquire_lock ()
164
164
try :
165
- lock = _module_locks [name ]()
166
- except KeyError :
167
- pass
168
- if lock is None :
169
- if _thread is None :
170
- lock = _DummyModuleLock (name )
171
- else :
172
- lock = _ModuleLock (name )
173
- def cb (_ ):
174
- del _module_locks [name ]
175
- _module_locks [name ] = _weakref .ref (lock , cb )
165
+ try :
166
+ lock = _module_locks [name ]()
167
+ except KeyError :
168
+ lock = None
169
+
170
+ if lock is None :
171
+ if _thread is None :
172
+ lock = _DummyModuleLock (name )
173
+ else :
174
+ lock = _ModuleLock (name )
175
+ def cb (_ ):
176
+ del _module_locks [name ]
177
+ _module_locks [name ] = _weakref .ref (lock , cb )
178
+ finally :
179
+ _imp .release_lock ()
180
+
176
181
return lock
177
182
183
+
178
184
def _lock_unlock_module (name ):
179
- """Release the global import lock, and acquires then release the
180
- module lock for a given module name.
185
+ """Acquires then releases the module lock for a given module name.
186
+
181
187
This is used to ensure a module is completely initialized, in the
182
188
event it is being imported by another thread.
183
-
184
- Should only be called with the import lock taken."""
189
+ """
185
190
lock = _get_module_lock (name )
186
- _imp .release_lock ()
187
191
try :
188
192
lock .acquire ()
189
193
except _DeadlockError :
@@ -587,7 +591,6 @@ def _module_repr_from_spec(spec):
587
591
def _exec (spec , module ):
588
592
"""Execute the spec's specified module in an existing module's namespace."""
589
593
name = spec .name
590
- _imp .acquire_lock ()
591
594
with _ModuleLockManager (name ):
592
595
if sys .modules .get (name ) is not module :
593
596
msg = 'module {!r} not in sys.modules' .format (name )
@@ -670,7 +673,6 @@ def _load(spec):
670
673
clobbered.
671
674
672
675
"""
673
- _imp .acquire_lock ()
674
676
with _ModuleLockManager (spec .name ):
675
677
return _load_unlocked (spec )
676
678
@@ -957,16 +959,16 @@ def _find_and_load_unlocked(name, import_):
957
959
958
960
def _find_and_load (name , import_ ):
959
961
"""Find and load the module."""
960
- _imp .acquire_lock ()
961
- if name not in sys .modules :
962
- with _ModuleLockManager (name ):
962
+ with _ModuleLockManager (name ):
963
+ if name not in sys .modules :
963
964
return _find_and_load_unlocked (name , import_ )
965
+
964
966
module = sys .modules [name ]
965
967
if module is None :
966
- _imp .release_lock ()
967
968
message = ('import of {} halted; '
968
969
'None in sys.modules' .format (name ))
969
970
raise ModuleNotFoundError (message , name = name )
971
+
970
972
_lock_unlock_module (name )
971
973
return module
972
974
0 commit comments