Author: Honza_Kral Date: 2010-11-21 08:58:18 -0600 (Sun, 21 Nov 2010) New Revision: 14663
Modified: django/branches/releases/1.2.X/django/dispatch/dispatcher.py Log: [1.2.X] Make django signals more thread-safe. Thanks milosu for the patch! Backport of r14662 from trunk. Modified: django/branches/releases/1.2.X/django/dispatch/dispatcher.py =================================================================== --- django/branches/releases/1.2.X/django/dispatch/dispatcher.py 2010-11-21 14:54:23 UTC (rev 14662) +++ django/branches/releases/1.2.X/django/dispatch/dispatcher.py 2010-11-21 14:58:18 UTC (rev 14663) @@ -1,4 +1,5 @@ import weakref +import threading from django.dispatch import saferef @@ -30,6 +31,7 @@ if providing_args is None: providing_args = [] self.providing_args = set(providing_args) + self.lock = threading.Lock() def connect(self, receiver, sender=None, weak=True, dispatch_uid=None): """ @@ -97,11 +99,15 @@ if weak: receiver = saferef.safeRef(receiver, onDelete=self._remove_receiver) - for r_key, _ in self.receivers: - if r_key == lookup_key: - break - else: - self.receivers.append((lookup_key, receiver)) + try: + self.lock.acquire() + for r_key, _ in self.receivers: + if r_key == lookup_key: + break + else: + self.receivers.append((lookup_key, receiver)) + finally: + self.lock.release() def disconnect(self, receiver=None, sender=None, weak=True, dispatch_uid=None): """ @@ -130,11 +136,15 @@ else: lookup_key = (_make_id(receiver), _make_id(sender)) - for index in xrange(len(self.receivers)): - (r_key, _) = self.receivers[index] - if r_key == lookup_key: - del self.receivers[index] - break + try: + self.lock.acquire() + for index in xrange(len(self.receivers)): + (r_key, _) = self.receivers[index] + if r_key == lookup_key: + del self.receivers[index] + break + finally: + self.lock.release() def send(self, sender, **named): """ @@ -227,11 +237,20 @@ Remove dead receivers from connections. """ - to_remove = [] - for key, connected_receiver in self.receivers: - if connected_receiver == receiver: - to_remove.append(key) - for key in to_remove: - for idx, (r_key, _) in enumerate(self.receivers): - if r_key == key: - del self.receivers[idx] + try: + self.lock.acquire() + to_remove = [] + for key, connected_receiver in self.receivers: + if connected_receiver == receiver: + to_remove.append(key) + for key in to_remove: + last_idx = len(self.receivers) - 1 + # enumerate in reverse order so that indexes are valid even + # after we delete some items + for idx, (r_key, _) in enumerate(reversed(self.receivers)): + if r_key == key: + del self.receivers[last_idx-idx] + finally: + self.lock.release() + + -- You received this message because you are subscribed to the Google Groups "Django updates" group. To post to this group, send email to django-upda...@googlegroups.com. To unsubscribe from this group, send email to django-updates+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-updates?hl=en.