|
21 | 21 |
|
22 | 22 | from test import lock_tests |
23 | 23 |
|
| 24 | + |
| 25 | +# Between fork() and exec(), only async-safe functions are allowed (issues |
| 26 | +# #12316 and #11870), and fork() from a worker thread is known to trigger |
| 27 | +# problems with some operating systems (issue #3863): skip problematic tests |
| 28 | +# on platforms known to behave badly. |
| 29 | +platforms_to_skip = ('freebsd4', 'freebsd5', 'freebsd6', 'netbsd5', |
| 30 | + 'hp-ux11') |
| 31 | + |
| 32 | + |
24 | 33 | # A trivial mutable counter. |
25 | 34 | class Counter(object): |
26 | 35 | def __init__(self): |
@@ -468,15 +477,70 @@ def test_is_alive_after_fork(self): |
468 | 477 | pid, status = os.waitpid(pid, 0) |
469 | 478 | self.assertEqual(0, status) |
470 | 479 |
|
| 480 | + def test_main_thread(self): |
| 481 | + main = threading.main_thread() |
| 482 | + self.assertEqual(main.name, 'MainThread') |
| 483 | + self.assertEqual(main.ident, threading.current_thread().ident) |
| 484 | + self.assertEqual(main.ident, threading.get_ident()) |
471 | 485 |
|
472 | | -class ThreadJoinOnShutdown(BaseTestCase): |
| 486 | + def f(): |
| 487 | + self.assertNotEqual(threading.main_thread().ident, |
| 488 | + threading.current_thread().ident) |
| 489 | + th = threading.Thread(target=f) |
| 490 | + th.start() |
| 491 | + th.join() |
| 492 | + |
| 493 | + @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()") |
| 494 | + @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()") |
| 495 | + def test_main_thread_after_fork(self): |
| 496 | + code = """if 1: |
| 497 | + import os, threading |
| 498 | +
|
| 499 | + pid = os.fork() |
| 500 | + if pid == 0: |
| 501 | + main = threading.main_thread() |
| 502 | + print(main.name) |
| 503 | + print(main.ident == threading.current_thread().ident) |
| 504 | + print(main.ident == threading.get_ident()) |
| 505 | + else: |
| 506 | + os.waitpid(pid, 0) |
| 507 | + """ |
| 508 | + _, out, err = assert_python_ok("-c", code) |
| 509 | + data = out.decode().replace('\r', '') |
| 510 | + self.assertEqual(err, b"") |
| 511 | + self.assertEqual(data, "MainThread\nTrue\nTrue\n") |
| 512 | + |
| 513 | + @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") |
| 514 | + @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()") |
| 515 | + @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()") |
| 516 | + def test_main_thread_after_fork_from_nonmain_thread(self): |
| 517 | + code = """if 1: |
| 518 | + import os, threading, sys |
| 519 | +
|
| 520 | + def f(): |
| 521 | + pid = os.fork() |
| 522 | + if pid == 0: |
| 523 | + main = threading.main_thread() |
| 524 | + print(main.name) |
| 525 | + print(main.ident == threading.current_thread().ident) |
| 526 | + print(main.ident == threading.get_ident()) |
| 527 | + # stdout is fully buffered because not a tty, |
| 528 | + # we have to flush before exit. |
| 529 | + sys.stdout.flush() |
| 530 | + else: |
| 531 | + os.waitpid(pid, 0) |
473 | 532 |
|
474 | | - # Between fork() and exec(), only async-safe functions are allowed (issues |
475 | | - # #12316 and #11870), and fork() from a worker thread is known to trigger |
476 | | - # problems with some operating systems (issue #3863): skip problematic tests |
477 | | - # on platforms known to behave badly. |
478 | | - platforms_to_skip = ('freebsd4', 'freebsd5', 'freebsd6', 'netbsd5', |
479 | | - 'hp-ux11') |
| 533 | + th = threading.Thread(target=f) |
| 534 | + th.start() |
| 535 | + th.join() |
| 536 | + """ |
| 537 | + _, out, err = assert_python_ok("-c", code) |
| 538 | + data = out.decode().replace('\r', '') |
| 539 | + self.assertEqual(err, b"") |
| 540 | + self.assertEqual(data, "Thread-1\nTrue\nTrue\n") |
| 541 | + |
| 542 | + |
| 543 | +class ThreadJoinOnShutdown(BaseTestCase): |
480 | 544 |
|
481 | 545 | def _run_and_join(self, script): |
482 | 546 | script = """if 1: |
|
0 commit comments