Skip to content

GSubprocessLauncher: Move cleanup to dispose()

The GSubprocessLauncher class lacks a dispose() method, and frees all its resources in the finalize() method.

This is a problem with Javascript, because the sockets passed to a child process using g_subprocess_launcher_take_fd() aren't closed in the parent space until the object is fully freed. This means that if the child closes a socket, it won't be detected until the GSubprocessLauncher object has been freed by the garbage collector.

Just closing the socket externally is not a valid solution, because the finalize() method will close it again, and since another file/pipe/socket can be opened in the meantime and be given the same FD number, the finalize() method would close an incorrect FD.

An example is launching a child process that will use its own socket for Wayland: the parent creates two sockets with socketpair(), passes one to the Wayland API (wl_client_create()), and the other is passed to the child process using g_subprocess_launcher_take_fd(). But now there are two instances of that second socket: one in the parent, and another one in the child process. That means that, if the child closes its socket, or dies, the Wayland server will not detect that until the GSubprocessLauncher object is fully destroyed. That means that a GSubprocessLauncher created in Javascript will last for several seconds after the child dies, and every window or graphical element will remain in the screen until the Garbage Collector destroys the GSubprocessLauncher object.

This patch fixes this by moving the resource free code into a dispose() method, which can be called from Javascript. This allows to ensure that any socket passed to the child with g_subprocess_launcher_take_fd() can be closed even on Javascript just by calling the method run_dispose().

Edited by Rastersoft

Merge request reports