diff options
author | Sean Quah <8349537+squahtx@users.noreply.github.com> | 2022-03-01 15:27:15 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-01 15:27:15 +0000 |
commit | 4d6b6c17c860a6ef258e513d841dbda6ea151cbd (patch) | |
tree | 1ab3f9180e5b6f1931d442536dc63559a1950420 /tests/util | |
parent | Add module callbacks called for reacting to deactivation status change and pr... (diff) | |
download | synapse-4d6b6c17c860a6ef258e513d841dbda6ea151cbd.tar.xz |
Fix rare error in `ReadWriteLock` when writers complete immediately (#12105)
Signed-off-by: Sean Quah <seanq@element.io>
Diffstat (limited to 'tests/util')
-rw-r--r-- | tests/util/test_rwlock.py | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/tests/util/test_rwlock.py b/tests/util/test_rwlock.py index a10071c70f..0774625b85 100644 --- a/tests/util/test_rwlock.py +++ b/tests/util/test_rwlock.py @@ -13,6 +13,7 @@ # limitations under the License. from twisted.internet import defer +from twisted.internet.defer import Deferred from synapse.util.async_helpers import ReadWriteLock @@ -83,3 +84,32 @@ class ReadWriteLockTestCase(unittest.TestCase): self.assertTrue(d.called) with d.result: pass + + def test_lock_handoff_to_nonblocking_writer(self): + """Test a writer handing the lock to another writer that completes instantly.""" + rwlock = ReadWriteLock() + key = "key" + + unblock: "Deferred[None]" = Deferred() + + async def blocking_write(): + with await rwlock.write(key): + await unblock + + async def nonblocking_write(): + with await rwlock.write(key): + pass + + d1 = defer.ensureDeferred(blocking_write()) + d2 = defer.ensureDeferred(nonblocking_write()) + self.assertFalse(d1.called) + self.assertFalse(d2.called) + + # Unblock the first writer. The second writer will complete without blocking. + unblock.callback(None) + self.assertTrue(d1.called) + self.assertTrue(d2.called) + + # The `ReadWriteLock` should operate as normal. + d3 = defer.ensureDeferred(nonblocking_write()) + self.assertTrue(d3.called) |