[Coroutine] Assertion when coroutine is not run
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi,
I've been toying with Boost.Coroutine lately. For starters I have
tried to implement a message parser using the library. For this
purpose I have two coroutine<char>::push_type in a containing class.
These are initialized at class construction with a lambda. One
coroutine parses the message header, the other the body.
This all worked fine. Until I had a test case where I was only
interested in the message header, so I never called the
message-body-coroutine. At object destruction I get a this assertion:
replyparser:
/usr/local/include/boost/coroutine/detail/push_coroutine_object.hpp:167:
void boost::coroutines::detail::push_coroutine_object
2014-03-10 1:37 GMT+01:00 Brian Ravnsgaard Riis
[&](coroutine<char>::pull_type& c) { content.push_back(c.get()); while(content.size() != contentLength) { c(); content.push_back(c.get()); } validResult = true; }
before calling c.get() you should test if a value is available from pull_type, e.g. 'if(c) x=c.get()'
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 2014-03-10 08:26, Oliver Kowalke wrote:
2014-03-10 1:37 GMT+01:00 Brian Ravnsgaard Riis
mailto:brian@ravnsgaard.net>: [&](coroutine<char>::pull_type& c) { content.push_back(c.get()); while(content.size() != contentLength) { c(); content.push_back(c.get()); } validResult = true; }
before calling c.get() you should test if a value is available from pull_type, e.g. 'if(c) x=c.get()'
Hi Oliver, thanks for replying. Maybe I should've mentioned that I only call the push_type if there's anything left in the buffer: while(begin != end && !validResult) { parser(*begin++) } "parser" is the push_type, obviously; begin and end are iterators into the buffer I'm parsing. Anyway, I quickly tried to add the check in the coroutine as well, but that did not change anything. I didn't expect it to, as *I never call the push_type anyway!* If I "merge" the above push_type with the one I use for parsing the message header and just re-use that, then the assertion also does not trigger. The problem seems to be that the push_type is initialised with the lambda but then never called. Will experiment a bit more... /Brian -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJTHXH6AAoJEFES4N8QrEodTaQH/3SsIb7W9qbIMndqIAOB9viP xHZ2XSN/bReMKw0+51QlfKPrMMijL8Ul3/EPCWJKI7iFgbUUDXnGOJ8M2k9q+NCI 7eW4FoJtPCMxfBRkjxOfZWua64qr8UhDi6b16+u41+ddkmCB/arrC/6w5lJPkco0 psx/hY3AQMtA6Nn/b2BoiXze32n7z5NL9lxb4ebyyZ3sbUHfB6m9nvdgDWZvloMY 3on31hwrkClnH8N8areksAfN1MzY/PPYkX7ziztssqjj90LNFBFhThK/uJBNBDc6 +6St8ROuMThJVSq8NydVsPgUtRTnvv7ULrnPbYA9rF5Xw8c+40KYUE6o79MMJm0= =QbCx -----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 2014-03-10 09:04, Brian Ravnsgaard Riis wrote:
Hi Oliver, thanks for replying.
Maybe I should've mentioned that I only call the push_type if there's anything left in the buffer:
while(begin != end && !validResult) { parser(*begin++) }
"parser" is the push_type, obviously; begin and end are iterators into the buffer I'm parsing. Anyway, I quickly tried to add the check in the coroutine as well, but that did not change anything. I didn't expect it to, as *I never call the push_type anyway!*
If I "merge" the above push_type with the one I use for parsing the message header and just re-use that, then the assertion also does not trigger. The problem seems to be that the push_type is initialised with the lambda but then never called.
Will experiment a bit more...
/Brian
I tried adding a test case to Boost.Coroutine's own test suite. As my case I just build a push_type<char> and initialise with a lambda but then never call it. Same assertion. See attached diff. /Brian -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJTHXS2AAoJEFES4N8QrEodJkcH/32ohbU6PfRxDET/aRhYum41 RyCkmhwl///bAtwyzIzC3FSYXdoizNODCLK09Im8yL9CIG67ocImUBTu6iaoTXJp C+gsVBB39eL2+CwiyR9rjIChWD5MFHLvpHysDJD0M23Ka6dKK7E/5IBguDZykSeb AdZpMdLy3bo2npLbGfUsJdlCZ+uvf+M+E/9Bro1/dzRm4Ka9lN37LL8pY6zeNoNA I3ACJN68SQwnh+Z68AZo/tPbpiARxar6hxNK4M2Lk6bAVHK+Pl9xNUbbXWsu0m4o Lmtra9j+OGY8O5LPqB60N6CAQb+Sa+h+3cD0ikr7xStb+lKLva9AEmuoVFrRl5w= =83dN -----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 2014-03-10 09:35, Oliver Kowalke wrote:
could you provide a complete application/code demonstrating your problem?
Sure. See attached. I'm parsing an extremely simple HTTP subset in the example. If there's no message content (i.e. Content-Length: 0) then there is no point in calling that parser. I can of course merge the two coroutines without problems, which will be fine for my use-cases. However, I fail to understand why I get the assertion at all, when I don't call the coroutine. Some basic mechanics I haven't quite caught yet, I guess. /Brian -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJTHaoNAAoJEFES4N8QrEodTeYH/1MKF1OSMASJ0Y4QHgcFhTcW WJFC+mSiB+PHC5wzdOG/LRoM3t6ToIrK/H/DgvTbWVdun8ui1oDIeW014aL5UnL2 55DnYbGT4DJWZe5Lxxd3lu2O0DkoaVTTsEDj1SYOR6eLUbA1mOC7A+6W7Doixh2U OfF6yoWB6bco3JN90YUUkD5CzT0JgBS0oPhLvSu2ul2mUYsXwoCdAZdJvHaXV4vn HmzqoJCMjyVLykNcitMI7FVjfW5c8e5/TLJfYl+rI/wVgZhza94jaSHZFaIDW0mJ h4hXdhLjCjWy+oguVO/h+PprQ7Wjnk7dvhq+TStvzlX1hFAuXQfl2P95RwR7Ub4= =MgB+ -----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 2014-03-10 13:03, Brian Ravnsgaard Riis wrote:
I can of course merge the two coroutines without problems, which will be fine for my use-cases. However, I fail to understand why I get the assertion at all, when I don't call the coroutine. Some basic mechanics I haven't quite caught yet, I guess.
Hi, I'm now working around the problem by just not initialising the two push_type members. Then in the two parse*-functions I initialise when needed, using normal private member functions: if(!headerParser_) { boost::coroutines::coroutine<char>::push_type { std::bind(&Parser::doParseHeader, this, std::placeholders::_1) }.swap(headerParser_); } This works fine, and is fine with me too(!) really. I'm still not sure why it's necessary, though... /Brian -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJTHp92AAoJEFES4N8QrEodmmsIAJ7MdJd5khbLjwnoQliBRXYU eG8f6EbiePY7VU0Bn30J+ZsYlJ29qNq17nHMLvm7GukNFqPPuzsG8QtAC697vyxg 3mWwkvZtIrR0dTzT6i1+z1fAEqZSZfVFrU2cv7o5jCb2A3GBpPk8aL5v0VuFEDRq +PEjA9Un7W0aQhujt77Undtguu0p8g7pgeKTFANfsgf1IQY9+PiSLo7/REtRRr0S twLoM1MDb89b4OBc8ZgoagpJtSwbLBXKHIqlCBoOkAuBLj1KTnfeEb3bcimhrP+1 CtOgESCMcbalW6oXP1eqTpfnoRiSC+RZ5E2Q/ET+jRAHAQ4pwgnF6j4yYa0UmIg= =nqdf -----END PGP SIGNATURE-----
using your example together with the code from branch develop does not produce the error.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 2014-03-11 19:55, Oliver Kowalke wrote:
using your example together with the code from branch develop does not produce the error.
Hi,
I just tried building develop, but this failed:
clang-linux.compile.c++.without-pth
bin.v2/libs/coroutine/build/clang-linux-3.4/release/link-static/threading-multi/detail/coroutine_context.o
libs/coroutine/src/detail/coroutine_context.cpp:38:5: error: no
matching constructor for initialization of 'context::fcontext_t'
ctx_( 0)
^ ~
./boost/context/detail/fcontext_x86_64.hpp:47:8: note: candidate
constructor (the implicit copy constructor) not viable: no known
conversion from 'int' to 'const boost::context::fcontext_t' for 1st
argument
struct fcontext_t
^
./boost/context/detail/fcontext_x86_64.hpp:47:8: note: candidate
constructor (the implicit move constructor) not viable: no known
conversion from 'int' to 'boost::context::fcontext_t' for 1st argument
struct fcontext_t
^
./boost/context/detail/fcontext_x86_64.hpp:53:5: note: candidate
constructor not viable: requires 0 arguments, but 1 was provided
fcontext_t() :
^
libs/coroutine/src/detail/coroutine_context.cpp:47:5: error: no
matching constructor for initialization of 'context::fcontext_t'
ctx_( context::make_fcontext( stack_ctx_.sp, stack_ctx_.size, fn) )
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./boost/context/detail/fcontext_x86_64.hpp:47:8: note: candidate
constructor (the implicit copy constructor) not viable: no known
conversion from 'boost::context::fcontext_t *' to 'const
boost::context::fcontext_t' for 1st argument; dereference the argument
with *
struct fcontext_t
^
*
./boost/context/detail/fcontext_x86_64.hpp:47:8: note: candidate
constructor (the implicit move constructor) not viable: no known
conversion from 'boost::context::fcontext_t *' to
'boost::context::fcontext_t' for 1st argument; dereference the
argument with *
struct fcontext_t
^
*
./boost/context/detail/fcontext_x86_64.hpp:53:5: note: candidate
constructor not viable: requires 0 arguments, but 1 was provided
fcontext_t() :
^
libs/coroutine/src/detail/coroutine_context.cpp:79:44: error: no
viable conversion from 'context::fcontext_t' to 'const
boost::context::fcontext_t *'
return context::jump_fcontext( & ctx_, other.ctx_, param,
preserve_fpu);
^~~~~~~~~~
./boost/context/fcontext.hpp:79:84: note: passing argument to
parameter 'nfc' here
intptr_t BOOST_CONTEXT_CALLDECL jump_fcontext( fcontext_t * ofc,
fcontext_t const* nfc, intptr_t vp, bool preserve_fpu = true);
^
3 errors generated.
"clang++" -c -x c++ -O3 -finline-functions -Wno-inline -Wall
- -pthread -DBOOST_ALL_NO_LIB=1 -DBOOST_CHRONO_STATIC_LINK=1
- -DBOOST_COROUTINES_SOURCE -DBOOST_SYSTEM_NO_DEPRECATED
- -DBOOST_SYSTEM_STATIC_LINK=1 -DBOOST_THREAD_BUILD_LIB=1
- -DBOOST_THREAD_POSIX -DBOOST_THREAD_USE_LIB=1 -DNDEBUG -I"." -o
"bin.v2/libs/coroutine/build/clang-linux-3.4/release/link-static/threading-multi/detail/coroutine_context.o"
"libs/coroutine/src/detail/coroutine_context.cpp"
...failed clang-linux.compile.c++.without-pth
bin.v2/libs/coroutine/build/clang-linux-3.4/release/link-static/threading-multi/detail/coroutine_context.o...
...skipped
you are mixing boost-1.55 and branch develop - that doesn't work. boost.coroutine depends on boost.context and boost.context has some modification in trunk too. you need to fetch bot libs from trunk.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 2014-03-13 08:16, Oliver Kowalke wrote:
you are mixing boost-1.55 and branch develop - that doesn't work. boost.coroutine depends on boost.context and boost.context has some modification in trunk too. you need to fetch bot libs from trunk.
Yep, using both from develop worked. And now the test case runs correctly, so whatever the issue was has disappeared since 1.55. Thanks for your time, Oliver. /Brian -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJTIWzFAAoJEFES4N8QrEod+dkH/iZeUtrpZN0ZE6q4IVGseb3+ 2HGVIV8125ive58ojhmvoSKO6eCC2zU6bYRrOJHUrcizssWJ+/VB1Jn1d1uu78zs 7CMOb0f77PVnZ/dcPnHw2JHaNHy1A+mz0IP4AWEHLccr4Ltj5EV1PADCTD2bOwMp xF+87+2O7ZVzcG9RTOn4nVm3TVchH4RhMY9ziJ6YmliD+xD9CDO0/mj+AEgNZFnn 92OmjE1E25i0282IOtaLuP/PSRoErJ4kzjMvsDnYcL9kdtkoChBWGh29Z6q7xm0j QAQvUTl7G86WH6qm25EgQ1Yw1XMPZjxf5spvDR/hao0UFS8rdo7obyS3cXxp0FY= =F0jU -----END PGP SIGNATURE-----
participants (2)
-
Brian Ravnsgaard Riis
-
Oliver Kowalke