On Mon, Jul 10, 2017 at 9:49 AM, Przemysław Sobala
<[email protected]> wrote:
> W dniu sobota, 8 lipca 2017 00:42:31 UTC+2 użytkownik Ben Noordhuis napisał:
>>
>> On Fri, Jul 7, 2017 at 10:50 AM, Przemysław Sobala
>> <[email protected]> wrote:
>> > W dniu piątek, 7 lipca 2017 10:29:13 UTC+2 użytkownik Przemysław Sobala
>> > napisał:
>> >>
>> >> W dniu czwartek, 6 lipca 2017 17:30:05 UTC+2 użytkownik Ben Noordhuis
>> >> napisał:
>> >>>
>> >>> On Thu, Jul 6, 2017 at 12:21 PM, Przemysław Sobala
>> >>> <[email protected]> wrote:
>> >>> > Hello
>> >>> > [In the preface I want to say that it can be valgrind's false
>> >>> > positive].
>> >>> > I'm building a C++ class that uses libuv (1.13.0) and libcurl
>> >>> > (7.54.1)
>> >>> > for
>> >>> > non-blocking file downloading. UV loop is being initialized in
>> >>> > object's
>> >>> > constructor, deinitialized in destructor and it's being kept a class
>> >>> > member.
>> >>> > When it's a pointer type class member (uv_loop_t *), initialized via
>> >>> > malloc:
>> >>> > loop = (uv_loop_t *) malloc(sizeof(uv_loop_t));
>> >>> > if (loop == NULL) {
>> >>> > throw std::bad_alloc();
>> >>> > }
>> >>> > uv_loop_init(loop);
>> >>> > and deinitialized via uv_loop_close(loop) there's no memory leak.
>> >>> >
>> >>> > But when it's a struct type class member (uv_loop_t) it's
>> >>> > initialized
>> >>> > automatically  while object construction, then in constructor I call
>> >>> > uv_loop_init(&loop) and uv_loop_close(&loop) in destructor, valgrind
>> >>> > reports
>> >>> > a memory leak:
>> >>> > ==2337== 256 bytes in 1 blocks are definitely lost in loss record
>> >>> > 790
>> >>> > of 840
>> >>> > ==2337==    at 0x4C2FC47: realloc (vg_replace_malloc.c:785)
>> >>> > ==2337==    by 0x816560: maybe_resize (core.c:808)
>> >>> > ==2337==    by 0x816560: uv__io_start (core.c:847)
>> >>> > ==2337==    by 0x8181EB: uv_poll_start (poll.c:120)
>> >>> > ==2337==    by 0x417ECE:
>> >>> > imageresizer::engine::FileDownloader::handle_socket(void*, int, int,
>> >>> > void*)
>> >>> > (FileDownloader.cpp:298)
>> >>> > ==2337==    by 0x417E28:
>> >>> > imageresizer::engine::FileDownloader::handle_socket_cb(void*, int,
>> >>> > int,
>> >>> > void*, void*) (FileDownloader.cpp:277)
>> >>> > ==2337==    by 0x7D1798: singlesocket (in
>> >>> >
>> >>> > /opt/WP/imageresizer-worker/dist/Debug/GNU-Linux/imageresizer-worker)
>> >>> > ==2337==    by 0x7D4AD9: multi_socket (in
>> >>> >
>> >>> > /opt/WP/imageresizer-worker/dist/Debug/GNU-Linux/imageresizer-worker)
>> >>> > ==2337==    by 0x7D4C86: curl_multi_socket_action (in
>> >>> >
>> >>> > /opt/WP/imageresizer-worker/dist/Debug/GNU-Linux/imageresizer-worker)
>> >>> > ==2337==    by 0x417D59:
>> >>> > imageresizer::engine::FileDownloader::on_timeout(uv_timer_s*)
>> >>> > (FileDownloader.cpp:248)
>> >>> > ==2337==    by 0x417D25:
>> >>> > imageresizer::engine::FileDownloader::on_timeout_cb(uv_timer_s*)
>> >>> > (FileDownloader.cpp:242)
>> >>> > ==2337==    by 0x81D4B4: uv__run_timers (timer.c:165)
>> >>> > ==2337==    by 0x8159AB: uv_run (core.c:353)
>> >>> >
>> >>> > Can you help me with getting rid of that memory leak?
>> >>> >
>> >>> > --
>> >>> > regards
>> >>> > Przemysław Sobala
>> >>>
>> >>>
>> >>> Check the return value of uv_loop_close().  My guess it's UV_EBUSY,
>> >>> indicating the event loop can't be closed yet because there are open
>> >>> handles or requests.
>> >>
>> >>
>> >> Yes, but uv_loop_close() returns UV_EBUSY in both cases.
>> >> Should I wait some time for all handles to close or iterate over all
>> >> handles inside loop and call uv_close() ?
>> >
>> >
>> > I've configured my asynchronous loop stop callback as this:
>> > uv_async_init(&loop, &loop_close_event, [](uv_async_t* handle) {
>> > uv_stop(handle->loop);
>> > uv_walk(handle->loop,
>> > [](uv_handle_t *handle, void *arg) {
>> > uv_close(handle, NULL);
>> > }, NULL);
>> > });
>> >
>> > And now uv_loop_close returns 0 and valgrind reports no memory leak. Is
>> > that
>> > a correct approach?
>>
>> Yes, that's one way to do it, with two caveats:
>>
>> 1. You probably don't need to call uv_stop().
>> 2. Closing handles indiscriminately is usually not a good idea unless
>> you own every handle.
>
>
> I think I get it. As soon as I close all loop's handles the loop will quit
> itself without the redundant uv_stop() call.
>
> What is the most preferable way to asynchronously stop and gracefully close
> the loop while it's working (iterating) e.g. inside the signal handler?

Depends on what you mean by asynchronous.  If you mean from inside
uv_run(), then uv_stop() is not your worst option.  You still need to
close open handles afterwards, though.

-- 
You received this message because you are subscribed to the Google Groups 
"libuv" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/libuv.
For more options, visit https://groups.google.com/d/optout.

Reply via email to