specifying hostname that does not have dns resolution causes a thread leak #245

Closed
Sneaktip18 opened this Issue Jun 3, 2013 · 11 comments

Comments

Projects
None yet
2 participants
@Sneaktip18

If we specify a non-resolvable hostname when trying to send a "DELETE" http request, the exception of Host Not Found is generated however the call to join in the destructor of the async_impl class never returns and thread will remain, eventually if we continue running in this mode we will run out of memory due to keeping these threads alive... When reproducing this issue we see hundreds of threads with the backtrace below:
#0 0xffffe402 in __kernel_vsyscall ()
#1 0x008de779 in __lll_lock_wait () from /lib/libpthread.so.0
#2 0x008d9ddf in L_lock_885 () from /lib/libpthread.so.0
#3 0x008d9ca6 in pthread_mutex_lock () from /lib/libpthread.so.0
#4 0x080c4fc8 in boost::mutex::lock (this=0xefb91298) at /builds/ExternalLibs/boost/V1_48_0/boost/thread/pthread/mutex.hpp:52
#5 0x080c50d5 in boost::lock_guardboost::mutex::lock_guard (this=0xdb0e4e90, m
=...)

at /builds/ExternalLibs/boost/V1_48_0/boost/thread/locks.hpp:257

#6 0x080dd126 in boost::detail::interruption_checker::interruption_checker(._9 *, ._12 *) (this=0xdb0e4ebc, cond_mutex=0xefb912b0,

cond=0xefb912c8) at /builds/ExternalLibs/boost/V1_48_0/boost/thread/pthread/thread_data.hpp:101

#7 0x080dd221 in boost::condition_variable::wait (this=0xefb912b0, m=...)

at /builds/ExternalLibs/boost/V1_48_0/boost/thread/pthread/condition_variable.hpp:53

#8 0x088044c1 in boost::thread::join() ()
#9 0x08196b33 in boost::network::http::impl::async_client<boost::network::http::tags::http_async_8bit_udp_resolve, 1u, 1u>::~async_client

(this=0xefb93e98, __in_chrg=<value optimized out>)

at /home/rrobertelli/cpp-netlib-0.9-devel/boost/network/protocol/http/client/async_impl.hpp:71

#10 0x08196db9 in boost::network::http::basic_client_impl<boost::network::http::tags::http_async_8bit_udp_resolve, 1u, 1u>::~basic_client_impl (this=0xefb93e98, __in_chrg=)

at /home/rrobertelli/cpp-netlib-0.9-devel/boost/network/protocol/http/client/pimpl.hpp:74

#11 0x08196dd9 in boost::checked_delete<boost::network::http::basic_client_impl<boost::network::http::tags::http_async_8bit_udp_resolve, 1u, 1u> > (x=0xefb93e98) at /builds/ExternalLibs/boost/V1_48_0/boost/checked_delete.hpp:34

Any information on how to work around this problem would be greatly appreciated...
Thanks,
Robert

@Sneaktip18

This comment has been minimized.

Show comment
Hide comment
@Sneaktip18

Sneaktip18 Jun 3, 2013

Also forgot to mention that this was reproduce don 0.9.4 version of cppnetlib...

Also forgot to mention that this was reproduce don 0.9.4 version of cppnetlib...

@deanberris

This comment has been minimized.

Show comment
Hide comment
@deanberris

deanberris Jun 4, 2013

Member

Can you please post a minimal reproduction of the case? Also I suppose you're creating one client every time you're making a request which is not good -- you should use the same client in multiple threads.

Also I see that you're using Boost 1.48, is it possible for you to use a later version of Boost?

Member

deanberris commented Jun 4, 2013

Can you please post a minimal reproduction of the case? Also I suppose you're creating one client every time you're making a request which is not good -- you should use the same client in multiple threads.

Also I see that you're using Boost 1.48, is it possible for you to use a later version of Boost?

@Sneaktip18

This comment has been minimized.

Show comment
Hide comment
@Sneaktip18

Sneaktip18 Jun 14, 2013

Sorry this took so long, however here is a standalone application that reproduces the problem...

#include <stdio.h>
#include
#include <boost/thread.hpp>
#include <boost/network/protocol/http/client.hpp>

