@@ -4200,6 +4200,64 @@ def emit(self, record):
4200
4200
logger .setLevel (logging .DEBUG )
4201
4201
logger .debug ("boom" )
4202
4202
4203
+ @threading_helper .requires_working_threading ()
4204
+ def test_thread_supression_noninterference (self ):
4205
+ lock = threading .Lock ()
4206
+ logger = logging .getLogger ("test_thread_supression_noninterference" )
4207
+
4208
+ # Block on the first call, allow others through
4209
+ #
4210
+ # NOTE: We need to bypass the base class's lock, otherwise that will
4211
+ # block multiple calls to the same handler itself.
4212
+ class BlockOnceHandler (TestHandler ):
4213
+ def __init__ (self , barrier ):
4214
+ super ().__init__ (support .Matcher ())
4215
+ self .barrier = barrier
4216
+
4217
+ def createLock (self ):
4218
+ self .lock = None
4219
+
4220
+ def handle (self , record ):
4221
+ self .emit (record )
4222
+
4223
+ def emit (self , record ):
4224
+ if self .barrier :
4225
+ barrier = self .barrier
4226
+ self .barrier = None
4227
+ barrier .wait ()
4228
+ with lock :
4229
+ pass
4230
+ super ().emit (record )
4231
+ logger .info ("blow up if not supressed" )
4232
+
4233
+ barrier = threading .Barrier (2 )
4234
+ handler = BlockOnceHandler (barrier )
4235
+ logger .addHandler (handler )
4236
+ logger .setLevel (logging .DEBUG )
4237
+
4238
+ t1 = threading .Thread (target = logger .debug , args = ("1" ,))
4239
+ with lock :
4240
+
4241
+ # Ensure first thread is blocked in the handler, hence supressing logging...
4242
+ t1 .start ()
4243
+ barrier .wait ()
4244
+
4245
+ # ...but the second thread should still be able to log...
4246
+ t2 = threading .Thread (target = logger .debug , args = ("2" ,))
4247
+ t2 .start ()
4248
+ t2 .join (timeout = 3 )
4249
+
4250
+ self .assertEqual (len (handler .buffer ), 1 )
4251
+ self .assertTrue (handler .matches (levelno = logging .DEBUG , message = '2' ))
4252
+
4253
+ # The first thread should still be blocked here
4254
+ self .assertTrue (t1 .is_alive ())
4255
+
4256
+ # Now the lock has been released the first thread should complete
4257
+ t1 .join ()
4258
+ self .assertEqual (len (handler .buffer ), 2 )
4259
+ self .assertTrue (handler .matches (levelno = logging .DEBUG , message = '1' ))
4260
+
4203
4261
class ManagerTest (BaseTest ):
4204
4262
def test_manager_loggerclass (self ):
4205
4263
logged = []
0 commit comments