(self, cond)
| 631 | self.assertRaises(RuntimeError, cond.notify) |
| 632 | |
| 633 | def _check_notify(self, cond): |
| 634 | # Note that this test is sensitive to timing. If the worker threads |
| 635 | # don't execute in a timely fashion, the main thread may think they |
| 636 | # are further along then they are. The main thread therefore issues |
| 637 | # wait_threads_blocked() statements to try to make sure that it doesn't |
| 638 | # race ahead of the workers. |
| 639 | # Secondly, this test assumes that condition variables are not subject |
| 640 | # to spurious wakeups. The absence of spurious wakeups is an implementation |
| 641 | # detail of Condition Variables in current CPython, but in general, not |
| 642 | # a guaranteed property of condition variables as a programming |
| 643 | # construct. In particular, it is possible that this can no longer |
| 644 | # be conveniently guaranteed should their implementation ever change. |
| 645 | ready = [] |
| 646 | results1 = [] |
| 647 | results2 = [] |
| 648 | phase_num = 0 |
| 649 | def f(): |
| 650 | cond.acquire() |
| 651 | ready.append(phase_num) |
| 652 | result = cond.wait() |
| 653 | |
| 654 | cond.release() |
| 655 | results1.append((result, phase_num)) |
| 656 | |
| 657 | cond.acquire() |
| 658 | ready.append(phase_num) |
| 659 | |
| 660 | result = cond.wait() |
| 661 | cond.release() |
| 662 | results2.append((result, phase_num)) |
| 663 | |
| 664 | N = 5 |
| 665 | with Bunch(f, N): |
| 666 | # first wait, to ensure all workers settle into cond.wait() before |
| 667 | # we continue. See issues #8799 and #30727. |
| 668 | for _ in support.sleeping_retry(support.SHORT_TIMEOUT): |
| 669 | if len(ready) >= N: |
| 670 | break |
| 671 | |
| 672 | ready.clear() |
| 673 | self.assertEqual(results1, []) |
| 674 | |
| 675 | # Notify 3 threads at first |
| 676 | count1 = 3 |
| 677 | cond.acquire() |
| 678 | cond.notify(count1) |
| 679 | wait_threads_blocked(count1) |
| 680 | |
| 681 | # Phase 1 |
| 682 | phase_num = 1 |
| 683 | cond.release() |
| 684 | for _ in support.sleeping_retry(support.SHORT_TIMEOUT): |
| 685 | if len(results1) >= count1: |
| 686 | break |
| 687 | |
| 688 | self.assertEqual(results1, [(True, 1)] * count1) |
| 689 | self.assertEqual(results2, []) |
| 690 |
no test coverage detected