bpo-40091: Fix a hang at fork in the logging module (GH-19416) · python/cpython@4c3da78 (original) (raw)

`@@ -234,11 +234,9 @@ def _releaseLock():

`

234

234

`def _register_at_fork_reinit_lock(instance):

`

235

235

`pass # no-op when os.register_at_fork does not exist.

`

236

236

`else:

`

237

``

`-

A collection of instances with a createLock method (logging.Handler)

`

``

237

`+

A collection of instances with a _at_fork_reinit method (logging.Handler)

`

238

238

`# to be called in the child after forking. The weakref avoids us keeping

`

239

``

`-

discarded Handler instances alive. A set is used to avoid accumulating

`

240

``

`-

duplicate registrations as createLock() is responsible for registering

`

241

``

`-

a new Handler instance with this set in the first place.

`

``

239

`+

discarded Handler instances alive.

`

242

240

`_at_fork_reinit_lock_weakset = weakref.WeakSet()

`

243

241

``

244

242

`def _register_at_fork_reinit_lock(instance):

`

`@@ -249,16 +247,12 @@ def _register_at_fork_reinit_lock(instance):

`

249

247

`_releaseLock()

`

250

248

``

251

249

`def _after_at_fork_child_reinit_locks():

`

252

``

`-

_acquireLock() was called in the parent before forking.

`

253

250

`for handler in _at_fork_reinit_lock_weakset:

`

254

``

`-

try:

`

255

``

`-

handler.createLock()

`

256

``

`-

except Exception as err:

`

257

``

`-

Similar to what PyErr_WriteUnraisable does.

`

258

``

`-

print("Ignoring exception from logging atfork", instance,

`

259

``

`-

"._reinit_lock() method:", err, file=sys.stderr)

`

260

``

`-

_releaseLock() # Acquired by os.register_at_fork(before=.

`

``

251

`+

handler._at_fork_reinit()

`

261

252

``

``

253

`+

_acquireLock() was called in the parent before forking.

`

``

254

`+

The lock is reinitialized to unlocked state.

`

``

255

`+

_lock._at_fork_reinit()

`

262

256

``

263

257

`os.register_at_fork(before=_acquireLock,

`

264

258

`after_in_child=_after_at_fork_child_reinit_locks,

`

`@@ -891,6 +885,9 @@ def createLock(self):

`

891

885

`self.lock = threading.RLock()

`

892

886

`_register_at_fork_reinit_lock(self)

`

893

887

``

``

888

`+

def _at_fork_reinit(self):

`

``

889

`+

self.lock._at_fork_reinit()

`

``

890

+

894

891

`def acquire(self):

`

895

892

`"""

`

896

893

` Acquire the I/O thread lock.

`

`@@ -2168,6 +2165,9 @@ def emit(self, record):

`

2168

2165

`def createLock(self):

`

2169

2166

`self.lock = None

`

2170

2167

``

``

2168

`+

def _at_fork_reinit(self):

`

``

2169

`+

pass

`

``

2170

+

2171

2171

`# Warnings integration

`

2172

2172

``

2173

2173

`_warnings_showwarning = None

`