locked
Do I have to hold onto returned tasks? RRS feed

  • Question

  • int _tmain(int argc, _TCHAR* argv[])
    {
    	volatile bool shutdown = false;
    	auto task = async::tcp_listener<byte>::create(_T("localhost"), 8080, [&shutdown](async::streambuf<byte> buf)
    	{
    		_tprintf_s(_T("incoming connection\n"));
    		shutdown = true;
    	});
    	while(!shutdown) { ::Sleep(200); }
    }

    If I remove the "auto task" variable this crashes when a connection is established because the listener is deleted too early or something like that.

    The example from the docs doesn't hold onto the task (and it also doesn't specify the template argument to tcp_listener and streambuf).

    Am I supposed to hold onto the task returned by tcp_listener::create or is this a bug? (I'm new to C++ PPL, sorry)

    PS: a tcp_listener::listen function similar to http_listener::listen would be useful. Even if Casablanca targets http connections, I'd really like to use similar features when dealing with custom tcp protocols, so to me it makes sense to keep both in one framework.


    • Edited by Tobias Käs Sunday, February 10, 2013 10:05 AM
    Sunday, February 10, 2013 10:02 AM

Answers

  • Tobias,

    Thanks for your analysis. I can see now that this is a defect in our code. I'll file and bug and we'll fix in the server release.

    One more thing. I realize this won't be helpful to you, but for your information, our next release of Casablanca will not contain server-side features like tcp_listener. At this moment we're readying the client-side functionality, so it will be a while before we get to this bug.

    Artur Laksberg Visual C++ Team Microsoft

    • Marked as answer by Tobias Käs Wednesday, February 13, 2013 8:45 AM
    Wednesday, February 13, 2013 5:48 AM

All replies

  • Tobias,

    Having 'auto task' here is not necessary, since you're not waiting on it, or attaching continuation to it. It really doesn't matter if you have it there or not.

    I wasn't able to repro your crash though. Do you have a sample that reproduces it consistently? Can you attach a call stack?

    Thanks for the tip on the tcp_listener::listen, we'll consider that.


    Artur Laksberg Visual C++ Team Microsoft

    Tuesday, February 12, 2013 2:08 AM
  • I'm using a stock VS2012 console project (debug build), include tcp_listener.h, link to the x86 debug lib and it reliably crashes when I perform a connection without having the "auto task" variable:

    msvcr110d.dll!FindCompleteObject(void * * inptr) Line 319
    msvcr110d.dll!__RTDynamicCast(void * inptr, long VfDelta, void * SrcType, void * TargetType, int isReference) Line 217
    CasablancaTest.exe!async::basic_tcp_listener<unsigned char>::_tcpstream_callback_open::on_accept(async::details::_tcp_info * l_info, async::details::_tcp_info * s_info) Line 185
    casablanca110.dll!<lambda_5fb5ade51a662c8aac2eab9f777f9b16>::operator()()
    casablanca110.dll!std::_Callable_obj<class <lambda_5fb5ade51a662c8aac2eab9f777f9b16>,0>::_ApplyX<void>(void)
    casablanca110.dll!std::_Func_impl<struct std::_Callable_obj<class <lambda_5fb5ade51a662c8aac2eab9f777f9b16>,0>,class std::allocator<class std::_Func_class<void,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil> >,void,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil>::_Do_call(void)
    casablanca110.dll!std::_Func_class<void,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil>::operator()(void)
    casablanca110.dll!<lambda_2125a6b6484c03a33ff8acce6052a47c>::operator()()
    casablanca110.dll!std::_Callable_obj<class <lambda_2125a6b6484c03a33ff8acce6052a47c>,0>::_ApplyX<unsigned char>(void)
    casablanca110.dll!std::_Func_impl<struct std::_Callable_obj<class <lambda_2125a6b6484c03a33ff8acce6052a47c>,0>,class std::allocator<class std::_Func_class<unsigned char,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil> >,unsigned char,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil>::_Do_call(void)
    casablanca110.dll!std::_Func_class<unsigned char,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil,struct std::_Nil>::operator()(void)
    casablanca110.dll!pplx::task<unsigned char>::_InitialTaskHandle<void,class <lambda_5fb5ade51a662c8aac2eab9f777f9b16>,struct pplx::details::_TypeSelectorNoAsync>::_Init(struct pplx::details::_TypeSelectorNoAsync)
    casablanca110.dll!pplx::task<unsigned char>::_InitialTaskHandle<void,class <lambda_5fb5ade51a662c8aac2eab9f777f9b16>,struct pplx::details::_TypeSelectorNoAsync>::_Perform(void)
    casablanca110.dll!pplx::details::_PPLTaskHandle<unsigned char,struct pplx::task<unsigned char>::_InitialTaskHandle<void,class <lambda_5fb5ade51a662c8aac2eab9f777f9b16>,struct pplx::details::_TypeSelectorNoAsync>,class pplx::details::_UnrealizedChore>::operator()(void)
    casablanca110.dll!pplx::details::_UnrealizedChore::_InvokeBridge<struct pplx::details::_PPLTaskHandle<unsigned char,struct pplx::task<unsigned char>::_InitialTaskHandle<void,class <lambda_5fb5ade51a662c8aac2eab9f777f9b16>,struct pplx::details::_TypeSelectorNoAsync>,class pplx::details::_UnrealizedChore> >(struct pplx::details::_PPLTaskHandle<unsigned char,struct pplx::task<unsigned char>::_InitialTaskHandle<void,class <lambda_5fb5ade51a662c8aac2eab9f777f9b16>,struct pplx::details::_TypeSelectorNoAsync>,class pplx::details::_UnrealizedChore> *)
    casablanca110.dll!pplx::details::_Task_impl_base::_RunChoreBridge(void *)
    casablanca110.dll!pplx::details::pplx_dflt_scheduler::DefaultWorkCallback(struct _TP_CALLBACK_INSTANCE *,void *,struct _TP_WORK *)


    The basic_tcp_listener in line 3 of the stack trace is in _tcpstream_callback_open::on_accept where a dynamic_cast of the basic_tcp_listener seems to fail with an access violation, which then results in a throw std::__non_rtti_object

    When I checked the property pages of the project, the compiler setting for RTTI was blank, so I don't know what the default is, but setting it to 'yes (/GR)' doesn't seem to make a difference.

    Also when I put a breakpoint into the basic_tcp_listener dtor it seems to be called way too early, before I even attempt to connect.

    • Edited by Tobias Käs Tuesday, February 12, 2013 8:53 AM
    Tuesday, February 12, 2013 7:55 AM
  • Tobias,

    Thanks for your analysis. I can see now that this is a defect in our code. I'll file and bug and we'll fix in the server release.

    One more thing. I realize this won't be helpful to you, but for your information, our next release of Casablanca will not contain server-side features like tcp_listener. At this moment we're readying the client-side functionality, so it will be a while before we get to this bug.

    Artur Laksberg Visual C++ Team Microsoft

    • Marked as answer by Tobias Käs Wednesday, February 13, 2013 8:45 AM
    Wednesday, February 13, 2013 5:48 AM

  • Thanks for the info. Casablanca looks very promising, keep up the good work.
    Wednesday, February 13, 2013 8:50 AM