void sendRequest(const char* hostname)
{
namespace http = boost::network::http;
try
{
http::client client;
http::client::request request(hostname);
http::client::response response = client.delete_(request);
int status = response.status();

    if (status == 200)
    {
        std::cout << "request successfull..." << std::endl;
    }
    else
    {
        std::cout << "request completed with status: " << status << std::endl;
    }
}
catch (std::exception& e)
{
    std::cout << "Send Request Exception... ERROR=" << e.what() << std::endl;
}
catch (...)
{
    std::cout << "Send Request Exception..." << std::endl;
}

}

int main(int argc, char* argv[])
{
std::cout << "Sending Request Test" << std::endl;
std::string hostname("http://doesnotexist.google.com");
if (argc == 2)
{
hostname = argv[1];
}

int loop = 0;
while (loop++ < 50)
{
    std::cout << "MAIN: [LOOP=" << loop << "] - starting thread..." << std::endl;
    boost::thread workerThread(sendRequest, hostname.c_str());
    std::cout << "MAIN: waiting for thread..." << std::endl;
    workerThread.join();
    std::cout << "MAIN: thread done..., sleeping..." << std::endl;
    sleep(10);
}

return 0;

}

The following is my run via gdb.... you will notice that every 10 seconds we spawn a thread that makes a request and that request throws an exception, however in the process of trying to fulfill that request cppnetlib spawns 2 threads of its own that never exit. One of those threads seems to be waiting on join() while the other seems to be blocked by a mutex... see backtraces below:

The following shows how threads are being leaked...

GNU gdb (GDB) CentOS (7.0.1-45.el5.centos)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
http://www.gnu.org/software/gdb/bugs/...
Reading symbols from /home/rrobertelli/sandbox/cppnetlib/test...(no debugging symbols found)...done.

(gdb) run http://doesnotexist.google.com

Starting program: /home/rrobertelli/sandbox/cppnetlib/test http://doesnotexist.google.com
[Thread debugging using libthread_db enabled]
Sending Request Test
MAIN: [LOOP=1] - starting thread...
[New Thread 0xf7fe6b90 (LWP 13843)]
MAIN: waiting for thread...
[New Thread 0xf75e5b90 (LWP 13844)]
[New Thread 0xf6be4b90 (LWP 13845)]
Send Request Exception... ERROR=Host not found (authoritative)
MAIN: thread done..., sleeping...
[Thread 0xf7fe6b90 (LWP 13843) exited]
MAIN: [LOOP=2] - starting thread...
[New Thread 0xf7fe6b90 (LWP 13846)]
MAIN: waiting for thread...
[New Thread 0xf61bab90 (LWP 13847)]
[New Thread 0xf57b9b90 (LWP 13848)]
Send Request Exception... ERROR=Host not found (authoritative)
MAIN: thread done..., sleeping...
[Thread 0xf7fe6b90 (LWP 13846) exited]

Program received signal SIGINT, Interrupt.

0xffffe410 in __kernel_vsyscall ()
(gdb) info threads
7 Thread 0xf57b9b90 (LWP 13848) 0xffffe410 in __kernel_vsyscall ()
6 Thread 0xf61bab90 (LWP 13847) 0xffffe410 in __kernel_vsyscall ()
4 Thread 0xf6be4b90 (LWP 13845) 0xffffe410 in __kernel_vsyscall ()
3 Thread 0xf75e5b90 (LWP 13844) 0xffffe410 in __kernel_vsyscall ()

  • 1 Thread 0xf7fe76d0 (LWP 13840) 0xffffe410 in __kernel_vsyscall ()

I then continue running application and more threads leak...

(gdb) continue

