[quickjs-devel] Re: Asynchronous finalizers?

  • From: Ondřej Jirman <deibeemoocheuguhumoh@xxxxxx>
  • To: quickjs-devel@xxxxxxxxxxxxx
  • Date: Tue, 20 Aug 2019 22:50:29 +0200

Hi,

On Tue, Aug 20, 2019 at 09:57:22PM +0200, Saúl Ibarra Corretgé wrote:

Hey there,

While working on integrating libuv I ran into the following situation:
libuv handles (a TCP socket for example) are not closed synchronously,
that is, the libuv provided close function (uv_close) takes a callback
and it's not safe to free the memory until the callback is called (it's
safe to free the handle in the callback).

I'm embedding libuv handles in a structure which I then set as the
opaque for some JS objects. If the handle wasn't closed when the
finalizer runs, I close it and free the opaque data in the close callback.

This has been working great, until I tried to be tidy and cleanup all
handles on shutdown. Handles which are destroyed when the JSContext is
going away (because JS_FreeContext was called) get their finalizrs run,
but I can no longer touch the context in the handle close callback
because it was freed already (I've allocated these structures with
js_malloc).

The only way forward I see is to allocate the opaque structures with
plan malloc so there is no dependency in the JSContext.

If QuickJS runtime doesn't own the opaque data completely, and it may outlive
the runtime, you probably shouldn't be using js_malloc that is tied to the
runtime. So that sounds like a way to go.

Just mark the data as released from quickjs in the finalizer, and then
free it in the close callback.

Another option would be for QuickJS to provide a way to destroy a
context without freeing its memory, so there is time for me to cleanup
in between. Would this make sense in the grand scheme of things?

There would not be any time. If you destroy the runtime (and as part of that
run all the finalizers), all of its memory must be gone. There's no after.

QuickJS would have to be changed, so that each JSValue object would own
a reference to the runtime, for this to work at all. And it would also go
against the memory leak check that can be done while freeing the runtime.

regards,
        Ondrej


Cheers,

-- 
Saúl


Other related posts: