umka-lang icon indicating copy to clipboard operation
umka-lang copied to clipboard

Cannot destroy a busy fiber

Open vtereshkov opened this issue 3 years ago • 4 comments

Fibers are unable to free the allocated heap if their functions have not returned in a regular way. This caused memory leaks, such as #16 and #255. To make the behavior more predictable and easier to analyze, any attempt to free a fiber variable whose function has not returned is now treated as an error:

fn main() {
        for i := 0; i < 10000; i++ {
                ctx := new(int)
                resume(make(fiber, |ctx| {
                    a := make([]int, 10000)
                    resume()
                }))
        }                                        // Runtime error: Cannot destroy a busy fiber
}

It is, however, very inconvenient for the user to care about how to terminate every fiber properly.

vtereshkov avatar Dec 18 '22 22:12 vtereshkov

I hit this error today. How are fibers meant to interact with C code?

Let's say in C I have an async function set_timer(seconds, callback). I'd like to expose it in umka as:

fn __ffi_sleep(nsecs: int)
fn sleep*(nsecs: int) {
  __ffi_sleep(nsecs)
  resume()
}

fn resume_from_c(f: fiber) {
  resume(f)
}

This allows for an umka fiber to just call sleep(1). For this to work, it seems to me that a few things need to happen:

  1. Some way to access "current fiber" to pass it to C, so that it could be __ffi_sleep(fiber.current, nsecs). C would call umkaIncRef on the fiber.
  2. Upon the C callback running, C needs some way to resume the fiber; it can call resume_from_c.
  3. The top-level function ("main" or whatever C initially called) needs to be able to return/yield all the way back to C but leave the (suspended) fibers alive. The C event loop will ultimately call resume_from_c on fibers as their tasks complete.

But this issue makes 3 an error, because there's a live fiber but the top-level call is returning.

Anyways, maybe I'm holding it wrong. Please let me know how or if Umka can interact with async C code.

rsepassi avatar Nov 07 '25 00:11 rsepassi

@rsepassi To be clear: Umka is single-threaded. Its fibers have nothing to do with OS threads. They all co-exist in the virtual machine running on a single OS thread. If called from different OS threads, Umka may crash.

AFAIK, the same applies to coroutines in Lua and fibers in Wren.

We have a request for proper multithreading: https://github.com/vtereshkov/umka-lang/issues/259. But it's a distant future, to say the least.

For now, you can only run multiple Umka instances on different OS threads. But it's the host app that would be responsible for their interaction.

vtereshkov avatar Nov 07 '25 10:11 vtereshkov

Yes, I understand. My question is about single threaded interaction with an event loop in C. Another way to put it is how would umka interact with libuv? Both Lua and Wren have the ability to be embedded in a C event loop. For example, for Wren, you can see its Scheduler machinery here: https://github.com/wren-lang/wren-cli/blob/main/src/module/scheduler.wren How IO functions use it: https://github.com/wren-lang/wren-cli/blob/main/src/module/io.wren And you can see that the structure in C is that you call wrenInterpret, then you run the uv event loop to completion. So Wren Fibers are live beyond the initial interpret call and are being resumed by uv callbacks.

https://github.com/wren-lang/wren-cli/blob/18553636618a4d33f10af9b5ab92da6431784a8c/src/cli/vm.c#L342

On Fri, Nov 7, 2025 at 2:46 AM Vasiliy Tereshkov @.***> wrote:

vtereshkov left a comment (vtereshkov/umka-lang#258) https://github.com/vtereshkov/umka-lang/issues/258#issuecomment-3501828743

@rsepassi https://github.com/rsepassi To be clear: Umka is single-threaded. Its fibers have nothing to do with OS threads. They all co-exist in the virtual machine running on a single OS thread. If called from different OS threads, Umka may crash.

AFAIK, the same applies to coroutines in Lua and fibers in Wren.

We have a request for proper multithreading: #259 https://github.com/vtereshkov/umka-lang/issues/259. But it's a distant future, to say the least.

For now, you can only run multiple Umka instances on different OS threads. But it's the host app that would be responsible for their interaction.

— Reply to this email directly, view it on GitHub https://github.com/vtereshkov/umka-lang/issues/258#issuecomment-3501828743, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIQMW7VHFWHMGOWGNUFOJ333R2BNAVCNFSM6AAAAACLMN3SVOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTKMBRHAZDQNZUGM . You are receiving this because you were mentioned.Message ID: @.***>

rsepassi avatar Nov 07 '25 16:11 rsepassi

@rsepassi I still cannot see how set_timer could be single-threaded (maybe you meant that it was multi-threaded, but only one, callback thread would directly interact with Umka).

But I admit the problem with Umka fibers outliving main. Let me first fix #577, which may be related, and then return to this issue.

vtereshkov avatar Nov 08 '25 10:11 vtereshkov