Description
I recently used cpprest sdk on the centos7.4 operating system to develop a multi-threaded http server and client program, but found that the program tasks often enters wait() and can't quit, is it where I used it wrong?my main code is as follows :
first, I set the receive and send timeouts via http_listener_config like following:
http server side:
http_listener_config listenconfig;
listenconfig.set_timeout(utility::seconds(3));
HttpServerBase(utility::string_t url, http_listener_config& listenconfig, std::string reqcmdid, eRedisListKey redislistkey, RedisConnectPool* connpool, eMapType reqcmdtype, bool bsyncprocess = false)
:m_Listener(url, listenconfig)
{
m_RedisConnPool = std::move(connpool);
m_ReqCommandId = std::move(reqcmdid);
m_RedisListKey = std::move(redislistkey);
m_SyncProcess = bsyncprocess;
m_ReqCmdMapType = std::move(reqcmdtype);
m_Listener.support(methods::POST, std::bind(&HttpServerBase::Handle_Process_Json, this, std::placeholders::_1));
SPDLOG_DEBUG("create HttpServerBase succeed listener url:{}, m_ReqCommandId:{}, m_RedisListKey:{}, m_SyncProcess:{}", url, m_ReqCommandId, m_RedisListKey, m_SyncProcess);
};
//json parse
virtual void Handle_Process_Json(http_request message)
{
try
{
SPDLOG_DEBUG("recv request:{} from remote_address:{}, command:{}", http::uri::decode(message.to_string()), message.remote_address(), m_ReqCommandId);
auto parsetask = message.extract_json().then([&](pplx::task<json::value> previousTask)
{
try
{
SPDLOG_DEBUG("after extract_json");
const json::value& cjsonreq = previousTask.get();
SPDLOG_DEBUG("after previousTask.get()");
message.reply(status_codes::OK);
}
catch (const std::exception& sysexp)
{
SPDLOG_ERROR("occured std::exception:{} when recv:{}", sysexp.what(), m_ReqCommandId);
}
}).wait();
}
catch (const std::exception& sysexp)
{
SPDLOG_ERROR("occured std::exception:{} when recv:{}", sysexp.what(), m_ReqCommandId);
}
catch(...)
{
SPDLOG_ERROR("occured exception");
}
};
http client side:
//first param is desturl
//second param is request's timeout
HttpClientBase(utility::string_t desturl, std::chrono::microseconds timeout)
{
uri_builder builder(desturl);
m_http_client_config.set_timeout(timeout);
m_http_client = new http_client(builder.to_uri().to_string(), m_http_client_config);
};
virtual void SendRequest(const method& mtd, const utility::string_t& path_query_fragment, const json::value& req_body_data)
{
try
{
m_http_client->request(mtd, path_query_fragment, req_body_data).then([=](pplx::task<http_response> task)
{
try
{
//parse response
http_response response = task.get();
SPDLOG_DEBUG("recv response msg from media that rspcode is {}", response.status_code());
if(response.status_code() == status_codes::OK)
{
auto rspbody = response.extract_json().get();
if(rspbody.is_null())
{
SPDLOG_ERROR("rspbody is NULL in ProcessMediaInfo::SendRequest");
return ;
}
processjson(rspbody);
}
}
catch (const http_exception& e)
{
SPDLOG_ERROR("occured http_exception:{}, errorcode:{} in ProcessMediaInfo::SendRequest body:{}", e.what(), e.error_code().message(), req_body_data.serialize());
}
});
}
catch (const std::exception& sysexp)
{
SPDLOG_ERROR("occured std::exception:{} in ProcessMediaInfo::SendRequest", sysexp.what());
}
Does this cpprest sdk support the centos7.4 operating system? Why is this?I found that after the program runs for a while, multiple threads will enter each other and wait for each other to compete with std::unique_lock and can't quit, When this happens, httpserver will not be able to receive new messages. The thread stack information is as follows:
Thread 49 (Thread 0x7fedb7e42700 (LWP 7836)):
#0 0x00007fedbbec8965 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1 0x00007fedbc18a82c in std::condition_variable::wait(std::unique_lockstd::mutex&) () from /lib64/libstdc++.so.6
#2 0x000000000042be6d in pplx::details::_Task_impl_base::_Wait() ()
#3 0x000000000045a694 in std::_Function_handler<void (pplx::taskweb::http::http_response), ProcessMediaInfo::SendRequest(std::string const&, std::string const&, web::json::value const&)::{lambda(pplx::taskweb::http::http_response)#1}>::_M_invoke(std::_Any_data const&, pplx::taskweb::http::http_response) ()
#4 0x00000000004268ef in std::_Function_handler<unsigned char (pplx::taskweb::http::http_response), std::function<unsigned char (pplx::taskweb::http::http_response)> pplx::details::_MakeTToUnitFunc<pplx::taskweb::http::http_response >(std::function<void (pplx::taskweb::http::http_response)> const&)::{lambda(pplx::taskweb::http::http_response)#1}>::_M_invoke(std::_Any_data const&, pplx::taskweb::http::http_response) ()
#5 0x0000000000461c37 in std::function<unsigned char (pplx::taskweb::http::http_response)>::operator()(pplx::taskweb::http::http_response) const ()
#6 0x0000000000461d20 in pplx::details::_PPLTaskHandle<unsigned char, pplx::taskweb::http::http_response::_ContinuationTaskHandle<web::http::http_response, void, ProcessMediaInfo::SendRequest(std::string const&, std::string const&, web::json::value const&)::{lambda(pplx::taskweb::http::http_response)#1}, std::integral_constant<bool, true>, pplx::details::_TypeSelectorNoAsync>, pplx::details::_ContinuationTaskHandleBase>::invoke() const ()
#7 0x000000000041919f in pplx::details::_TaskProcHandle::_RunChoreBridge(void*) ()
#8 0x00000000004ac3fe in boost::asio::detail::completion_handler<boost::_bi::bind_t<void, void ()(void), boost::_bi::list1<boost::_bi::value<void*> > > >::do_complete(void*, boost::asio::detail::scheduler_operation*, boost::system::error_code const&, unsigned long) ()
#9 0x00000000004ae9d0 in boost::asio::detail::scheduler::run(boost::system::error_code&) ()
#10 0x00000000004acdc6 in boost::asio::detail::posix_thread::func<(anonymous namespace)::threadpool_impl::add_thread()::{lambda()#1}>::run() ()
#11 0x00000000004ad4bf in boost_asio_detail_posix_thread_function ()
#12 0x00007fedbbec4dd5 in start_thread () from /lib64/libpthread.so.0
#13 0x00007fedbb6d5ead in clone () from /lib64/libc.so.6
Thread 48 (Thread 0x7fedb7641700 (LWP 7837)):
#0 0x00007fedbbec8965 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1 0x00007fedbc18a82c in std::condition_variable::wait(std::unique_lockstd::mutex&) () from /lib64/libstdc++.so.6
#2 0x000000000042be6d in pplx::details::_Task_impl_base::_Wait() ()
#3 0x000000000045a694 in std::_Function_handler<void (pplx::taskweb::http::http_response), ProcessMediaInfo::SendRequest(std::string const&, std::string const&, web::json::value const&)::{lambda(pplx::taskweb::http::http_response)#1}>::_M_invoke(std::_Any_data const&, pplx::taskweb::http::http_response) ()
#4 0x00000000004268ef in std::_Function_handler<unsigned char (pplx::taskweb::http::http_response), std::function<unsigned char (pplx::taskweb::http::http_response)> pplx::details::_MakeTToUnitFunc<pplx::taskweb::http::http_response >(std::function<void (pplx::taskweb::http::http_response)> const&)::{lambda(pplx::taskweb::http::http_response)#1}>::_M_invoke(std::_Any_data const&, pplx::taskweb::http::http_response) ()
#5 0x0000000000461c37 in std::function<unsigned char (pplx::taskweb::http::http_response)>::operator()(pplx::taskweb::http::http_response) const ()
#6 0x0000000000461d20 in pplx::details::_PPLTaskHandle<unsigned char, pplx::taskweb::http::http_response::_ContinuationTaskHandle<web::http::http_response, void, ProcessMediaInfo::SendRequest(std::string const&, std::string const&, web::json::value const&)::{lambda(pplx::taskweb::http::http_response)#1}, std::integral_constant<bool, true>, pplx::details::_TypeSelectorNoAsync>, pplx::details::_ContinuationTaskHandleBase>::invoke() const ()
#7 0x000000000041919f in pplx::details::_TaskProcHandle::_RunChoreBridge(void*) ()
#8 0x00000000004ac3fe in boost::asio::detail::completion_handler<boost::_bi::bind_t<void, void ()(void), boost::_bi::list1<boost::_bi::value<void*> > > >::do_complete(void*, boost::asio::detail::scheduler_operation*, boost::system::error_code const&, unsigned long) ()
#9 0x00000000004ae9d0 in boost::asio::detail::scheduler::run(boost::system::error_code&) ()
#10 0x00000000004acdc6 in boost::asio::detail::posix_thread::func<(anonymous namespace)::threadpool_impl::add_thread()::{lambda()#1}>::run() ()
#11 0x00000000004ad4bf in boost_asio_detail_posix_thread_function ()
#12 0x00007fedbbec4dd5 in start_thread () from /lib64/libpthread.so.0
#13 0x00007fedbb6d5ead in clone () from /lib64/libc.so.6
What is wrong with the above code...? Has anyone encountered such a problem?