diff options
author | Richard van der Hoff <richard@matrix.org> | 2017-09-20 01:32:42 +0100 |
---|---|---|
committer | Richard van der Hoff <richard@matrix.org> | 2017-09-20 01:32:42 +0100 |
commit | abdefb8a01bf67b3055e9fbe52bb11a02ffd8d9a (patch) | |
tree | 5da0013e4c6d425cbf45980f76c13540ca9d89f2 | |
parent | Add some comments to _start_key_lookups (diff) | |
download | synapse-abdefb8a01bf67b3055e9fbe52bb11a02ffd8d9a.tar.xz |
Fix potential race in _start_key_lookups
If the verify_request.deferred has already completed, then `remove_deferreds` will be called immediately. It therefore might resolve the server_to_deferred deferred while there are still other requests for that server in flight. To avoid that, we should build the complete list of requests, and *then* add the callbacks.
-rw-r--r-- | synapse/crypto/keyring.py | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/synapse/crypto/keyring.py b/synapse/crypto/keyring.py index d7fd831bf9..0e381c4710 100644 --- a/synapse/crypto/keyring.py +++ b/synapse/crypto/keyring.py @@ -172,7 +172,13 @@ class Keyring(object): # map from server name to a set of request ids server_to_request_ids = {} - def remove_deferreds(res, server_name, verify_request): + for verify_request in verify_requests: + server_name = verify_request.server_name + request_id = id(verify_request) + server_to_request_ids.setdefault(server_name, set()).add(request_id) + + def remove_deferreds(res, verify_request): + server_name = verify_request.server_name request_id = id(verify_request) server_to_request_ids[server_name].discard(request_id) if not server_to_request_ids[server_name]: @@ -182,11 +188,8 @@ class Keyring(object): return res for verify_request in verify_requests: - server_name = verify_request.server_name - request_id = id(verify_request) - server_to_request_ids.setdefault(server_name, set()).add(request_id) verify_request.deferred.addBoth( - remove_deferreds, server_name, verify_request, + remove_deferreds, verify_request, ) @defer.inlineCallbacks |