Fix race condition in ReplyWaiters.wake_all()

While we're iterating over the queues in ReplyWaiters.wake_all(), new
queues can be registered and we get:

  RuntimeError: dictionary changed size during iteration

Instead of using an iterator, take a snapshot list of message IDs and
operate on that.

We don't actually care about any new queues added after wake_all() is
called because the connection lock has already been dropped so one of
the other waiters must have picked it up.

We also don't need to worry about queues being removed - if we write to
a removed queue, that's not going to be a problem.

Change-Id: Ib572cbfd3a7346b76579f82b64aa85a03c1a4fb2
This commit is contained in:
Mark McLoughlin 2013-08-02 07:25:45 +01:00
parent 950c37c595
commit a3a684d2c9

@ -119,9 +119,8 @@ class ReplyWaiters(object):
queue.put(message_data)
def wake_all(self, except_id):
for msg_id in self._queues:
if msg_id == except_id:
continue
msg_ids = [i for i in self._queues if i != except_id]
for msg_id in msg_ids:
self.put(msg_id, None)
def add(self, msg_id, queue):