Commit 327bb1c0 authored by Julien Muchembled's avatar Julien Muchembled

qa: fix unclean test shutdown after use of ConnectionFilter

Leaks in filter_queue caused deadlocks in the following threaded tests that
filter connections.
parent 59004b8c
...@@ -461,7 +461,7 @@ class ConnectionFilter(object): ...@@ -461,7 +461,7 @@ class ConnectionFilter(object):
filtered_count = 0 filtered_count = 0
filter_list = [] filter_list = []
filter_queue = weakref.WeakKeyDictionary() filter_queue = weakref.WeakKeyDictionary() # XXX: see the end of __new__
lock = threading.RLock() lock = threading.RLock()
_addPacket = Connection._addPacket _addPacket = Connection._addPacket
...@@ -477,7 +477,7 @@ class ConnectionFilter(object): ...@@ -477,7 +477,7 @@ class ConnectionFilter(object):
queue = cls.filter_queue[conn] queue = cls.filter_queue[conn]
except KeyError: except KeyError:
for self in cls.filter_list: for self in cls.filter_list:
if self(conn, packet): if self._test(conn, packet):
self.filtered_count += 1 self.filtered_count += 1
break break
else: else:
...@@ -494,10 +494,13 @@ class ConnectionFilter(object): ...@@ -494,10 +494,13 @@ class ConnectionFilter(object):
del cls.filter_list[-1:] del cls.filter_list[-1:]
if not cls.filter_list: if not cls.filter_list:
Connection._addPacket = cls._addPacket.im_func Connection._addPacket = cls._addPacket.im_func
with cls.lock: # Retry even in case of exception, at least to avoid leaks in
cls._retry() # filter_queue. Sometimes, WeakKeyDictionary only does the job
# only an explicit call to gc.collect.
with cls.lock:
cls._retry()
def __call__(self, conn, packet): def _test(self, conn, packet):
if not self.conn_list or conn in self.conn_list: if not self.conn_list or conn in self.conn_list:
for filter in self.filter_dict: for filter in self.filter_dict:
if filter(conn, packet): if filter(conn, packet):
...@@ -510,7 +513,7 @@ class ConnectionFilter(object): ...@@ -510,7 +513,7 @@ class ConnectionFilter(object):
while queue: while queue:
packet = queue.popleft() packet = queue.popleft()
for self in cls.filter_list: for self in cls.filter_list:
if self(conn, packet): if self._test(conn, packet):
queue.appendleft(packet) queue.appendleft(packet)
break break
else: else:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment