@@ -361,9 +361,11 @@ class _BoundMethodProxy(object):
361
361
Minor bugfixes by Michael Droettboom
362
362
'''
363
363
def __init__ (self , cb ):
364
+ self ._hash = hash (cb )
365
+ self ._callbacks = []
364
366
try :
365
367
try :
366
- self .inst = ref (cb .im_self )
368
+ self .inst = ref (cb .im_self , self . _destroy )
367
369
except TypeError :
368
370
self .inst = None
369
371
if six .PY3 :
@@ -377,6 +379,13 @@ def __init__(self, cb):
377
379
self .func = cb
378
380
self .klass = None
379
381
382
+ def add_callback (self , callback ):
383
+ self ._callbacks .append (_BoundMethodProxy (callback ))
384
+
385
+ def _destroy (self , wk ):
386
+ for callback in self ._callbacks :
387
+ callback (self )
388
+
380
389
def __getstate__ (self ):
381
390
d = self .__dict__ .copy ()
382
391
# de-weak reference inst
@@ -433,6 +442,9 @@ def __ne__(self, other):
433
442
'''
434
443
return not self .__eq__ (other )
435
444
445
+ def __hash__ (self ):
446
+ return self ._hash
447
+
436
448
437
449
class CallbackRegistry (object ):
438
450
"""
@@ -492,17 +504,24 @@ def connect(self, s, func):
492
504
func will be called
493
505
"""
494
506
self ._func_cid_map .setdefault (s , WeakKeyDictionary ())
495
- if func in self ._func_cid_map [s ]:
496
- return self ._func_cid_map [s ][func ]
507
+ proxy = _BoundMethodProxy (func )
508
+ if proxy in self ._func_cid_map [s ]:
509
+ return self ._func_cid_map [s ][proxy ]
497
510
511
+ proxy .add_callback (self .remove_proxy )
498
512
self ._cid += 1
499
513
cid = self ._cid
500
- self ._func_cid_map [s ][func ] = cid
514
+ self ._func_cid_map [s ][proxy ] = cid
501
515
self .callbacks .setdefault (s , dict ())
502
- proxy = _BoundMethodProxy (func )
503
516
self .callbacks [s ][cid ] = proxy
504
517
return cid
505
518
519
+ def remove_proxy (self , proxy ):
520
+ """Removes a dead proxy as soon as it dies"""
521
+ for category , proxies in list (six .iteritems (self ._func_cid_map )):
522
+ if proxy in proxies :
523
+ del self .callbacks [category ][proxies [proxy ]]
524
+
506
525
def disconnect (self , cid ):
507
526
"""
508
527
disconnect the callback registered with callback id *cid*
@@ -527,11 +546,7 @@ def process(self, s, *args, **kwargs):
527
546
"""
528
547
if s in self .callbacks :
529
548
for cid , proxy in list (six .iteritems (self .callbacks [s ])):
530
- # Clean out dead references
531
- if proxy .inst is not None and proxy .inst () is None :
532
- del self .callbacks [s ][cid ]
533
- else :
534
- proxy (* args , ** kwargs )
549
+ proxy (* args , ** kwargs )
535
550
536
551
537
552
class Scheduler (threading .Thread ):
0 commit comments