Where does flow of execution go when a thread returns?

I use a keyboard input thread to handle single key presses in a hardware testing application, and allow the escape key to terminate the test run.

After that occurs my app sometimes becomes unresponsive, or does other random things so I wanted to pick up the flow of execution at the point immediately following the thread exit and start debugging. The thread method code looks like:

            while self.running:
                ch = sys.stdin.read(1)
                match ch:
                    case '\x1b':
                        self.running = False
                        print(f'Ending key_input()', end='\r\n')
                        return  # show's over, shut down this thread

Where does control return to, if that means anything?

This happens within an outer loop that is used to select a test and setup/run/cleanup.

The outer loop has an explicit ‘quit’ command that performs a thread.join() and I know it doesn’t go there, so where does it go?

If that’s the function that got started as the beginning of the thread, execution flow doesn’t go anywhere - the thread ends. Starting a thread starts an entire new thread of execution, which ends when that function returns (or raises), or when the thread is stopped in some other way.