{"action":"created","issue":{"url":"https://api.github.com/repos/boostorg/beast/issues/1012","repository_url":"https://api.github.com/repos/boostorg/beast","labels_url":"https://api.github.com/repos/boostorg/beast/issues/1012/labels{/name}","comments_url":"https://api.github.com/repos/boostorg/beast/issues/1012/comments","events_url":"https://api.github.com/repos/boostorg/beast/issues/1012/events","html_url":"https://github.com/boostorg/beast/issues/1012","id":295397069,"node_id":"MDU6SXNzdWUyOTUzOTcwNjk=","number":1012,"title":"Boost 1.66 upgrade: assertion failure and mixing async/sync ops","user":{"login":"vchang-akamai","id":23563094,"node_id":"MDQ6VXNlcjIzNTYzMDk0","avatar_url":"https://avatars3.githubusercontent.com/u/23563094?v=4","gravatar_id":"","url":"https://api.github.com/users/vchang-akamai","html_url":"https://github.com/vchang-akamai","followers_url":"https://api.github.com/users/vchang-akamai/followers","following_url":"https://api.github.com/users/vchang-akamai/following{/other_user}","gists_url":"https://api.github.com/users/vchang-akamai/gists{/gist_id}","starred_url":"https://api.github.com/users/vchang-akamai/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vchang-akamai/subscriptions","organizations_url":"https://api.github.com/users/vchang-akamai/orgs","repos_url":"https://api.github.com/users/vchang-akamai/repos","events_url":"https://api.github.com/users/vchang-akamai/events{/privacy}","received_events_url":"https://api.github.com/users/vchang-akamai/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":68,"created_at":"2018-02-08T06:13:36Z","updated_at":"2018-12-17T18:39:26Z","closed_at":"2018-03-01T20:29:12Z","author_association":"NONE","body":"I recently upgraded from Beast beta 0.69 to official Boost 1.66. (Belated congratz to Vinnie :-)\r\n\r\nI have a SSL websocket client test application for sending various test traffic to my SSL websocket server application. This test client can create multiple concurrent websocket connections and multiple worker threads  all managed under a single asio::io_service.  Each connection session uses a mix of asynchronous reads and synchronous writes (including synchronous websocket::stream::close()). The async read callbacks are wrapped by a strand. The synchronous writes/close are executed from within strand-wrapped callbacks or strand-posted functions. There is at most one active async_read() at a time.\r\n\r\nThis test client worked fine with Beast 0.69. After upgrading to Boost 1.66, I noticed that when these client websocket connections attempt to initiate the close:\r\n1) websocket::stream::close() always produced the error code websocket::error::failed\r\n(\"boost.beast.websocket: WebSocket connection failed due to a protocol violation\")\r\n2) Sometimes one or more of the connection sessions would assert fail at:\r\nbeast/websocket/impl/read.ipp:576\r\nAssertion `ws_.status_ == status::open' failed.\r\n\r\n\r\nAs an experiment, I changed close() to async_close() and then I noticed:\r\n1) The error code websocket::error::failed went away. async_close's callback always receives a success status.\r\n2) The read.ipp:576 \"ws_.status_ == status::open\" assertion failure went away.\r\n3) A new assertion failure appeared, but much less frequently:\r\nbeast/websocket/impl/read.ipp:217\r\nAssertion `ws_.rd_block_' failed.\r\nThe async_read() callback handler was not reached, so I'm guessing this asserted while processing the peer close frame response from the server.\r\n\r\n\r\nQuestions:\r\n\r\n1) Is it incorrect to mix async and sync calls? \r\n\r\nI understand that there can be no more than one active async read, write, ping, close op without an intervening corresponding callback.  I also understand that websocket objects are not thread safe so some kind of synchronization control (like an explicit strand) is needed when using multiple threads.\r\n\r\nI think I'm following these rules...   But perhaps if websocket::stream::close() is internally performing async ops on the websocket, then these async ops might get executed on another thread without strand protection. This could race with my earlier call to async_read() if the timing is unlucky and end up with two threads modifying the same websocket.\r\n\r\nBut the docs for close() says it's implemented with the next layer's write_some() which are blocking calls.\r\n\r\nNot sure if this is my bug or Beast bug\r\n\r\n2) what might be causing the new assertion failure at read.ipp:217?\r\n\r\n\r\n\r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/boostorg/beast/issues/comments/447952218","html_url":"https://github.com/boostorg/beast/issues/1012#issuecomment-447952218","issue_url":"https://api.github.com/repos/boostorg/beast/issues/1012","id":447952218,"node_id":"MDEyOklzc3VlQ29tbWVudDQ0Nzk1MjIxOA==","user":{"login":"svarogaden","id":23310597,"node_id":"MDQ6VXNlcjIzMzEwNTk3","avatar_url":"https://avatars1.githubusercontent.com/u/23310597?v=4","gravatar_id":"","url":"https://api.github.com/users/svarogaden","html_url":"https://github.com/svarogaden","followers_url":"https://api.github.com/users/svarogaden/followers","following_url":"https://api.github.com/users/svarogaden/following{/other_user}","gists_url":"https://api.github.com/users/svarogaden/gists{/gist_id}","starred_url":"https://api.github.com/users/svarogaden/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/svarogaden/subscriptions","organizations_url":"https://api.github.com/users/svarogaden/orgs","repos_url":"https://api.github.com/users/svarogaden/repos","events_url":"https://api.github.com/users/svarogaden/events{/privacy}","received_events_url":"https://api.github.com/users/svarogaden/received_events","type":"User","site_admin":false},"created_at":"2018-12-17T18:39:26Z","updated_at":"2018-12-17T18:39:26Z","author_association":"NONE","body":"\r\nAs I understand it is impossible to synchronize access to a multi-thread web socket\r\n\r\n\r\n\r\n"}}
{"actor":{"display_login":"svarogaden"}}