@@ -229,49 +229,38 @@ def _releaseLock():
229
229
# Prevent a held logging lock from blocking a child from logging.
230
230
231
231
if not hasattr (os , 'register_at_fork' ): # Windows and friends.
232
- def _register_at_fork_acquire_release (instance ):
232
+ def _register_at_fork_reinit_lock (instance ):
233
233
pass # no-op when os.register_at_fork does not exist.
234
- else : # The os.register_at_fork API exists
235
- os .register_at_fork (before = _acquireLock ,
236
- after_in_child = _releaseLock ,
237
- after_in_parent = _releaseLock )
238
-
239
- # A collection of instances with acquire and release methods (logging.Handler)
240
- # to be called before and after fork. The weakref avoids us keeping discarded
241
- # Handler instances alive forever in case an odd program creates and destroys
242
- # many over its lifetime.
243
- _at_fork_acquire_release_weakset = weakref .WeakSet ()
244
-
245
-
246
- def _register_at_fork_acquire_release (instance ):
247
- # We put the instance itself in a single WeakSet as we MUST have only
248
- # one atomic weak ref. used by both before and after atfork calls to
249
- # guarantee matched pairs of acquire and release calls.
250
- _at_fork_acquire_release_weakset .add (instance )
251
-
234
+ else :
235
+ # A collection of instances with a createLock method (logging.Handler)
236
+ # to be called in the child after forking. The weakref avoids us keeping
237
+ # discarded Handler instances alive. A set is used to avoid accumulating
238
+ # duplicate registrations as createLock() is responsible for registering
239
+ # a new Handler instance with this set in the first place.
240
+ _at_fork_reinit_lock_weakset = weakref .WeakSet ()
241
+
242
+ def _register_at_fork_reinit_lock (instance ):
243
+ _acquireLock ()
244
+ try :
245
+ _at_fork_reinit_lock_weakset .add (instance )
246
+ finally :
247
+ _releaseLock ()
252
248
253
- def _at_fork_weak_calls ( method_name ):
254
- for instance in _at_fork_acquire_release_weakset :
255
- method = getattr ( instance , method_name )
249
+ def _after_at_fork_child_reinit_locks ( ):
250
+ # _acquireLock() was called in the parent before forking.
251
+ for handler in _at_fork_reinit_lock_weakset :
256
252
try :
257
- method ()
253
+ handler . createLock ()
258
254
except Exception as err :
259
255
# Similar to what PyErr_WriteUnraisable does.
260
256
print ("Ignoring exception from logging atfork" , instance ,
261
- method_name , "method:" , err , file = sys .stderr )
262
-
263
-
264
- def _before_at_fork_weak_calls ():
265
- _at_fork_weak_calls ('acquire' )
257
+ "._reinit_lock() method:" , err , file = sys .stderr )
258
+ _releaseLock () # Acquired by os.register_at_fork(before=.
266
259
267
260
268
- def _after_at_fork_weak_calls ():
269
- _at_fork_weak_calls ('release' )
270
-
271
-
272
- os .register_at_fork (before = _before_at_fork_weak_calls ,
273
- after_in_child = _after_at_fork_weak_calls ,
274
- after_in_parent = _after_at_fork_weak_calls )
261
+ os .register_at_fork (before = _acquireLock ,
262
+ after_in_child = _after_at_fork_child_reinit_locks ,
263
+ after_in_parent = _releaseLock )
275
264
276
265
277
266
#---------------------------------------------------------------------------
@@ -844,7 +833,7 @@ def createLock(self):
844
833
Acquire a thread lock for serializing access to the underlying I/O.
845
834
"""
846
835
self .lock = threading .RLock ()
847
- _register_at_fork_acquire_release (self )
836
+ _register_at_fork_reinit_lock (self )
848
837
849
838
def acquire (self ):
850
839
"""
0 commit comments