Continuing.
MAIN: [LOOP=3] - starting thread...
[New Thread 0xf7fe6b90 (LWP 13849)]
MAIN: waiting for thread...
[New Thread 0xf4db8b90 (LWP 13850)]
[New Thread 0xf43b7b90 (LWP 13851)]
Send Request Exception... ERROR=Host not found (authoritative)
MAIN: thread done..., sleeping...
[Thread 0xf7fe6b90 (LWP 13849) exited]
MAIN: [LOOP=4] - starting thread...
[New Thread 0xf7fe6b90 (LWP 13852)]
MAIN: waiting for thread...
[New Thread 0xf39b6b90 (LWP 13853)]
[New Thread 0xf2fb5b90 (LWP 13854)]
Send Request Exception... ERROR=Host not found (authoritative)
MAIN: thread done..., sleeping...
[Thread 0xf7fe6b90 (LWP 13852) exited]
MAIN: [LOOP=5] - starting thread...
[New Thread 0xf7fe6b90 (LWP 13857)]
MAIN: waiting for thread...
[New Thread 0xf25b4b90 (LWP 13858)]
[New Thread 0xf19ffb90 (LWP 13859)]
Send Request Exception... ERROR=Host not found (authoritative)
MAIN: thread done..., sleeping...
[Thread 0xf7fe6b90 (LWP 13857) exited]

Program received signal SIGINT, Interrupt.
0xffffe410 in __kernel_vsyscall ()
(gdb) info threads
16 Thread 0xf19ffb90 (LWP 13859) 0xffffe410 in __kernel_vsyscall ()
15 Thread 0xf25b4b90 (LWP 13858) 0xffffe410 in __kernel_vsyscall ()
13 Thread 0xf2fb5b90 (LWP 13854) 0xffffe410 in __kernel_vsyscall ()
12 Thread 0xf39b6b90 (LWP 13853) 0xffffe410 in __kernel_vsyscall ()
10 Thread 0xf43b7b90 (LWP 13851) 0xffffe410 in __kernel_vsyscall ()
9 Thread 0xf4db8b90 (LWP 13850) 0xffffe410 in __kernel_vsyscall ()
7 Thread 0xf57b9b90 (LWP 13848) 0xffffe410 in __kernel_vsyscall ()
6 Thread 0xf61bab90 (LWP 13847) 0xffffe410 in __kernel_vsyscall ()
4 Thread 0xf6be4b90 (LWP 13845) 0xffffe410 in __kernel_vsyscall ()
3 Thread 0xf75e5b90 (LWP 13844) 0xffffe410 in __kernel_vsyscall ()

  • 1 Thread 0xf7fe76d0 (LWP 13840) 0xffffe410 in __kernel_vsyscall ()

The following is the backtrace of the 2 threads we leak on every loop.

(gdb) thread 15

[Switching to thread 15 (Thread 0xf25b4b90 (LWP 13858))]#0 0xffffe410 in __kernel_vsyscall ()

(gdb) bt

#0 0xffffe410 in __kernel_vsyscall ()
#1 0x007c9839 in _lll_lock_wait () from /lib/libpthread.so.0
#2 0x007c4e9f in L_lock_885 () from /lib/libpthread.so.0
#3 0x007c4d66 in pthread_mutex_lock () from /lib/libpthread.so.0
#4 0x08072bb0 in boost::mutex::lock() ()
#5 0x08072c17 in boost::lock_guardboost::mutex::lock_guard(boost::mutex&) ()
#6 0x08094552 in boost::detail::interruption_checker::interruption_checker(pthread_mutex_t
, pthread_cond_t
) ()
#7 0x0809464d in boost::condition_variable::wait(boost::unique_lockboost::mutex&) ()
#8 0x080971f1 in boost::thread::join() ()
#9 0x0807098b in boost::network::http::impl::async_client<boost::network::http::tags::http_async_8bit_udp_resolve, 1u, 1u>::~async_client() ()
#10 0x08070b67 in boost::network::http::basic_client_impl<boost::network::http::tags::http_async_8bit_udp_resolve, 1u, 1u>::~basic_client_impl() ()

The other thread's backtrace...

(gdb) thread 16

[Switching to thread 16 (Thread 0xf19ffb90 (LWP 13859))]#0 0xffffe410 in __kernel_vsyscall ()

