forked from boostorg/beast
control callback is copied or moved:
The function stream::control_callback now copies or moves the callback. In some cases this may require a dynamic allocation. To avoid the possibility of a dynamic allocation, callers may wrap their callback using `std::ref` before setting it.
This commit is contained in:
@@ -3,6 +3,10 @@ Version 147:
|
|||||||
* Don't use boost::string_ref
|
* Don't use boost::string_ref
|
||||||
* Use iterator wrapper in detail::buffers_range
|
* Use iterator wrapper in detail::buffers_range
|
||||||
|
|
||||||
|
WebSocket:
|
||||||
|
|
||||||
|
* control callback is copied or moved
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
Version 146:
|
Version 146:
|
||||||
|
@@ -580,9 +580,9 @@ public:
|
|||||||
string_view payload // The payload in the frame
|
string_view payload // The payload in the frame
|
||||||
);
|
);
|
||||||
@endcode
|
@endcode
|
||||||
The implementation type-erases the callback without requiring
|
The implementation type-erases the callback which may require
|
||||||
a dynamic allocation. For this reason, the callback object is
|
a dynamic allocation. To prevent the possiblity of a dynamic
|
||||||
passed by a non-constant reference.
|
allocation, use `std::ref` to wrap the callback.
|
||||||
If the read operation which receives the control frame is
|
If the read operation which receives the control frame is
|
||||||
an asynchronous operation, the callback will be invoked using
|
an asynchronous operation, the callback will be invoked using
|
||||||
the same method as that used to invoke the final handler.
|
the same method as that used to invoke the final handler.
|
||||||
@@ -592,15 +592,10 @@ public:
|
|||||||
Attempting to send a close frame after a close frame is
|
Attempting to send a close frame after a close frame is
|
||||||
received will result in undefined behavior.
|
received will result in undefined behavior.
|
||||||
*/
|
*/
|
||||||
template<class Callback>
|
|
||||||
void
|
void
|
||||||
control_callback(Callback& cb)
|
control_callback(std::function<void(frame_type, string_view)> cb)
|
||||||
{
|
{
|
||||||
// Callback may not be constant, caller is responsible for
|
ctrl_cb_ = std::move(cb);
|
||||||
// managing the lifetime of the callback. Copies are not made.
|
|
||||||
BOOST_STATIC_ASSERT(! std::is_const<Callback>::value);
|
|
||||||
|
|
||||||
ctrl_cb_ = std::ref(cb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reset the control frame callback.
|
/** Reset the control frame callback.
|
||||||
|
@@ -126,13 +126,13 @@ public:
|
|||||||
put(ws.next_layer().buffer(), cbuf(
|
put(ws.next_layer().buffer(), cbuf(
|
||||||
0x89, 0x00));
|
0x89, 0x00));
|
||||||
bool invoked = false;
|
bool invoked = false;
|
||||||
auto cb = [&](frame_type kind, string_view)
|
ws.control_callback(
|
||||||
{
|
[&](frame_type kind, string_view)
|
||||||
BEAST_EXPECT(! invoked);
|
{
|
||||||
BEAST_EXPECT(kind == frame_type::ping);
|
BEAST_EXPECT(! invoked);
|
||||||
invoked = true;
|
BEAST_EXPECT(kind == frame_type::ping);
|
||||||
};
|
invoked = true;
|
||||||
ws.control_callback(cb);
|
});
|
||||||
w.write(ws, sbuf("Hello"));
|
w.write(ws, sbuf("Hello"));
|
||||||
multi_buffer b;
|
multi_buffer b;
|
||||||
w.read(ws, b);
|
w.read(ws, b);
|
||||||
@@ -147,13 +147,13 @@ public:
|
|||||||
put(ws.next_layer().buffer(), cbuf(
|
put(ws.next_layer().buffer(), cbuf(
|
||||||
0x88, 0x00));
|
0x88, 0x00));
|
||||||
bool invoked = false;
|
bool invoked = false;
|
||||||
auto cb = [&](frame_type kind, string_view)
|
ws.control_callback(
|
||||||
{
|
[&](frame_type kind, string_view)
|
||||||
BEAST_EXPECT(! invoked);
|
{
|
||||||
BEAST_EXPECT(kind == frame_type::close);
|
BEAST_EXPECT(! invoked);
|
||||||
invoked = true;
|
BEAST_EXPECT(kind == frame_type::close);
|
||||||
};
|
invoked = true;
|
||||||
ws.control_callback(cb);
|
});
|
||||||
w.write(ws, sbuf("Hello"));
|
w.write(ws, sbuf("Hello"));
|
||||||
doReadTest(w, ws, close_code::none);
|
doReadTest(w, ws, close_code::none);
|
||||||
});
|
});
|
||||||
@@ -162,15 +162,14 @@ public:
|
|||||||
doTest(pmd, [&](ws_type& ws)
|
doTest(pmd, [&](ws_type& ws)
|
||||||
{
|
{
|
||||||
bool once = false;
|
bool once = false;
|
||||||
auto cb =
|
ws.control_callback(
|
||||||
[&](frame_type kind, string_view s)
|
[&](frame_type kind, string_view s)
|
||||||
{
|
{
|
||||||
BEAST_EXPECT(kind == frame_type::pong);
|
BEAST_EXPECT(kind == frame_type::pong);
|
||||||
BEAST_EXPECT(! once);
|
BEAST_EXPECT(! once);
|
||||||
once = true;
|
once = true;
|
||||||
BEAST_EXPECT(s == "");
|
BEAST_EXPECT(s == "");
|
||||||
};
|
});
|
||||||
ws.control_callback(cb);
|
|
||||||
w.ping(ws, "");
|
w.ping(ws, "");
|
||||||
ws.binary(true);
|
ws.binary(true);
|
||||||
w.write(ws, sbuf("Hello"));
|
w.write(ws, sbuf("Hello"));
|
||||||
@@ -185,15 +184,14 @@ public:
|
|||||||
doTest(pmd, [&](ws_type& ws)
|
doTest(pmd, [&](ws_type& ws)
|
||||||
{
|
{
|
||||||
bool once = false;
|
bool once = false;
|
||||||
auto cb =
|
ws.control_callback(
|
||||||
[&](frame_type kind, string_view s)
|
[&](frame_type kind, string_view s)
|
||||||
{
|
{
|
||||||
BEAST_EXPECT(kind == frame_type::pong);
|
BEAST_EXPECT(kind == frame_type::pong);
|
||||||
BEAST_EXPECT(! once);
|
BEAST_EXPECT(! once);
|
||||||
once = true;
|
once = true;
|
||||||
BEAST_EXPECT(s == "payload");
|
BEAST_EXPECT(s == "payload");
|
||||||
};
|
});
|
||||||
ws.control_callback(cb);
|
|
||||||
ws.ping("payload");
|
ws.ping("payload");
|
||||||
w.write_some(ws, false, sbuf("Hello, "));
|
w.write_some(ws, false, sbuf("Hello, "));
|
||||||
w.write_some(ws, false, sbuf(""));
|
w.write_some(ws, false, sbuf(""));
|
||||||
|
@@ -190,13 +190,12 @@ boost::asio::ip::tcp::socket sock{ioc};
|
|||||||
{
|
{
|
||||||
stream<boost::asio::ip::tcp::socket> ws{ioc};
|
stream<boost::asio::ip::tcp::socket> ws{ioc};
|
||||||
//[ws_snippet_17
|
//[ws_snippet_17
|
||||||
auto cb =
|
ws.control_callback(
|
||||||
[](frame_type kind, string_view payload)
|
[](frame_type kind, string_view payload)
|
||||||
{
|
{
|
||||||
// Do something with the payload
|
// Do something with the payload
|
||||||
boost::ignore_unused(kind, payload);
|
boost::ignore_unused(kind, payload);
|
||||||
};
|
});
|
||||||
ws.control_callback(cb);
|
|
||||||
//]
|
//]
|
||||||
|
|
||||||
//[ws_snippet_18
|
//[ws_snippet_18
|
||||||
|
Reference in New Issue
Block a user