W dniu poniedziałek, 10 lipca 2017 18:41:03 UTC+2 użytkownik Ben Noordhuis 
napisał:
>
> On Mon, Jul 10, 2017 at 9:49 AM, Przemysław Sobala 
> <[email protected] <javascript:>> 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. 
>

Eventually, I did it as in the 
https://github.com/libuv/libuv/blob/v1.x/test/test-loop-handles.c example 
via a MAKE_VALGRIND_HAPPY() macro:
1) call uv_stop() asynchronously inside a SIGINT handler
2) after the loop has stopped, in loop's thread, I'm iterating over all 
loop's handles, close them and then call uv_run() once more.
3) call uv_loop_close() that returns 0

Thank you.

-- 
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