(gdb) bt
#0 0xffffe410 in __kernel_vsyscall ()
#1 0x007c6cc5 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0
#2 0x08076416 in void boost::asio::detail::posix_event::waitboost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex >(boost::asio::detail::scoped_lockboost::asio::detail::posix_mutex&) ()
#3 0x0807666d in boost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lockboost::asio::detail::posix_mutex&, boost::asio::detail::task_io_service::thread_info&, boost::asio::detail::op_queueboost::asio::detail::task_io_service_operation&, boost::system::error_code const&) ()
#4 0x080767a0 in boost::asio::detail::task_io_service::run(boost::system::error_code&) ()
#5 0x08076868 in boost::asio::io_service::run() ()
#6 0x0807688f in boost::asio::detail::resolver_service_base::work_io_service_runner::operator()() ()
#7 0x080768a6 in boost::asio::detail::posix_thread::funcboost::asio::detail::resolver_service_base::work_io_service_runner::run() ()
#8 0x0805d2a8 in boost_asio_detail_posix_thread_function ()
#9 0x007c2912 in start_thread () from /lib/libpthread.so.0
#10 0x0073360e in clone () from /lib/libc.so.6

Thanks,
Robert

Sorry this took so long, however here is a standalone application that reproduces the problem...

#include <stdio.h>
#include
#include <boost/thread.hpp>
#include <boost/network/protocol/http/client.hpp>

void sendRequest(const char* hostname)
{
namespace http = boost::network::http;
try
{
http::client client;
http::client::request request(hostname);
http::client::response response = client.delete_(request);
int status = response.status();

    if (status == 200)
    {
        std::cout << "request successfull..." << std::endl;
    }
    else
    {
        std::cout << "request completed with status: " << status << std::endl;
    }
}
catch (std::exception& e)
{
    std::cout << "Send Request Exception... ERROR=" << e.what() << std::endl;
}
catch (...)
{
    std::cout << "Send Request Exception..." << std::endl;
}

}

int main(int argc, char* argv[])
{
std::cout << "Sending Request Test" << std::endl;
std::string hostname("http://doesnotexist.google.com");
if (argc == 2)
{
hostname = argv[1];
}

int loop = 0;
while (loop++ < 50)
{
    std::cout << "MAIN: [LOOP=" << loop << "] - starting thread..." << std::endl;
    boost::thread workerThread(sendRequest, hostname.c_str());
    std::cout << "MAIN: waiting for thread..." << std::endl;
    workerThread.join();
    std::cout << "MAIN: thread done..., sleeping..." << std::endl;
    sleep(10);
}

return 0;

}

The following is my run via gdb.... you will notice that every 10 seconds we spawn a thread that makes a request and that request throws an exception, however in the process of trying to fulfill that request cppnetlib spawns 2 threads of its own that never exit. One of those threads seems to be waiting on join() while the other seems to be blocked by a mutex... see backtraces below:

The following shows how threads are being leaked...

GNU gdb (GDB) CentOS (7.0.1-45.el5.centos)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
http://www.gnu.org/software/gdb/bugs/...
Reading symbols from /home/rrobertelli/sandbox/cppnetlib/test...(no debugging symbols found)...done.

(gdb) run http://doesnotexist.google.com

Starting program: /home/rrobertelli/sandbox/cppnetlib/test http://doesnotexist.google.com
[Thread debugging using libthread_db enabled]
Sending Request Test
MAIN: [LOOP=1] - starting thread...
[New Thread 0xf7fe6b90 (LWP 13843)]
MAIN: waiting for thread...
[New Thread 0xf75e5b90 (LWP 13844)]
[New Thread 0xf6be4b90 (LWP 13845)]
Send Request Exception... ERROR=Host not found (authoritative)
MAIN: thread done..., sleeping...
[Thread 0xf7fe6b90 (LWP 13843) exited]
MAIN: [LOOP=2] - starting thread...
[New Thread 0xf7fe6b90 (LWP 13846)]
MAIN: waiting for thread...
[New Thread 0xf61bab90 (LWP 13847)]
[New Thread 0xf57b9b90 (LWP 13848)]
Send Request Exception... ERROR=Host not found (authoritative)
MAIN: thread done..., sleeping...
[Thread 0xf7fe6b90 (LWP 13846) exited]

Program received signal SIGINT, Interrupt.

0xffffe410 in __kernel_vsyscall ()
(gdb) info threads
7 Thread 0xf57b9b90 (LWP 13848) 0xffffe410 in __kernel_vsyscall ()
6 Thread 0xf61bab90 (LWP 13847) 0xffffe410 in __kernel_vsyscall ()
4 Thread 0xf6be4b90 (LWP 13845) 0xffffe410 in __kernel_vsyscall ()
3 Thread 0xf75e5b90 (LWP 13844) 0xffffe410 in __kernel_vsyscall ()

  • 1 Thread 0xf7fe76d0 (LWP 13840) 0xffffe410 in __kernel_vsyscall ()

