I\'m trying to find out how to fix these memory leaks I\'m getting while running this program with Valgrind. The leaks occur with the two allocations in nShell_client_main
I finally figured out how to stop a loop and clean up all handles. I created a bunch of handles and SIGINT signal handle:
uv_signal_t *sigint = new uv_signal_t;
uv_signal_init(uv_default_loop(), sigint);
uv_signal_start(sigint, on_sigint_received, SIGINT);
When SIGINT is received (Ctrl+C in console is pressed) the on_sigint_received
callback is called.
The on_sigint_received
looks like:
void on_sigint_received(uv_signal_t *handle, int signum)
{
int result = uv_loop_close(handle->loop);
if (result == UV_EBUSY)
{
uv_walk(handle->loop, on_uv_walk, NULL);
}
}
It triggers a call back function on_uv_walk
:
void on_uv_walk(uv_handle_t* handle, void* arg)
{
uv_close(handle, on_uv_close);
}
It tries to close each opened libuv handle.
Note: that I do not call uv_stop
before uv_walk
, as mentioned saghul.
After on_sigint_received
function is called libuv loop continuous the execution and on the next iteration calls on_uv_close
for each opened handle. If you call the uv_stop
function, then the on_uv_close
callback will not be called.
void on_uv_close(uv_handle_t* handle)
{
if (handle != NULL)
{
delete handle;
}
}
After that libuv do not have opened handles and finishes the loop (exits from uv_run
):
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
int result = uv_loop_close(uv_default_loop());
if (result)
{
cerr << "failed to close libuv loop: " << uv_err_name(result) << endl;
}
else
{
cout << "libuv loop is closed successfully!\n";
}
libuv is not done with a handle until it's close callback is called. That is the exact moment when you can free the handle.
I see you call uv_loop_close
, but you don't check for the return value. If there are still pending handles, it will return UV_EBUSY, so you should check for that.
If you want to close a loop and close all handles, you need to do the following:
uv_stop
to stop the loopuv_walk
and call uv_close
on all handles which are not closinguv_run
so all close callbacks are called and you can free the memory in the callbacksuv_loop_close
, it should return 0 now