|
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