From a3a684d2c9bd7f113ae822b25c4c2730c9f12749 Mon Sep 17 00:00:00 2001 From: Mark McLoughlin <markmc@redhat.com> Date: Fri, 2 Aug 2013 07:25:45 +0100 Subject: [PATCH] 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 --- oslo/messaging/_drivers/amqpdriver.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/oslo/messaging/_drivers/amqpdriver.py b/oslo/messaging/_drivers/amqpdriver.py index 6cd35bb03..b68ae3e56 100644 --- a/oslo/messaging/_drivers/amqpdriver.py +++ b/oslo/messaging/_drivers/amqpdriver.py @@ -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):