I am operating some long running websocket clients and every few days I get the assertion failed in do_close case of the switch statement:
Assertion `! d.ws.wr_block_' failed.
Is this a bug in the library or does it imply I am doing something wrong?
This was beast/websocket/impl/read.ipp line 454 as of commit 1ab7a2f04ca9a0b35f2032877cab78d94e96ebad.
This means you are trying to close when you have an active write. Close counts as a write, you can't do both simultaneously.
I should add some comments around that assert, it happens semi-often.
I am not calling any close function. Is there something else that triggers the close?
If you have a read operation pending, and a close frame is received, the implementation will automatically send a close frame in response. Although a write is performed at the low level, the implementation coordinates with caller-initiated writes to ensure that there is no block (wr_block_ is a flag indicating that a write operation is in progress).
It is possible, although unlikely, that a bug exists. I will investigate. This assertion can also happen if you attempt two writes at the same time. In the meanwhile, if you want to help track this down please review your code and make absolutely certain that you are not trying to perform two writes at the same time.
Upon reviewing the asynchronous read implementation, I can see how there might be a small window allowing a race condition. Please give this branch a try and let me know if any of the new asserts go off:
https://github.com/vinniefalco/Beast/commits/fix
I'm running the new branch now.
I'm having a similar problem. But it crashes instead. Using the fix branch I still get crashes in read.ipp:661 calling maybe_invoke() and d.ws.wr_block_ is filled with trash.
I never call close nor delete the connections. I always have a pending read, but writes are made synchronously and I only have one thread.
@felipealmeida Did you run the debug version?
I'm always compiling with debug, yes.
I'm using C++1y in GCC
The problem is always reproducible in my case. I'm not sure it is a Beast bug however.
OK. So I'm stupid. I'm moving the websocket stream while a pending operation exists, by using a std::vector.
Ah, you can't move websocket streams while there are pending operations :) Good catch. But I still think there's a bug from the original description in this issue. I have some ideas about it, I will push a possible fix shortly.
I rewrote history in the fix branch to include a possible fix, please try it and let me know if the asserts go away (don't forget to run a debug build!)
https://github.com/vinniefalco/Beast/commits/fix
So...I guess you haven't seen the assert anymore?