@@ -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
"""
0 commit comments