Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Lib/test/lock_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,8 +572,13 @@ def f():

N = 5
with Bunch(f, N):
# Threads blocked on event.wait()
wait_threads_blocked(N)
# Wait until all threads are registered as waiters in
# event.wait(). A thread that only reaches wait() after set()
# and clear() would block until the timeout, so a fixed sleep
# is not enough on a busy machine.
Comment on lines +575 to +578

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that the second part of the comment is useful.

Suggested change
# Wait until all threads are registered as waiters in
# event.wait(). A thread that only reaches wait() after set()
# and clear() would block until the timeout, so a fixed sleep
# is not enough on a busy machine.
# Wait until all threads are registered as waiters in
# event.wait().

for _ in support.sleeping_retry(support.SHORT_TIMEOUT):
if len(event._cond._waiters) >= N:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If possible, I would prefer to avoid accessing private attributes.

Can you try instead to test if len(results) >= N: break?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, test might be something like below:

    def test_set_and_clear(self):
        # gh-57711: check that wait() returns true even when the event is
        # cleared before the waiting thread is woken up.
        event = self.eventtype()
        N = 5
        ready = []
        results = []
        def f():
            ready.append(True)
            results.append(event.wait(support.LONG_TIMEOUT))

        with Bunch(f, N):
            # Threads blocked on event.wait()
            for _ in support.sleeping_retry(support.SHORT_TIMEOUT):
                if len(ready) >= N:
                    break

            # Threads unblocked
            event.set()
            for _ in support.sleeping_retry(support.SHORT_TIMEOUT):
                if len(results) >= N:
                    break
            event.clear()

        self.assertEqual(results, [True] * N)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with Bunch(...): already waits until all started threads complete. Is it really needed to wait until len(results) >= N before calling event.clear()?

The test description says:

check that wait() returns true even when the event is cleared before the waiting thread is woken up.

Waiting for theads between set() and clear() seems to go against the test description.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. The assertEqual will fail if there is a missing value or a false value So we can remove the last support.sleeping_retry that tests the results.

break

# Threads unblocked
event.set()
Expand Down
Loading