# Where does the toplevel go?

**URL:** <https://swi-prolog.discourse.group/t/where-does-the-toplevel-go/9395>\
**Category:** General\
**Created:** [November 20, 2025, 3:16pm UTC](https://swi-prolog.discourse.group/t/where-does-the-toplevel-go/9395 "2025-11-20T15:16:45Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![z5h](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/z5h/32/5445_2.png) [@z5h](https://swi-prolog.discourse.group/u/z5h)\
**Post date:** [November 20, 2025, 3:16pm UTC](https://swi-prolog.discourse.group/t/where-does-the-toplevel-go/9395/1 "2025-11-20T15:16:45Z")

</div>

Consider this code to be run from the interactive toplevel:

```prolog
go :-
  thread_create(console, T),
  thread_join(T, Status),
  writeln(status:Status), !.

console :-
	with_tty_raw(get_single_char(C)),
	writeln(get_single_char(C)).

```

When I run it I get output I expect …

```prolog
?- go.
get_single_char(103)
status:true
true.

```

but the interactive toplevel `?-` prompt doesn’t come back.

What’s happening? And what have I missed in the documentation that would have prepared me to expect this?

I see the new thread would “inherit” `prompt`, `user_input`, `user_output` but it’s not clear that the original thread wouldn’t resume as usual once the new thread terminates.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [November 20, 2025, 8:28pm UTC](https://swi-prolog.discourse.group/t/where-does-the-toplevel-go/9395/2 "2025-11-20T20:28:47Z")

</div>

> [@z5h](#):
>
> What’s happening?

The stream lock was not released. Pushed a fix.
