MCPcopy Index your code
hub / github.com/python/cpython / acquire

Method acquire

Lib/importlib/_bootstrap.py:304–370  ·  view source on GitHub ↗

Acquire the module lock. If a potential deadlock is detected, a _DeadlockError is raised. Otherwise, the lock is always acquired and True is returned.

(self)

Source from the content-addressed store, hash-verified

302 )
303
304 def acquire(self):
305 """
306 Acquire the module lock. If a potential deadlock is detected,
307 a _DeadlockError is raised.
308 Otherwise, the lock is always acquired and True is returned.
309 """
310 tid = _thread.get_ident()
311 with _BlockingOnManager(tid, self):
312 while True:
313 # Protect interaction with state on self with a per-module
314 # lock. This makes it safe for more than one thread to try to
315 # acquire the lock for a single module at the same time.
316 with self.lock:
317 if self.count == [] or self.owner == tid:
318 # If the lock for this module is unowned then we can
319 # take the lock immediately and succeed. If the lock
320 # for this module is owned by the running thread then
321 # we can also allow the acquire to succeed. This
322 # supports circular imports (thread T imports module A
323 # which imports module B which imports module A).
324 self.owner = tid
325 self.count.append(True)
326 return True
327
328 # At this point we know the lock is held (because count !=
329 # 0) by another thread (because owner != tid). We'll have
330 # to get in line to take the module lock.
331
332 # But first, check to see if this thread would create a
333 # deadlock by acquiring this module lock. If it would
334 # then just stop with an error.
335 #
336 # It's not clear who is expected to handle this error.
337 # There is one handler in _lock_unlock_module but many
338 # times this method is called when entering the context
339 # manager _ModuleLockManager instead - so _DeadlockError
340 # will just propagate up to application code.
341 #
342 # This seems to be more than just a hypothetical -
343 # https://stackoverflow.com/questions/59509154
344 # https://github.com/encode/django-rest-framework/issues/7078
345 if self.has_deadlock():
346 raise _DeadlockError(f'deadlock detected by {self!r}')
347
348 # Check to see if we're going to be able to acquire the
349 # lock. If we are going to have to wait then increment
350 # the waiters so `self.release` will know to unblock us
351 # later on. We do this part non-blockingly so we don't
352 # get stuck here before we increment waiters. We have
353 # this extra acquire call (in addition to the one below,
354 # outside the self.lock context manager) to make sure
355 # self.wakeup is held when the next acquire is called (so
356 # we block). This is probably needlessly complex and we
357 # should just take self.wakeup in the return codepath
358 # above.
359 if self.wakeup.acquire(False):
360 self.waiters.append(None)
361

Callers 5

_getresponseMethod · 0.45
pollresponseMethod · 0.45
handle_EOFMethod · 0.45
__enter__Method · 0.45
_lock_unlock_moduleFunction · 0.45

Calls 5

has_deadlockMethod · 0.95
_BlockingOnManagerClass · 0.85
_DeadlockErrorClass · 0.85
appendMethod · 0.45
releaseMethod · 0.45

Tested by

no test coverage detected