@@ -231,49 +231,38 @@ def _releaseLock():
231231# Prevent a held logging lock from blocking a child from logging.
232232
233233if 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 ):
235235 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 ()
254250
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 :
258254 try :
259- method ()
255+ handler . createLock ()
260256 except Exception as err :
261257 # Similar to what PyErr_WriteUnraisable does.
262258 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=.
268261
269262
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 )
277266
278267
279268#---------------------------------------------------------------------------
@@ -900,7 +889,7 @@ def createLock(self):
900889 Acquire a thread lock for serializing access to the underlying I/O.
901890 """
902891 self .lock = threading .RLock ()
903- _register_at_fork_acquire_release (self )
892+ _register_at_fork_reinit_lock (self )
904893
905894 def acquire (self ):
906895 """
0 commit comments