loop_mutex.lock(); uv_run(loop, UV_RUN_DEFAULT); loop_mutex.unlock(); uv_async_init(loop, &loop_wakup, NULL);
void FileDownloader::Add(const string url, const string file_path, done_callback_t done_cb, error_callback_t error_cb) { curl_easy_ctx *easy_ctx = new curl_easy_ctx(); easy_ctx->done_callback = done_cb; easy_ctx->error_callback = error_cb; easy_ctx->file = unique_ptr<File>(new File(file_path)); CURL *handle = curl_easy_init(); // downloaded data will be written to file curl_easy_setopt(handle, CURLOPT_WRITEDATA, easy_ctx->file->InternalHandle()); // private single downloading context curl_easy_setopt(handle, CURLOPT_PRIVATE, easy_ctx); // fail if http response code is >= 400 curl_easy_setopt(handle, CURLOPT_FAILONERROR, 1); // follow redirects curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1); // whole request timeout [sec] curl_easy_setopt(handle, CURLOPT_TIMEOUT, req_timeout); // URL to download curl_easy_setopt(handle, CURLOPT_URL, url.c_str()); // disable signal handlers curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1L); synchronized(curl_handle_mutex) { curl_multi_add_handle(curl_handle, handle); } uv_async_send(&loop_wakup); LOG(INFO) << "Downloading " << url << " -> " << file_path; }uv_stop(loop);
uv_async_send(&loop_wakeup);
// wait for loop to successfully closeloop_mutex.lock();(gdb) info threads
Id Target Id Frame
* 1 Thread 0x7f58cffff700 (LWP 10505) 0x00007f58ea4a8765 in raise () from /lib64/libc.so.6
2 Thread 0x7f58ec434980 (LWP 10496) 0x00007f58ea842bd0 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
3 Thread 0x7f58e6e56700 (LWP 10500) 0x00007f58ea577307 in epoll_pwait () from /lib64/libc.so.6
4 Thread 0x7f58e7e58700 (LWP 10498) 0x00007f58ea845afd in __lll_lock_wait () from /lib64/libpthread.so.0
5 Thread 0x7f58e8659700 (LWP 10497) 0x00007f58ea577307 in epoll_pwait () from /lib64/libc.so.6
6 Thread 0x7f58cf7fe700 (LWP 10506) 0x00007f58ea56722d in write () from /lib64/libc.so.6
7 Thread 0x7f58e7657700 (LWP 10499) 0x00007f58ea577307 in epoll_pwait () from /lib64/libc.so.6
8 Thread 0x7f58e6655700 (LWP 10501) 0x00007f58ea577307 in epoll_pwait () from /lib64/libc.so.6
9 Thread 0x7f58e5e54700 (LWP 10502) 0x00007f58ea577307 in epoll_pwait () from /lib64/libc.so.6
10 Thread 0x7f58e4e52700 (LWP 10504) 0x00007f58ea577307 in epoll_pwait () from /lib64/libc.so.6
11 Thread 0x7f58e5653700 (LWP 10503) 0x00007f58ea577307 in epoll_pwait () from /lib64/libc.so.6
#0 0x00007f58ea4a8765 in raise () from /lib64/libc.so.6
#1 0x00007f58ea4aa483 in abort () from /lib64/libc.so.6
#2 0x00000000004b7a23 in MagickPanicSignalHandler (signo=11) at magick/magick.c:835
#3 <signal handler called>
#4 0x0000000000813162 in heap_remove (less_than=0x812fc0 <timer_less_than>, node=0x7ffddd63ec98, heap=0xc28a28 <default_loop_struct+520>) at ./src/heap-inl.h:187
#5 uv_timer_stop (handle=0x7ffddd63ec30) at src/unix/timer.c:97
#6 0x000000000081341d in uv_timer_start (handle=0xffffffffffffff98, cb=<optimized out>, timeout=<optimized out>, repeat=<optimized out>) at src/unix/timer.c:87
#7 0x00007ffddd63ebf0 in ?? ()
#8 0x0000000000417c74 in imageresizer::engine::FileDownloader::start_timeout (this=0x1f1, multi=0x7f58eb73ca60, timeout_ms=140019881360094) at src/engine/FileDownloader.cpp:249
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) bt
#0 0x00007f58ea845afd in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x00007f58ea83fa0d in pthread_mutex_lock () from /lib64/libpthread.so.0
#2 0x0000000000416d81 in __gthread_mutex_lock (__mutex=0x7ffddd63ed70) at /usr/include/c++/6.3.1/x86_64-redhat-linux/bits/gthr-default.h:748
#3 0x0000000000418032 in std::mutex::lock (this=0x7ffddd63ed70) at /usr/include/c++/6.3.1/bits/std_mutex.h:101
#4 0x0000000000418209 in imageresizer::util::Lock::Lock (this=0x7f58e7e57a70, m=...) at ./src/util/Lock.h:21
#5 0x0000000000417b77 in imageresizer::engine::FileDownloader::on_timeout (this=0x7ffddd63ebf0, handle=0x7ffddd63ec30) at src/engine/FileDownloader.cpp:230
#6 0x0000000000417b48 in imageresizer::engine::FileDownloader::on_timeout_cb (handle=0x7ffddd63ec30) at src/engine/FileDownloader.cpp:223
#7 0x0000000000813515 in uv__run_timers (loop=0x7ffddd63ed70) at src/unix/timer.c:159
#8 0x000000000080bf3c in uv__update_time (loop=0xc28820 <default_loop_struct>) at src/unix/internal.h:316
#9 uv_run (loop=0xc28820 <default_loop_struct>, mode=UV_RUN_DEFAULT) at src/unix/core.c:342
#10 0x0000000000417474 in imageresizer::engine::FileDownloader::StartLoop (this=0x7ffddd63ebf0) at src/engine/FileDownloader.cpp:96
#11 0x000000000041979a in std::__invoke_impl<void, void (imageresizer::engine::FileDownloader::* const&)(), imageresizer::engine::FileDownloader*>(std::__invoke_memfun_deref, void (imageresizer::engine::FileDownloader::* const&)(), image
resizer::engine::FileDownloader*&&) (
__f=@0x1a323f0: (void (imageresizer::engine::FileDownloader::*)(imageresizer::engine::FileDownloader * const)) 0x4173e4 <imageresizer::engine::FileDownloader::Add(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocato
r<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::function<void ()>, std::function<void (imageresizer::DownloadFileError const&)>)+670>,
__t=<unknown type in /opt/WP/imageresizer-worker/dist/Debug/GNU-Linux/imageresizer-worker, CU 0x1cd0b, DIE 0x2a784>) at /usr/include/c++/6.3.1/functional:227
#12 0x0000000000419727 in std::__invoke<void (imageresizer::engine::FileDownloader::* const&)(), imageresizer::engine::FileDownloader*>(void (imageresizer::engine::FileDownloader::* const&)(), imageresizer::engine::FileDownloader*&&) (
__fn=@0x1a323f0: (void (imageresizer::engine::FileDownloader::*)(imageresizer::engine::FileDownloader * const)) 0x4173e4 <imageresizer::engine::FileDownloader::Add(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocat
or<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::function<void ()>, std::function<void (imageresizer::DownloadFileError const&)>)+670>,
__args#0=<unknown type in /opt/WP/imageresizer-worker/dist/Debug/GNU-Linux/imageresizer-worker, CU 0x1cd0b, DIE 0x2a784>) at /usr/include/c++/6.3.1/functional:251
#13 0x00000000004196d8 in std::_Mem_fn_base<void (imageresizer::engine::FileDownloader::*)(), true>::operator()<imageresizer::engine::FileDownloader*>(imageresizer::engine::FileDownloader*&&) const (this=0x1a323f0,
__args#0=<unknown type in /opt/WP/imageresizer-worker/dist/Debug/GNU-Linux/imageresizer-worker, CU 0x1cd0b, DIE 0x2a784>) at /usr/include/c++/6.3.1/functional:604
#14 0x00000000004196a3 in std::_Bind_simple<std::_Mem_fn<void (imageresizer::engine::FileDownloader::*)()> (imageresizer::engine::FileDownloader*)>::_M_invoke<0ul>(std::_Index_tuple<0ul>) (this=0x1a323e8)
at /usr/include/c++/6.3.1/functional:1390
#15 0x00000000004195f1 in std::_Bind_simple<std::_Mem_fn<void (imageresizer::engine::FileDownloader::*)()> (imageresizer::engine::FileDownloader*)>::operator()() (this=0x1a323e8) at /usr/include/c++/6.3.1/functional:1380
#16 0x00000000004195d0 in std::thread::_State_impl<std::_Bind_simple<std::_Mem_fn<void (imageresizer::engine::FileDownloader::*)()> (imageresizer::engine::FileDownloader*)> >::_M_run() (this=0x1a323e0)
at /usr/include/c++/6.3.1/thread:196
#17 0x00007f58eb02d5cf in ?? () from /lib64/libstdc++.so.6
#18 0x00007f58ea83d5ca in start_thread () from /lib64/libpthread.so.0
#19 0x00007f58ea5770ed in clone () from /lib64/libc.so.6
__fn=@0x1a323f0: (void (imageresizer::engine::FileDownloader<span
(gdb) info threads
Id Target Id Frame
* 1 Thread 0x7f1c5550f700 (LWP 10974) 0x00007f1c57b5f765 in raise () from /lib64/libc.so.6
2 Thread 0x7f1c59aeb980 (LWP 10972) 0x00007f1c57ef9bd0 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
3 Thread 0x7f1c55d10700 (LWP 10973) 0x00007f1c57c2e307 in epoll_pwait () from /lib64/libc.so.6
4 Thread 0x7f1c4ffff700 (LWP 10976) 0x00007f1c57c2e307 in epoll_pwait () from /lib64/libc.so.6
5 Thread 0x7f1c4effd700 (LWP 10978) 0x00007f1c57c2e307 in epoll_pwait () from /lib64/libc.so.6
6 Thread 0x7f1c4d7fa700 (LWP 10981) 0x00007f1c57c2e307 in epoll_pwait () from /lib64/libc.so.6
7 Thread 0x7f1c4dffb700 (LWP 10980) 0x00007f1c57c2e307 in epoll_pwait () from /lib64/libc.so.6
8 Thread 0x7f1c4f7fe700 (LWP 10977) 0x00007f1c57c2e307 in epoll_pwait () from /lib64/libc.so.6
9 Thread 0x7f1c4e7fc700 (LWP 10979) 0x00007f1c57c2e307 in epoll_pwait () from /lib64/libc.so.6
10 Thread 0x7f1c54d0e700 (LWP 10975) 0x00007f1c57c2e307 in epoll_pwait () from /lib64/libc.so.6
11 Thread 0x7f1c4cff9700 (LWP 10982) 0x00007f1c57c2e307 in epoll_pwait () from /lib64/libc.so.6
(gdb) bt
#0 0x00007f1c57b5f765 in raise () from /lib64/libc.so.6
#1 0x00007f1c57b61483 in abort () from /lib64/libc.so.6
#2 0x00000000004b7a23 in GetMagickInfoArray (exception=0xc28820 <default_loop_ptr>) at magick/magick.c:548
#3 0x0000000000000000 in ?? ()
(gdb) bt
#0 0x00007efd3665a765 in raise () from /lib64/libc.so.6
#1 0x00007efd3665c483 in abort () from /lib64/libc.so.6
#2 0x00000000004b79b3 in MagickPanicSignalHandler (signo=11) at magick/magick.c:840
#3 <signal handler called>
#4 heap_insert (less_than=0x812f40 <timer_less_than>, newnode=0x7ffd799e8ab8, heap=0xc28a28 <default_loop_struct+520>) at ./src/heap-inl.h:140
#5 uv_timer_start (handle=0x7ffd799e8a50, cb=0x417abe <imageresizer::engine::FileDownloader::on_timeout_cb(uv_timer_s*)>, timeout=<optimized out>, repeat=0) at src/unix/timer.c:84
#6 0x0000000000417c0c in imageresizer::engine::FileDownloader::start_timeout (this=0x7ffd799e8a10, multi=0x2c0cdd0, timeout_ms=96) at src/engine/FileDownloader.cpp:249
#7 0x0000000000417baf in imageresizer::engine::FileDownloader::start_timeout_cb (multi=0x2c0cdd0, timeout_ms=96, userp=0x7ffd799e8a10) at src/engine/FileDownloader.cpp:237
#8 0x00000000007c7665 in update_timer ()
#9 0x00000000007cb098 in curl_multi_socket_action ()
#10 0x0000000000417b3f in imageresizer::engine::FileDownloader::on_timeout (this=0x7ffd799e8a10, handle=0x7ffd799e8a50) at src/engine/FileDownloader.cpp:231
#11 0x0000000000417ae0 in imageresizer::engine::FileDownloader::on_timeout_cb (handle=0x7ffd799e8a50) at src/engine/FileDownloader.cpp:223
#12 0x00000000008134a5 in uv__run_timers (loop=loop@entry=0xc28820 <default_loop_struct>) at src/unix/timer.c:165
#13 0x000000000080becc in uv_run (loop=0xc28820 <default_loop_struct>, mode=UV_RUN_DEFAULT) at src/unix/core.c:343
#14 0x0000000000417409 in imageresizer::engine::FileDownloader::StartLoop (this=0x7ffd799e8a10) at src/engine/FileDownloader.cpp:97
--
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 libuv+un...@googlegroups.com.
To post to this group, send email to li...@googlegroups.com.
Visit this group at https://groups.google.com/group/libuv.
For more options, visit https://groups.google.com/d/optout.
I'm about to compile and try rr. Meanwhile I've run my code in the production environment and caught some segmentation faults. I'd be pleased if you take a look: https://docs.google.com/document/d/1hOX9FLcx5N6gdLQ-aAMwNpPqCzpfXqDKjNaHqFGGbSY/edit?usp=sharing
<thread id>
I0605 11:46:54.860105 22880 FileDownloader.cpp:107] File downloading loop started
I0605 11:47:03.028491 22883 FileDownloader.cpp:254] start timeout 0ms
I0605 11:47:03.028506 22883 FileDownloader.cpp:265] /start timeout
I0605 11:47:03.028512 22883 FileDownloader.cpp:103] Downloading http://i.wp.pl/a/f/jpeg/37211/sarah-cover-photo-1280x.jpeg?i=0 -> /tmp/ir.download
I0605 11:47:03.029150 22880 FileDownloader.cpp:273] handle_socket (action: 2, socket: 0)
I0605 11:47:03.029168 22880 FileDownloader.cpp:303] /handle_socket
I0605 11:47:03.029171 22880 FileDownloader.cpp:254] start timeout 0ms
I0605 11:47:03.029173 22880 FileDownloader.cpp:265] /start timeout
I0605 11:47:03.030094 22880 FileDownloader.cpp:273] handle_socket (action: 1, socket: 0x7fc9d0002920)
I0605 11:47:03.030102 22880 FileDownloader.cpp:303] /handle_socket
I0605 11:47:03.030105 22880 FileDownloader.cpp:254] start timeout 199ms
I0605 11:47:03.030107 22880 FileDownloader.cpp:265] /start timeout
I0605 11:47:03.047816 22880 FileDownloader.cpp:273] handle_socket (action: 4, socket: 0x7fc9d0002920)
I0605 11:47:03.047832 22880 FileDownloader.cpp:303] /handle_socket
I0605 11:47:03.047835 22880 FileDownloader.cpp:192] Finished http://i.wp.pl/a/f/jpeg/37211/sarah-cover-photo-1280x.jpeg?i=0 (0 - No error, code: 200, time: 19.287 ms, speed: 250303 kb/s)
I0605 11:47:03.047858 22880 FileDownloader.cpp:254] start timeout -1ms
I0605 11:47:03.047863 22880 FileDownloader.cpp:265] /start timeout
I suggest you re-read my suggestion a few emails back. Move handling of the entire curl handle to the uv thread with a queue, a muted and an async handle.
-Saúl
synchronized(request_queue_mutex) { request_queue.data = curl_easy_handle; uv_queue_work(loop, &request_queue, [](uv_work_t* req) {}, [](uv_work_t* req, int status) { LOG(INFO) << "working done: "; curl_multi_add_handle(curl_handle, (CURL *) req->data); });}
==18186== Process terminating with default action of signal 6 (SIGABRT): dumping core
==18186== at 0x687C765: raise (in /usr/lib64/libc-2.23.so)
==18186== by 0x687E482: abort (in /usr/lib64/libc-2.23.so)
==18186== by 0x4B7D52: MagickPanicSignalHandler (magick.c:840)
==18186== by 0x663CC2F: ??? (in /usr/lib64/libpthread-2.23.so)
==18186== by 0xC29997: ???
==18186== by 0x80A30B: uv__work_done (threadpool.c:245)
==18186== by 0x80C0FA: uv__async_io (async.c:118)
==18186== by 0x8161F7: uv__io_poll (linux-core.c:400)
==18186== by 0x80C923: uv_run (core.c:359)
==18186== by 0x41768C: imageresizer::engine::FileDownloader::StartLoop() (FileDownloader.cpp:103)
==18186== by 0x4199A3: void std::__invoke_impl<void, void (imageresizer::engine::FileDownloader::* const&)(), imageresizer::engine::FileDownloader*>(std::__invoke_memfun_deref, void (imageresizer::engine::FileDownloader::* const&)(),
imageresizer::engine::FileDownloader*&&) (functional:227)
==18186== by 0x419930: std::result_of<void (imageresizer::engine::FileDownloader::* const&(imageresizer::engine::FileDownloader*&&))()>::type std::__invoke<void (imageresizer::engine::FileDownloader::* const&)(), imageresizer::engine:
:FileDownloader*>(void (imageresizer::engine::FileDownloader::* const&)(), imageresizer::engine::FileDownloader*&&) (functional:251)
You must make the curl_multi_add_handle function run in the loop
thread. An async handle could help you with that. But watch out with
where you call uv_async_init, only, I repeat *ONLY* uv_async_send is
thread-safe.