The issue with canceling request

Apr 27, 2015 at 9:08 AM
I have an issue with C++ Rest SDK 2.5.0 statically linked with my program. The first thread is executing an HTTP request and the second thread tries to cancel the request and the call never finishes. This happens relatively rare. Also I noticed the thread which cancels request set m_request_handle to nullptr and the thread which executes the request calls WinHttpSendRequest with winhttp_context->m_request_handle equal to nullptr. Is it a bug in the C++ Rest SDK 2.5.0 or something is wrong with my code?

first thread:
ntdll.dll!NtWaitForSingleObject()  Unknown
ntdll.dll!RtlpWaitOnCriticalSection()  Unknown
ntdll.dll!RtlEnterCriticalSection()    Unknown
winhttp.dll!INTERNET_HANDLE_BASE::SafeGetProxyResolver(void)    Unknown
winhttp.dll!HTTP_USER_REQUEST::SendRequest(unsigned char * const,unsigned long,unsigned __int64,int,void (*)(void *,unsigned __int64,unsigned long,void *,unsigned long),unsigned long,unsigned __int64,int)    Unknown
winhttp.dll!WinHttpSendRequest()   Unknown
agent.exe!web::http::client::details::winhttp_client::_start_request_send(web::http::client::details::winhttp_request_context * winhttp_context=0x0000000004603740, unsigned __int64 content_length=0x0000000000000000) Line 653    C++
agent.exe!web::http::client::details::winhttp_client::send_request(const std::shared_ptr<web::http::client::details::request_context> & request={...}) Line 635 C++
agent.exe!web::http::client::details::_http_client_communicator::open_and_send_request(const std::shared_ptr<web::http::client::details::request_context> & request={...}) Line 325 C++
agent.exe!web::http::client::details::_http_client_communicator::async_send_request::__l8::<lambda>() Line 247  C++
agent.exe!std::_Callable_obj<void <lambda>(void),0>::_ApplyX<void>() Line 284   C++
agent.exe!std::_Func_impl<std::_Callable_obj<void <lambda>(void),0>,std::allocator<std::_Func_class<void> >,void>::_Do_call() Line 229  C++
agent.exe!std::_Func_class<void>::operator()() Line 316 C++
agent.exe!Concurrency::details::_MakeVoidToUnitFunc::__l3::<lambda>() Line 2584 C++
agent.exe!std::_Callable_obj<unsigned char <lambda>(void),0>::_ApplyX<unsigned char>() Line 284 C++
agent.exe!std::_Func_impl<std::_Callable_obj<unsigned char <lambda>(void),0>,std::allocator<std::_Func_class<unsigned char> >,unsigned char>::_Do_call() Line 229   C++
agent.exe!std::_Func_class<unsigned char>::operator()() Line 316    C++
agent.exe!Concurrency::task<unsigned char>::_InitialTaskHandle<void,void <lambda>(void),Concurrency::details::_TypeSelectorNoAsync>::_LogWorkItemAndInvokeUserLambda<std::function<unsigned char __cdecl(void)> >(std::function<unsigned char __cdecl(void)> && _func={...}) Line 3666  C++
agent.exe!Concurrency::task<unsigned char>::_InitialTaskHandle<void,void <lambda>(void),Concurrency::details::_TypeSelectorNoAsync>::_Init(Concurrency::details::_TypeSelectorNoAsync __formal={...}) Line 3685 C++
agent.exe!Concurrency::task<unsigned char>::_InitialTaskHandle<void,void <lambda>(void),Concurrency::details::_TypeSelectorNoAsync>::_Perform() Line 3671   C++
agent.exe!Concurrency::details::_PPLTaskHandle<unsigned char,Concurrency::task<unsigned char>::_InitialTaskHandle<void,void <lambda>(void),Concurrency::details::_TypeSelectorNoAsync>,Concurrency::details::_TaskProcHandle>::invoke() Line 1605   C++
agent.exe!Concurrency::details::_TaskProcHandle::operator()() Line 111  C++
agent.exe!Concurrency::details::_UnrealizedChore::_InvokeBridge<Concurrency::details::_TaskProcHandle>(void * _PContext=0x00000000046a54b8) Line 4379   C++
agent.exe!Concurrency::details::_UnrealizedChore::_UnstructuredChoreWrapper(Concurrency::details::_UnrealizedChore * pChore=0x00000000046a54b8) Line 293    C++
agent.exe!Concurrency::details::_UnrealizedChore::_Invoke() Line 4334   C++
agent.exe!Concurrency::details::WorkItem::Invoke() Line 172 C++
agent.exe!Concurrency::details::InternalContextBase::ExecuteChoreInline(Concurrency::details::WorkItem * pWork=0x00000000037dfa20) Line 1605    C++
agent.exe!Concurrency::details::InternalContextBase::Dispatch(Concurrency::DispatchState * pDispatchState=0x00000000037dfab8) Line 1719 C++
agent.exe!Concurrency::details::FreeThreadProxy::Dispatch() Line 197    C++
agent.exe!Concurrency::details::ThreadProxy::ThreadProxyMain(void * lpParameter=0x0000000003c772f0) Line 172    C++
kernel32.dll!BaseThreadInitThunk() Unknown
ntdll.dll!RtlUserThreadStart() Unknown
[Async Call]    
agent.exe!web::http::client::details::_http_client_communicator::async_send_request(const std::shared_ptr<web::http::client::details::request_context> & request={...}) Line 245    C++
agent.exe!web::http::client::details::http_network_handler::propagate(web::http::http_request request) Line 1285    C++
agent.exe!web::http::oauth2::details::oauth2_handler::propagate(web::http::http_request request) Line 514   C++
agent.exe!web::http::http_pipeline::propagate(web::http::http_request request) Line 1401    C++
agent.exe!web::http::client::http_client::request(web::http::http_request request, const Concurrency::cancellation_token & token) Line 129  C++
agent.exe!web::http::client::http_client::request(const std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > & mtd, const std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > & path_query_fragment, const Concurrency::cancellation_token & token) Line 424 C++
agent.exe!CAgentInet::RequestAction::__l3::<lambda>(Concurrency::cancellation_token_source cancel) Line 177 C++
agent.exe!std::_Callable_obj<Concurrency::task<web::http::http_response> <lambda>(Concurrency::cancellation_token_source),0>::_ApplyX<Concurrency::task<web::http::http_response>,Concurrency::cancellation_token_source>(Concurrency::cancellation_token_source && <_Args_0>) Line 283 C++
agent.exe!std::_Func_impl<std::_Callable_obj<Concurrency::task<web::http::http_response> <lambda>(Concurrency::cancellation_token_source),0>,std::allocator<std::_Func_class<Concurrency::task<web::http::http_response>,Concurrency::cancellation_token_source> >,Concurrency::task<web::http::http_response>,Concurrency::cancellation_token_source>::_Do_call(Concurrency::cancellation_token_source && <_Args_0>) Line 228  C++
agent.exe!std::_Func_class<Concurrency::task<web::http::http_response>,Concurrency::cancellation_token_source>::operator()(Concurrency::cancellation_token_source <_Args_0>) Line 315   C++


