Skip to content

Commit

Permalink
PYTHON-2334 Add regression test for gevent.Timeout compatibility (#475)
Browse files Browse the repository at this point in the history
Use with statement in Semaphore.release.
  • Loading branch information
ShaneHarvey authored Jul 30, 2020
1 parent 83578dc commit c99254f
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
7 changes: 3 additions & 4 deletions pymongo/thread_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,9 @@ def acquire(self, blocking=True, timeout=None):
__enter__ = acquire

def release(self):
self._cond.acquire()
self._value = self._value + 1
self._cond.notify()
self._cond.release()
with self._cond:
self._value = self._value + 1
self._cond.notify()

def __exit__(self, t, v, tb):
self.release()
Expand Down
30 changes: 30 additions & 0 deletions test/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1944,6 +1944,36 @@ def poller():
task.kill()
self.assertTrue(task.dead)

def test_gevent_timeout(self):
if not gevent_monkey_patched():
raise SkipTest("Must be running monkey patched by gevent")
from gevent import spawn, Timeout
client = rs_or_single_client(maxPoolSize=1)
coll = client.pymongo_test.test
coll.insert_one({})

def contentious_task():
# The 10 second timeout causes this test to fail without blocking
# forever if a bug like PYTHON-2334 is reintroduced.
with Timeout(10):
coll.find_one({'$where': delay(1)})

def timeout_task():
with Timeout(.5):
try:
coll.find_one({})
except Timeout:
pass

ct = spawn(contentious_task)
tt = spawn(timeout_task)
tt.join(15)
ct.join(15)
self.assertTrue(tt.dead)
self.assertTrue(ct.dead)
self.assertIsNone(tt.get())
self.assertIsNone(ct.get())


if __name__ == "__main__":
unittest.main()

0 comments on commit c99254f

Please sign in to comment.