bpo-36533: Reinit logging.Handler locks on fork(). (GH-12704) · python/cpython@64aa6d2 (original) (raw)

`@@ -231,49 +231,38 @@ def _releaseLock():

`

231

231

`# Prevent a held logging lock from blocking a child from logging.

`

232

232

``

233

233

`if not hasattr(os, 'register_at_fork'): # Windows and friends.

`

234

``

`-

def _register_at_fork_acquire_release(instance):

`

``

234

`+

def _register_at_fork_reinit_lock(instance):

`

235

235

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

`

236

``

`-

else: # The os.register_at_fork API exists

`

237

``

`-

os.register_at_fork(before=_acquireLock,

`

238

``

`-

after_in_child=_releaseLock,

`

239

``

`-

after_in_parent=_releaseLock)

`

240

``

-

241

``

`-

A collection of instances with acquire and release methods (logging.Handler)

`

242

``

`-

to be called before and after fork. The weakref avoids us keeping discarded

`

243

``

`-

Handler instances alive forever in case an odd program creates and destroys

`

244

``

`-

many over its lifetime.

`

245

``

`-

_at_fork_acquire_release_weakset = weakref.WeakSet()

`

246

``

-

247

``

-

248

``

`-

def _register_at_fork_acquire_release(instance):

`

249

``

`-

We put the instance itself in a single WeakSet as we MUST have only

`

250

``

`-

one atomic weak ref. used by both before and after atfork calls to

`

251

``

`-

guarantee matched pairs of acquire and release calls.

`

252

``

`-

_at_fork_acquire_release_weakset.add(instance)

`

253

``

-

``

236

`+

else:

`

``

237

`+

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

`

``

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.

`

``

242

`+

_at_fork_reinit_lock_weakset = weakref.WeakSet()

`

``

243

+

``

244

`+

def _register_at_fork_reinit_lock(instance):

`

``

245

`+

_acquireLock()

`

``

246

`+

try:

`

``

247

`+

_at_fork_reinit_lock_weakset.add(instance)

`

``

248

`+

finally:

`

``

249

`+

_releaseLock()

`

254

250

``

255

``

`-

def _at_fork_weak_calls(method_name):

`

256

``

`-

for instance in _at_fork_acquire_release_weakset:

`

257

``

`-

method = getattr(instance, method_name)

`

``

251

`+

def _after_at_fork_child_reinit_locks():

`

``

252

`+

_acquireLock() was called in the parent before forking.

`

``

253

`+

for handler in _at_fork_reinit_lock_weakset:

`

258

254

`try:

`

259

``

`-

method()

`

``

255

`+

handler.createLock()

`

260

256

`except Exception as err:

`

261

257

`# Similar to what PyErr_WriteUnraisable does.

`

262

258

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

`

263

``

`-

method_name, "method:", err, file=sys.stderr)

`

264

``

-

265

``

-

266

``

`-

def _before_at_fork_weak_calls():

`

267

``

`-

_at_fork_weak_calls('acquire')

`

``

259

`+

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

`

``

260

`+

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

`

268

261

``

269

262

``

270

``

`-

def _after_at_fork_weak_calls():

`

271

``

`-

_at_fork_weak_calls('release')

`

272

``

-

273

``

-

274

``

`-

os.register_at_fork(before=_before_at_fork_weak_calls,

`

275

``

`-

after_in_child=_after_at_fork_weak_calls,

`

276

``

`-

after_in_parent=_after_at_fork_weak_calls)

`

``

263

`+

os.register_at_fork(before=_acquireLock,

`

``

264

`+

after_in_child=_after_at_fork_child_reinit_locks,

`

``

265

`+

after_in_parent=_releaseLock)

`

277

266

``

278

267

``

279

268

`#---------------------------------------------------------------------------

`

`@@ -900,7 +889,7 @@ def createLock(self):

`

900

889

` Acquire a thread lock for serializing access to the underlying I/O.

`

901

890

` """

`

902

891

`self.lock = threading.RLock()

`

903

``

`-

_register_at_fork_acquire_release(self)

`

``

892

`+

_register_at_fork_reinit_lock(self)

`

904

893

``

905

894

`def acquire(self):

`

906

895

`"""

`