I then continue running application and more threads leak...

(gdb) continue

Continuing.
MAIN: [LOOP=3] - starting thread...
[New Thread 0xf7fe6b90 (LWP 13849)]
MAIN: waiting for thread...
[New Thread 0xf4db8b90 (LWP 13850)]
[New Thread 0xf43b7b90 (LWP 13851)]
Send Request Exception... ERROR=Host not found (authoritative)
MAIN: thread done..., sleeping...
[Thread 0xf7fe6b90 (LWP 13849) exited]
MAIN: [LOOP=4] - starting thread...
[New Thread 0xf7fe6b90 (LWP 13852)]
MAIN: waiting for thread...
[New Thread 0xf39b6b90 (LWP 13853)]
[New Thread 0xf2fb5b90 (LWP 13854)]
Send Request Exception... ERROR=Host not found (authoritative)
MAIN: thread done..., sleeping...
[Thread 0xf7fe6b90 (LWP 13852) exited]
MAIN: [LOOP=5] - starting thread...
[New Thread 0xf7fe6b90 (LWP 13857)]
MAIN: waiting for thread...
[New Thread 0xf25b4b90 (LWP 13858)]
[New Thread 0xf19ffb90 (LWP 13859)]
Send Request Exception... ERROR=Host not found (authoritative)
MAIN: thread done..., sleeping...
[Thread 0xf7fe6b90 (LWP 13857) exited]

Program received signal SIGINT, Interrupt.
0xffffe410 in __kernel_vsyscall ()
(gdb) info threads
16 Thread 0xf19ffb90 (LWP 13859) 0xffffe410 in __kernel_vsyscall ()
15 Thread 0xf25b4b90 (LWP 13858) 0xffffe410 in __kernel_vsyscall ()
13 Thread 0xf2fb5b90 (LWP 13854) 0xffffe410 in __kernel_vsyscall ()
12 Thread 0xf39b6b90 (LWP 13853) 0xffffe410 in __kernel_vsyscall ()
10 Thread 0xf43b7b90 (LWP 13851) 0xffffe410 in __kernel_vsyscall ()
9 Thread 0xf4db8b90 (LWP 13850) 0xffffe410 in __kernel_vsyscall ()
7 Thread 0xf57b9b90 (LWP 13848) 0xffffe410 in __kernel_vsyscall ()
6 Thread 0xf61bab90 (LWP 13847) 0xffffe410 in __kernel_vsyscall ()
4 Thread 0xf6be4b90 (LWP 13845) 0xffffe410 in __kernel_vsyscall ()
3 Thread 0xf75e5b90 (LWP 13844) 0xffffe410 in __kernel_vsyscall ()

  • 1 Thread 0xf7fe76d0 (LWP 13840) 0xffffe410 in __kernel_vsyscall ()

The following is the backtrace of the 2 threads we leak on every loop.

(gdb) thread 15

[Switching to thread 15 (Thread 0xf25b4b90 (LWP 13858))]#0 0xffffe410 in __kernel_vsyscall ()

(gdb) bt

#0 0xffffe410 in __kernel_vsyscall ()
#1 0x007c9839 in _lll_lock_wait () from /lib/libpthread.so.0
#2 0x007c4e9f in L_lock_885 () from /lib/libpthread.so.0
#3 0x007c4d66 in pthread_mutex_lock () from /lib/libpthread.so.0
#4 0x08072bb0 in boost::mutex::lock() ()
#5 0x08072c17 in boost::lock_guardboost::mutex::lock_guard(boost::mutex&) ()
#6 0x08094552 in boost::detail::interruption_checker::interruption_checker(pthread_mutex_t
, pthread_cond_t
) ()
#7 0x0809464d in boost::condition_variable::wait(boost::unique_lockboost::mutex&) ()
#8 0x080971f1 in boost::thread::join() ()
#9 0x0807098b in boost::network::http::impl::async_client<boost::network::http::tags::http_async_8bit_udp_resolve, 1u, 1u>::~async_client() ()
#10 0x08070b67 in boost::network::http::basic_client_impl<boost::network::http::tags::http_async_8bit_udp_resolve, 1u, 1u>::~basic_client_impl() ()