second thread:
ntdll.dll!NtWaitForSingleObject()  Unknown
ntdll.dll!RtlpWaitOnCriticalSection()  Unknown
ntdll.dll!RtlEnterCriticalSection()    Unknown
winhttp.dll!HTTP_USER_REQUEST::_SafeDetachSysReq(void)  Unknown
winhttp.dll!HTTP_REQUEST_HANDLE_OBJECT::SafeShutdownUsrReq(void)    Unknown
winhttp.dll!WinHttpCloseHandle()   Unknown
agent.exe!web::http::client::details::winhttp_request_context::cleanup() Line 249 C++
agent.exe!web::http::client::details::winhttp_client::send_request::__l52::<lambda>() Line 615  C++
agent.exe!Concurrency::details::_CancellationTokenCallback<void <lambda>(void) >::_Exec() Line 181  C++
agent.exe!Concurrency::details::_CancellationTokenRegistration::_Invoke() Line 151  C++
agent.exe!Concurrency::details::_CancellationTokenState::_Cancel::__l7::<lambda>(Concurrency::details::_CancellationTokenRegistration * pRegistration=0x000000000436a1c0) Line 376  C++
agent.exe!Concurrency::details::_CancellationTokenState::TokenRegistrationContainer::for_each<void <lambda>(Concurrency::details::_CancellationTokenRegistration *) >(Concurrency::details::_CancellationTokenState::_Cancel::__l7::void <lambda>(Concurrency::details::_CancellationTokenRegistration *) lambda=void <lambda>(Concurrency::details::_CancellationTokenRegistration * pRegistration){...}) Line 258 C++
agent.exe!Concurrency::details::_CancellationTokenState::_Cancel() Line 378 C++
agent.exe!Concurrency::cancellation_token_source::cancel() Line 934 C++
agent.exe!CTaskList::Cancel() Line 63   C++
agent.exe!CSingleTask::Cancel() Line 26 C++
agent.exe!CSingleTask::CreateInitialTask() Line 19  C++
agent.exe!CAgentInet::RequestAction() Line 220  C++
agent.exe!CAgentSvc::OnEventLoop() Line 120 C++
agent.exe!CSimpleServiceModuleImpl<int>::Run() Line 311 C++
agent.exe!CSimpleServiceModuleImpl<int>::ServiceMain(unsigned long dwArgc=0x00000001, wchar_t * * lpszArgv=0x00000000002ecd48) Line 284 C++
agent.exe!CSimpleServiceModuleImpl<int>::StaticServiceMain(unsigned long dwArgc=0x00000001, wchar_t * * lpszArgv=0x00000000002ecd48) Line 268   C++
sechost.dll!ScSvcctrlThreadA(struct _THREAD_STARTUP_PARMSA *)   Unknown
kernel32.dll!BaseThreadInitThunk() Unknown
ntdll.dll!RtlUserThreadStart() Unknown

Apr 28, 2015 at 5:40 PM
Hi b_vital,

I haven't taken a deep look at the callstacks here yet, but you are running on Windows Desktop. What operating system are you running on and what Visual Studio version are you using?

FYI - we don't officially support static linking on Windows yet. Are you able to reproduce this issue without using static linking?

Thanks,
Steve
Apr 28, 2015 at 6:25 PM
  1. Windows 7 Version 7601 (Service Pack 1) MP (4 procs) Free x64
  2. Microsoft Visual Studio Community 2013 Version 12.0.31101.00 Update 4
  3. Sorry, I do not have resources to reproduce this issue without using static linking. I think the issue is not related to static linking because it happens twice a day while canceling requests occurs ~100 times in a sec.
Apr 29, 2015 at 5:57 PM
Hi b_vital,

Do you have a small repro that I can run myself to reproduce the issue?

Thanks,
Steve
Apr 29, 2015 at 6:42 PM
Hi Steve,

No, I do not. I can write it when I have free time but I am not sure this will be soon.