|
18 | 18 | import socket |
19 | 19 | import subprocess |
20 | 20 | import sys |
| 21 | +import textwrap |
21 | 22 | import time |
22 | 23 | import unittest |
23 | 24 |
|
@@ -492,29 +493,31 @@ def test_devpoll(self): |
492 | 493 | self.check_elapsed_time(dt) |
493 | 494 |
|
494 | 495 |
|
495 | | -class FNTLEINTRTest(EINTRBaseTest): |
| 496 | +class FCNTLEINTRTest(EINTRBaseTest): |
496 | 497 | def _lock(self, lock_func, lock_name): |
497 | 498 | self.addCleanup(os_helper.unlink, os_helper.TESTFN) |
498 | | - code = '\n'.join(( |
499 | | - "import fcntl, time", |
500 | | - "with open('%s', 'wb') as f:" % os_helper.TESTFN, |
501 | | - " fcntl.%s(f, fcntl.LOCK_EX)" % lock_name, |
502 | | - " time.sleep(%s)" % self.sleep_time)) |
503 | | - start_time = time.monotonic() |
504 | | - proc = self.subprocess(code) |
| 499 | + rd1, wr1 = os.pipe() |
| 500 | + rd2, wr2 = os.pipe() |
| 501 | + for fd in (rd1, wr1, rd2, wr2): |
| 502 | + self.addCleanup(os.close, fd) |
| 503 | + code = textwrap.dedent(f""" |
| 504 | + import fcntl, os, time |
| 505 | + with open('{os_helper.TESTFN}', 'wb') as f: |
| 506 | + fcntl.{lock_name}(f, fcntl.LOCK_EX) |
| 507 | + os.write({wr1}, b"ok") |
| 508 | + _ = os.read({rd2}, 2) # wait for parent process |
| 509 | + time.sleep({self.sleep_time}) |
| 510 | + """) |
| 511 | + proc = self.subprocess(code, pass_fds=[wr1, rd2]) |
505 | 512 | with kill_on_error(proc): |
506 | 513 | with open(os_helper.TESTFN, 'wb') as f: |
507 | 514 | # synchronize the subprocess |
| 515 | + ok = os.read(rd1, 2) |
| 516 | + self.assertEqual(ok, b"ok") |
| 517 | + |
| 518 | + # notify the child that the parent is ready |
508 | 519 | start_time = time.monotonic() |
509 | | - for _ in support.sleeping_retry(support.LONG_TIMEOUT, error=False): |
510 | | - try: |
511 | | - lock_func(f, fcntl.LOCK_EX | fcntl.LOCK_NB) |
512 | | - lock_func(f, fcntl.LOCK_UN) |
513 | | - except BlockingIOError: |
514 | | - break |
515 | | - else: |
516 | | - dt = time.monotonic() - start_time |
517 | | - raise Exception("failed to sync child in %.1f sec" % dt) |
| 520 | + os.write(wr2, b"go") |
518 | 521 |
|
519 | 522 | # the child locked the file just a moment ago for 'sleep_time' seconds |
520 | 523 | # that means that the lock below will block for 'sleep_time' minus some |
|
0 commit comments