The other thread's backtrace...

(gdb) thread 16

[Switching to thread 16 (Thread 0xf19ffb90 (LWP 13859))]#0 0xffffe410 in __kernel_vsyscall ()

(gdb) bt
#0 0xffffe410 in __kernel_vsyscall ()
#1 0x007c6cc5 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0
#2 0x08076416 in void boost::asio::detail::posix_event::waitboost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex >(boost::asio::detail::scoped_lockboost::asio::detail::posix_mutex&) ()
#3 0x0807666d in boost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lockboost::asio::detail::posix_mutex&, boost::asio::detail::task_io_service::thread_info&, boost::asio::detail::op_queueboost::asio::detail::task_io_service_operation&, boost::system::error_code const&) ()
#4 0x080767a0 in boost::asio::detail::task_io_service::run(boost::system::error_code&) ()
#5 0x08076868 in boost::asio::io_service::run() ()
#6 0x0807688f in boost::asio::detail::resolver_service_base::work_io_service_runner::operator()() ()
#7 0x080768a6 in boost::asio::detail::posix_thread::funcboost::asio::detail::resolver_service_base::work_io_service_runner::run() ()
#8 0x0805d2a8 in boost_asio_detail_posix_thread_function ()
#9 0x007c2912 in start_thread () from /lib/libpthread.so.0
#10 0x0073360e in clone () from /lib/libc.so.6

Thanks,
Robert

@deanberris

This comment has been minimized.

Show comment
Hide comment
@deanberris

deanberris Jun 29, 2013

Member

Sorry for the late response too -- can you try 0.10.0 which I think this issue has been fixed? Please find the links to http://cpp-netlib.org/.

Just looking at this my advice would be to not create many client instances, and just re-use a single one. The trick would be to instantiate a single client and hold on to it with a shared_ptr, and copy that to every function that will run in a thread. The client object is thread-safe and is meant to be used across multiple threads anyway.

Member

deanberris commented Jun 29, 2013

Sorry for the late response too -- can you try 0.10.0 which I think this issue has been fixed? Please find the links to http://cpp-netlib.org/.

Just looking at this my advice would be to not create many client instances, and just re-use a single one. The trick would be to instantiate a single client and hold on to it with a shared_ptr, and copy that to every function that will run in a thread. The client object is thread-safe and is meant to be used across multiple threads anyway.

@deanberris

This comment has been minimized.

Show comment
Hide comment
@deanberris

deanberris Jul 3, 2013

Member

Can you confirm whether this is still the case in 0.10.0? If this is still happening, please re-open the issue and I'll look into reproducing and debugging this properly.

Member

deanberris commented Jul 3, 2013

Can you confirm whether this is still the case in 0.10.0? If this is still happening, please re-open the issue and I'll look into reproducing and debugging this properly.

@deanberris deanberris closed this Jul 3, 2013

@ghost ghost assigned deanberris Aug 5, 2013

@deanberris deanberris reopened this Aug 5, 2013

@deanberris

This comment has been minimized.

Show comment
Hide comment
@deanberris

deanberris Aug 5, 2013

Member

So I think I've found where this is, and I have a fix that's ready for testing soon.

Member

deanberris commented Aug 5, 2013

So I think I've found where this is, and I have a fix that's ready for testing soon.

deanberris added a commit that referenced this issue Aug 14, 2013

Body generator for PUT/POST APIs
This commit does the following things:

- Add overloads to the HTTP Client implementation that takes a generator
  callback to generate chunks of the POST or PUT requests.
- Fixes #245 which happens when a resolution error occurs, which leaks
  futures and potentially threads associated with futures.
- Formats the files touched using clang-format in Google's style.

Unfortunately the API cannot be tested without starting a POST/PUT
capable server. A future commit should add an end-to-end test that uses
the HTTP server implementation and the HTTP client implementation to
verify end-to-end correctness.

deanberris added a commit that referenced this issue Aug 14, 2013

Body generator for PUT/POST APIs
This commit does the following things:

- Add overloads to the HTTP Client implementation that takes a generator
  callback to generate chunks of the POST or PUT requests.
- Fixes #245 which happens when a resolution error occurs, which leaks
  futures and potentially threads associated with futures.
