Generates a KeyboardInterrupt in the main thread by sending a Ctrl+C or by calling thread.interrupt_main(). :param main_thread: Needed because Jython needs main_thread._thread.interrupt() to be called. Note: if unable to send a Ctrl+C, the KeyboardInterrupt will only be ra
(main_thread=None)
| 372 | |
| 373 | |
| 374 | def interrupt_main_thread(main_thread=None): |
| 375 | """ |
| 376 | Generates a KeyboardInterrupt in the main thread by sending a Ctrl+C |
| 377 | or by calling thread.interrupt_main(). |
| 378 | |
| 379 | :param main_thread: |
| 380 | Needed because Jython needs main_thread._thread.interrupt() to be called. |
| 381 | |
| 382 | Note: if unable to send a Ctrl+C, the KeyboardInterrupt will only be raised |
| 383 | when the next Python instruction is about to be executed (so, it won't interrupt |
| 384 | a sleep(1000)). |
| 385 | """ |
| 386 | if main_thread is None: |
| 387 | main_thread = threading.main_thread() |
| 388 | |
| 389 | pydev_log.debug("Interrupt main thread.") |
| 390 | called = False |
| 391 | try: |
| 392 | if os.name == "posix": |
| 393 | # On Linux we can't interrupt 0 as in Windows because it's |
| 394 | # actually owned by a process -- on the good side, signals |
| 395 | # work much better on Linux! |
| 396 | os.kill(os.getpid(), signal.SIGINT) |
| 397 | called = True |
| 398 | |
| 399 | elif os.name == "nt": |
| 400 | # This generates a Ctrl+C only for the current process and not |
| 401 | # to the process group! |
| 402 | # Note: there doesn't seem to be any public documentation for this |
| 403 | # function (although it seems to be present from Windows Server 2003 SP1 onwards |
| 404 | # according to: https://www.geoffchappell.com/studies/windows/win32/kernel32/api/index.htm) |
| 405 | ctypes.windll.kernel32.CtrlRoutine(0) |
| 406 | |
| 407 | # The code below is deprecated because it actually sends a Ctrl+C |
| 408 | # to the process group, so, if this was a process created without |
| 409 | # passing `CREATE_NEW_PROCESS_GROUP` the signal may be sent to the |
| 410 | # parent process and to sub-processes too (which is not ideal -- |
| 411 | # for instance, when using pytest-xdist, it'll actually stop the |
| 412 | # testing, even when called in the subprocess). |
| 413 | |
| 414 | # if hasattr_checked(signal, 'CTRL_C_EVENT'): |
| 415 | # os.kill(0, signal.CTRL_C_EVENT) |
| 416 | # else: |
| 417 | # # Python 2.6 |
| 418 | # ctypes.windll.kernel32.GenerateConsoleCtrlEvent(0, 0) |
| 419 | called = True |
| 420 | |
| 421 | except: |
| 422 | # If something went wrong, fallback to interrupting when the next |
| 423 | # Python instruction is being called. |
| 424 | pydev_log.exception("Error interrupting main thread (using fallback).") |
| 425 | |
| 426 | if not called: |
| 427 | try: |
| 428 | # In this case, we don't really interrupt a sleep() nor IO operations |
| 429 | # (this makes the KeyboardInterrupt be sent only when the next Python |
| 430 | # instruction is about to be executed). |
| 431 | if hasattr(thread, "interrupt_main"): |