- Formats the files touched using clang-format in Google's style.

Unfortunately the API cannot be tested without starting a POST/PUT
capable server. A future commit should add an end-to-end test that uses
the HTTP server implementation and the HTTP client implementation to
verify end-to-end correctness.
@Sneaktip18

This comment has been minimized.

Show comment
Hide comment
@Sneaktip18

Sneaktip18 Sep 30, 2013

Hi Dean,

If you have that fix you mentioned, I will be more than happy to try and
test it out...

Thanks,
Rob

On Mon, Aug 5, 2013 at 9:48 AM, Dean Michael Berris <
notifications@github.com> wrote:

So I think I've found where this is, and I have a fix that's ready for
testing soon.


Reply to this email directly or view it on GitHubhttps://github.com/cpp-netlib/cpp-netlib/issues/245#issuecomment-22107013
.

Hi Dean,

If you have that fix you mentioned, I will be more than happy to try and
test it out...

Thanks,
Rob

On Mon, Aug 5, 2013 at 9:48 AM, Dean Michael Berris <
notifications@github.com> wrote:

So I think I've found where this is, and I have a fix that's ready for
testing soon.


Reply to this email directly or view it on GitHubhttps://github.com/cpp-netlib/cpp-netlib/issues/245#issuecomment-22107013
.

@deanberris

This comment has been minimized.

Show comment
Hide comment
@deanberris

deanberris Sep 30, 2013

Member

You can try the latest in 0.10-devel which does have this fix -- can you confirm that it's fixed there?

Member

deanberris commented Sep 30, 2013

You can try the latest in 0.10-devel which does have this fix -- can you confirm that it's fixed there?

@Sneaktip18

This comment has been minimized.

Show comment
Hide comment
@Sneaktip18

Sneaktip18 Sep 30, 2013

Sure, I will try and do this, thanks... If you can also mention what
revision has the fix, I may want to back port it to 0.9 branch since we are
currently using that branch. We plan on moving forward to latest branch in
next major release..

On Mon, Sep 30, 2013 at 1:19 PM, Dean Michael Berris <
notifications@github.com> wrote:

You can try the latest in 0.10-devel which does have this fix -- can you
confirm that it's fixed there?


Reply to this email directly or view it on GitHubhttps://github.com/cpp-netlib/cpp-netlib/issues/245#issuecomment-25383323
.

Sure, I will try and do this, thanks... If you can also mention what
revision has the fix, I may want to back port it to 0.9 branch since we are
currently using that branch. We plan on moving forward to latest branch in
next major release..

On Mon, Sep 30, 2013 at 1:19 PM, Dean Michael Berris <
notifications@github.com> wrote:

You can try the latest in 0.10-devel which does have this fix -- can you
confirm that it's fixed there?


Reply to this email directly or view it on GitHubhttps://github.com/cpp-netlib/cpp-netlib/issues/245#issuecomment-25383323
.

@deanberris

This comment has been minimized.

Show comment
Hide comment
@deanberris

deanberris Oct 2, 2013

Member

I don't know if this commit will do on top of 0.9.x -- 3f27c3a but that should give you an idea on how/where to fix it.

Member

deanberris commented Oct 2, 2013

I don't know if this commit will do on top of 0.9.x -- 3f27c3a but that should give you an idea on how/where to fix it.

@deanberris

This comment has been minimized.

Show comment
Hide comment
@deanberris

deanberris Nov 24, 2013

Member

This is going into 0.11.0.

Member

deanberris commented Nov 24, 2013

This is going into 0.11.0.

@deanberris deanberris closed this Nov 24, 2013

leecoder pushed a commit to leecoder/cpp-netlib that referenced this issue Apr 14, 2015

Body generator for PUT/POST APIs
This commit does the following things:

- Add overloads to the HTTP Client implementation that takes a generator
  callback to generate chunks of the POST or PUT requests.
- Fixes #245 which happens when a resolution error occurs, which leaks
  futures and potentially threads associated with futures.
- Formats the files touched using clang-format in Google's style.

Unfortunately the API cannot be tested without starting a POST/PUT
capable server. A future commit should add an end-to-end test that uses
the HTTP server implementation and the HTTP client implementation to
verify end-to-end correctness.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment