forked from boostorg/beast
Implement asio dealloc-before-invoke guarantee:
fix #215 This change guarantees that temporary memory allocated through the asio hooks by the Beast implementation is deallocated before invoking the final handler when performing composed operations. The change is accomplished by replacing std::shared_ptr with a thread-safe custom container handler_ptr to manage composed operation state. The container tracks other instances which manage the same object and resets them in a safe way before invoking the final handler. handler_ptr is provided as a public interface so that users of this library can utilize the same idiom to write their own composed operations.
This commit is contained in:
1 parent
1a26484eca
commit
01e1fa2dc9
21 files changed
+574
-322
No files matched your search
@@ -14,6 +14,7 @@
|
||||
#include <beast/http/string_body.hpp>
|
||||
#include <beast/http/write.hpp>
|
||||
#include <beast/core/handler_alloc.hpp>
|
||||
#include <beast/core/handler_ptr.hpp>
|
||||
#include <beast/core/prepare_buffers.hpp>
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
@@ -30,27 +31,21 @@ template<class NextLayer>
|
||||
template<class Handler>
|
||||
class stream<NextLayer>::response_op
|
||||
{
|
||||
using alloc_type =
|
||||
handler_alloc<char, Handler>;
|
||||
|
||||
struct data
|
||||
{
|
||||
bool cont;
|
||||
stream<NextLayer>& ws;
|
||||
http::response<http::string_body> resp;
|
||||
Handler h;
|
||||
error_code final_ec;
|
||||
bool cont;
|
||||
int state = 0;
|
||||
|
||||
template<class DeducedHandler,
|
||||
class Body, class Fields>
|
||||
data(DeducedHandler&& h_, stream<NextLayer>& ws_,
|
||||
template<class Body, class Fields>
|
||||
data(Handler&, stream<NextLayer>& ws_,
|
||||
http::request<Body, Fields> const& req,
|
||||
bool cont_)
|
||||
: ws(ws_)
|
||||
: cont(cont_)
|
||||
, ws(ws_)
|
||||
, resp(ws_.build_response(req))
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
, cont(cont_)
|
||||
{
|
||||
// can't call stream::reset() here
|
||||
// otherwise accept_op will malfunction
|
||||
@@ -60,7 +55,7 @@ class stream<NextLayer>::response_op
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<data> d_;
|
||||
handler_ptr<data, Handler> d_;
|
||||
|
||||
public:
|
||||
response_op(response_op&&) = default;
|
||||
@@ -69,7 +64,7 @@ public:
|
||||
template<class DeducedHandler, class... Args>
|
||||
response_op(DeducedHandler&& h,
|
||||
stream<NextLayer>& ws, Args&&... args)
|
||||
: d_(std::allocate_shared<data>(alloc_type{h},
|
||||
: d_(make_handler_ptr<data, Handler>(
|
||||
std::forward<DeducedHandler>(h), ws,
|
||||
std::forward<Args>(args)...))
|
||||
{
|
||||
@@ -84,7 +79,7 @@ public:
|
||||
std::size_t size, response_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate(size, op->d_->h);
|
||||
allocate(size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -92,7 +87,7 @@ public:
|
||||
void* p, std::size_t size, response_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
deallocate(p, size, op->d_->h);
|
||||
deallocate(p, size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -106,7 +101,7 @@ public:
|
||||
void asio_handler_invoke(Function&& f, response_op* op)
|
||||
{
|
||||
return boost_asio_handler_invoke_helpers::
|
||||
invoke(f, op->d_->h);
|
||||
invoke(f, op->d_.handler());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -138,7 +133,7 @@ operator()(error_code ec, bool again)
|
||||
break;
|
||||
}
|
||||
}
|
||||
d.h(ec);
|
||||
d_.invoke(ec);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -149,24 +144,19 @@ template<class NextLayer>
|
||||
template<class Handler>
|
||||
class stream<NextLayer>::accept_op
|
||||
{
|
||||
using alloc_type =
|
||||
handler_alloc<char, Handler>;
|
||||
|
||||
struct data
|
||||
{
|
||||
bool cont;
|
||||
stream<NextLayer>& ws;
|
||||
http::request<http::string_body> req;
|
||||
Handler h;
|
||||
bool cont;
|
||||
int state = 0;
|
||||
|
||||
template<class DeducedHandler, class Buffers>
|
||||
data(DeducedHandler&& h_, stream<NextLayer>& ws_,
|
||||
template<class Buffers>
|
||||
data(Handler& handler, stream<NextLayer>& ws_,
|
||||
Buffers const& buffers)
|
||||
: ws(ws_)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
, cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(h))
|
||||
: cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(handler))
|
||||
, ws(ws_)
|
||||
{
|
||||
using boost::asio::buffer_copy;
|
||||
using boost::asio::buffer_size;
|
||||
@@ -177,7 +167,7 @@ class stream<NextLayer>::accept_op
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<data> d_;
|
||||
handler_ptr<data, Handler> d_;
|
||||
|
||||
public:
|
||||
accept_op(accept_op&&) = default;
|
||||
@@ -186,7 +176,7 @@ public:
|
||||
template<class DeducedHandler, class... Args>
|
||||
accept_op(DeducedHandler&& h,
|
||||
stream<NextLayer>& ws, Args&&... args)
|
||||
: d_(std::allocate_shared<data>(alloc_type{h},
|
||||
: d_(make_handler_ptr<data, Handler>(
|
||||
std::forward<DeducedHandler>(h), ws,
|
||||
std::forward<Args>(args)...))
|
||||
{
|
||||
@@ -206,7 +196,7 @@ public:
|
||||
std::size_t size, accept_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate(size, op->d_->h);
|
||||
allocate(size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -214,7 +204,7 @@ public:
|
||||
void* p, std::size_t size, accept_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
deallocate(p, size, op->d_->h);
|
||||
deallocate(p, size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -228,7 +218,7 @@ public:
|
||||
void asio_handler_invoke(Function&& f, accept_op* op)
|
||||
{
|
||||
return boost_asio_handler_invoke_helpers::
|
||||
invoke(f, op->d_->h);
|
||||
invoke(f, op->d_.handler());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -256,19 +246,17 @@ operator()(error_code const& ec,
|
||||
|
||||
// got message
|
||||
case 1:
|
||||
{
|
||||
// respond to request
|
||||
#if 1
|
||||
// VFALCO I have no idea why passing std::move(*this) crashes
|
||||
d.state = 99;
|
||||
d.ws.async_accept(d.req, *this);
|
||||
#else
|
||||
auto& ws = d.ws;
|
||||
auto req = std::move(d.req);
|
||||
response_op<Handler>{
|
||||
std::move(d.h), d.ws, d.req, true};
|
||||
#endif
|
||||
d_.release_handler(), ws, req, true};
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
d.h(ec);
|
||||
d_.invoke(ec);
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define BEAST_WEBSOCKET_IMPL_CLOSE_IPP
|
||||
|
||||
#include <beast/core/handler_alloc.hpp>
|
||||
#include <beast/core/handler_ptr.hpp>
|
||||
#include <beast/core/static_streambuf.hpp>
|
||||
#include <beast/core/stream_concepts.hpp>
|
||||
#include <memory>
|
||||
@@ -30,28 +31,25 @@ class stream<NextLayer>::close_op
|
||||
|
||||
struct data : op
|
||||
{
|
||||
bool cont;
|
||||
stream<NextLayer>& ws;
|
||||
close_reason cr;
|
||||
Handler h;
|
||||
fb_type fb;
|
||||
bool cont;
|
||||
int state = 0;
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_, stream<NextLayer>& ws_,
|
||||
data(Handler& handler, stream<NextLayer>& ws_,
|
||||
close_reason const& cr_)
|
||||
: ws(ws_)
|
||||
: cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(handler))
|
||||
, ws(ws_)
|
||||
, cr(cr_)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
, cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(h))
|
||||
{
|
||||
ws.template write_close<
|
||||
static_streambuf>(fb, cr);
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<data> d_;
|
||||
handler_ptr<data, Handler> d_;
|
||||
|
||||
public:
|
||||
close_op(close_op&&) = default;
|
||||
@@ -60,7 +58,7 @@ public:
|
||||
template<class DeducedHandler, class... Args>
|
||||
close_op(DeducedHandler&& h,
|
||||
stream<NextLayer>& ws, Args&&... args)
|
||||
: d_(std::allocate_shared<data>(alloc_type{h},
|
||||
: d_(make_handler_ptr<data, Handler>(
|
||||
std::forward<DeducedHandler>(h), ws,
|
||||
std::forward<Args>(args)...))
|
||||
{
|
||||
@@ -83,7 +81,7 @@ public:
|
||||
std::size_t size, close_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate(size, op->d_->h);
|
||||
allocate(size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -91,7 +89,7 @@ public:
|
||||
void* p, std::size_t size, close_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
deallocate(p, size, op->d_->h);
|
||||
deallocate(p, size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -105,7 +103,7 @@ public:
|
||||
void asio_handler_invoke(Function&& f, close_op* op)
|
||||
{
|
||||
return boost_asio_handler_invoke_helpers::
|
||||
invoke(f, op->d_->h);
|
||||
invoke(f, op->d_.handler());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -188,7 +186,7 @@ upcall:
|
||||
if(d.ws.wr_block_ == &d)
|
||||
d.ws.wr_block_ = nullptr;
|
||||
d.ws.rd_op_.maybe_invoke();
|
||||
d.h(ec);
|
||||
d_.invoke(ec);
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <beast/http/read.hpp>
|
||||
#include <beast/http/write.hpp>
|
||||
#include <beast/core/handler_alloc.hpp>
|
||||
#include <beast/core/handler_ptr.hpp>
|
||||
#include <beast/core/stream_concepts.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <memory>
|
||||
@@ -33,29 +34,26 @@ class stream<NextLayer>::handshake_op
|
||||
|
||||
struct data
|
||||
{
|
||||
bool cont;
|
||||
stream<NextLayer>& ws;
|
||||
Handler h;
|
||||
std::string key;
|
||||
http::request<http::empty_body> req;
|
||||
http::response<http::string_body> resp;
|
||||
bool cont;
|
||||
int state = 0;
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_, stream<NextLayer>& ws_,
|
||||
data(Handler& handler, stream<NextLayer>& ws_,
|
||||
boost::string_ref const& host,
|
||||
boost::string_ref const& resource)
|
||||
: ws(ws_)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
: cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(handler))
|
||||
, ws(ws_)
|
||||
, req(ws.build_request(host, resource, key))
|
||||
, cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(h))
|
||||
{
|
||||
ws.reset();
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<data> d_;
|
||||
handler_ptr<data, Handler> d_;
|
||||
|
||||
public:
|
||||
handshake_op(handshake_op&&) = default;
|
||||
@@ -64,7 +62,7 @@ public:
|
||||
template<class DeducedHandler, class... Args>
|
||||
handshake_op(DeducedHandler&& h,
|
||||
stream<NextLayer>& ws, Args&&... args)
|
||||
: d_(std::allocate_shared<data>(alloc_type{h},
|
||||
: d_(make_handler_ptr<data, Handler>(
|
||||
std::forward<DeducedHandler>(h), ws,
|
||||
std::forward<Args>(args)...))
|
||||
{
|
||||
@@ -79,7 +77,7 @@ public:
|
||||
std::size_t size, handshake_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate(size, op->d_->h);
|
||||
allocate(size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -87,7 +85,7 @@ public:
|
||||
void* p, std::size_t size, handshake_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
deallocate(p, size, op->d_->h);
|
||||
deallocate(p, size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -101,7 +99,7 @@ public:
|
||||
void asio_handler_invoke(Function&& f, handshake_op* op)
|
||||
{
|
||||
return boost_asio_handler_invoke_helpers::
|
||||
invoke(f, op->d_->h);
|
||||
invoke(f, op->d_.handler());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -147,7 +145,7 @@ operator()(error_code ec, bool again)
|
||||
}
|
||||
}
|
||||
}
|
||||
d.h(ec);
|
||||
d_.invoke(ec);
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <beast/core/bind_handler.hpp>
|
||||
#include <beast/core/handler_alloc.hpp>
|
||||
#include <beast/core/handler_ptr.hpp>
|
||||
#include <beast/core/stream_concepts.hpp>
|
||||
#include <beast/websocket/detail/frame.hpp>
|
||||
#include <memory>
|
||||
@@ -25,24 +26,18 @@ template<class NextLayer>
|
||||
template<class Handler>
|
||||
class stream<NextLayer>::ping_op
|
||||
{
|
||||
using alloc_type =
|
||||
handler_alloc<char, Handler>;
|
||||
|
||||
struct data : op
|
||||
{
|
||||
stream<NextLayer>& ws;
|
||||
Handler h;
|
||||
detail::frame_streambuf fb;
|
||||
bool cont;
|
||||
stream<NextLayer>& ws;
|
||||
detail::frame_streambuf fb;
|
||||
int state = 0;
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_, stream<NextLayer>& ws_,
|
||||
data(Handler& handler, stream<NextLayer>& ws_,
|
||||
opcode op_, ping_data const& payload)
|
||||
: ws(ws_)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
, cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(h))
|
||||
: cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(handler))
|
||||
, ws(ws_)
|
||||
{
|
||||
using boost::asio::buffer;
|
||||
using boost::asio::buffer_copy;
|
||||
@@ -51,7 +46,7 @@ class stream<NextLayer>::ping_op
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<data> d_;
|
||||
handler_ptr<data, Handler> d_;
|
||||
|
||||
public:
|
||||
ping_op(ping_op&&) = default;
|
||||
@@ -60,7 +55,7 @@ public:
|
||||
template<class DeducedHandler, class... Args>
|
||||
ping_op(DeducedHandler&& h,
|
||||
stream<NextLayer>& ws, Args&&... args)
|
||||
: d_(std::make_shared<data>(
|
||||
: d_(make_handler_ptr<data, Handler>(
|
||||
std::forward<DeducedHandler>(h), ws,
|
||||
std::forward<Args>(args)...))
|
||||
{
|
||||
@@ -81,7 +76,7 @@ public:
|
||||
std::size_t size, ping_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate(size, op->d_->h);
|
||||
allocate(size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -89,7 +84,7 @@ public:
|
||||
void* p, std::size_t size, ping_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
deallocate(p, size, op->d_->h);
|
||||
deallocate(p, size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -103,7 +98,7 @@ public:
|
||||
void asio_handler_invoke(Function&& f, ping_op* op)
|
||||
{
|
||||
return boost_asio_handler_invoke_helpers::
|
||||
invoke(f, op->d_->h);
|
||||
invoke(f, op->d_.handler());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -187,7 +182,7 @@ upcall:
|
||||
if(d.ws.wr_block_ == &d)
|
||||
d.ws.wr_block_ = nullptr;
|
||||
d.ws.rd_op_.maybe_invoke();
|
||||
d.h(ec);
|
||||
d_.invoke(ec);
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <beast/websocket/teardown.hpp>
|
||||
#include <beast/core/buffer_concepts.hpp>
|
||||
#include <beast/core/handler_alloc.hpp>
|
||||
#include <beast/core/handler_ptr.hpp>
|
||||
#include <beast/core/prepare_buffers.hpp>
|
||||
#include <beast/core/static_streambuf.hpp>
|
||||
#include <beast/core/stream_concepts.hpp>
|
||||
@@ -31,9 +32,6 @@ template<class NextLayer>
|
||||
template<class DynamicBuffer, class Handler>
|
||||
class stream<NextLayer>::read_frame_op
|
||||
{
|
||||
using alloc_type =
|
||||
handler_alloc<char, Handler>;
|
||||
|
||||
using fb_type =
|
||||
detail::frame_streambuf;
|
||||
|
||||
@@ -45,30 +43,27 @@ class stream<NextLayer>::read_frame_op
|
||||
|
||||
struct data : op
|
||||
{
|
||||
bool cont;
|
||||
stream<NextLayer>& ws;
|
||||
frame_info& fi;
|
||||
DynamicBuffer& db;
|
||||
Handler h;
|
||||
fb_type fb;
|
||||
boost::optional<dmb_type> dmb;
|
||||
boost::optional<fmb_type> fmb;
|
||||
bool cont;
|
||||
int state = 0;
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_, stream<NextLayer>& ws_,
|
||||
data(Handler& handler, stream<NextLayer>& ws_,
|
||||
frame_info& fi_, DynamicBuffer& sb_)
|
||||
: ws(ws_)
|
||||
: cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(handler))
|
||||
, ws(ws_)
|
||||
, fi(fi_)
|
||||
, db(sb_)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
, cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(h))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<data> d_;
|
||||
handler_ptr<data, Handler> d_;
|
||||
|
||||
public:
|
||||
read_frame_op(read_frame_op&&) = default;
|
||||
@@ -77,7 +72,7 @@ public:
|
||||
template<class DeducedHandler, class... Args>
|
||||
read_frame_op(DeducedHandler&& h,
|
||||
stream<NextLayer>& ws, Args&&... args)
|
||||
: d_(std::allocate_shared<data>(alloc_type{h},
|
||||
: d_(make_handler_ptr<data, Handler>(
|
||||
std::forward<DeducedHandler>(h), ws,
|
||||
std::forward<Args>(args)...))
|
||||
{
|
||||
@@ -105,7 +100,7 @@ public:
|
||||
std::size_t size, read_frame_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate(size, op->d_->h);
|
||||
allocate(size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -113,7 +108,7 @@ public:
|
||||
void* p, std::size_t size, read_frame_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
deallocate(p, size, op->d_->h);
|
||||
deallocate(p, size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -127,7 +122,7 @@ public:
|
||||
void asio_handler_invoke(Function&& f, read_frame_op* op)
|
||||
{
|
||||
return boost_asio_handler_invoke_helpers::
|
||||
invoke(f, op->d_->h);
|
||||
invoke(f, op->d_.handler());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -545,7 +540,7 @@ upcall:
|
||||
if(d.ws.wr_block_ == &d)
|
||||
d.ws.wr_block_ = nullptr;
|
||||
d.ws.wr_op_.maybe_invoke();
|
||||
d.h(ec);
|
||||
d_.invoke(ec);
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
@@ -734,34 +729,28 @@ template<class NextLayer>
|
||||
template<class DynamicBuffer, class Handler>
|
||||
class stream<NextLayer>::read_op
|
||||
{
|
||||
using alloc_type =
|
||||
handler_alloc<char, Handler>;
|
||||
|
||||
struct data
|
||||
{
|
||||
bool cont;
|
||||
stream<NextLayer>& ws;
|
||||
opcode& op;
|
||||
DynamicBuffer& db;
|
||||
Handler h;
|
||||
frame_info fi;
|
||||
bool cont;
|
||||
int state = 0;
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_,
|
||||
data(Handler& handler,
|
||||
stream<NextLayer>& ws_, opcode& op_,
|
||||
DynamicBuffer& sb_)
|
||||
: ws(ws_)
|
||||
: cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(handler))
|
||||
, ws(ws_)
|
||||
, op(op_)
|
||||
, db(sb_)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
, cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(h))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<data> d_;
|
||||
handler_ptr<data, Handler> d_;
|
||||
|
||||
public:
|
||||
read_op(read_op&&) = default;
|
||||
@@ -770,7 +759,7 @@ public:
|
||||
template<class DeducedHandler, class... Args>
|
||||
read_op(DeducedHandler&& h,
|
||||
stream<NextLayer>& ws, Args&&... args)
|
||||
: d_(std::allocate_shared<data>(alloc_type{h},
|
||||
: d_(make_handler_ptr<data, Handler>(
|
||||
std::forward<DeducedHandler>(h), ws,
|
||||
std::forward<Args>(args)...))
|
||||
{
|
||||
@@ -785,7 +774,7 @@ public:
|
||||
std::size_t size, read_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate(size, op->d_->h);
|
||||
allocate(size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -793,7 +782,7 @@ public:
|
||||
void* p, std::size_t size, read_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
deallocate(p, size, op->d_->h);
|
||||
deallocate(p, size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -807,7 +796,7 @@ public:
|
||||
void asio_handler_invoke(Function&& f, read_op* op)
|
||||
{
|
||||
return boost_asio_handler_invoke_helpers::
|
||||
invoke(f, op->d_->h);
|
||||
invoke(f, op->d_.handler());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -847,7 +836,7 @@ operator()(error_code const& ec, bool again)
|
||||
}
|
||||
}
|
||||
upcall:
|
||||
d.h(ec);
|
||||
d_.invoke(ec);
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
#define BEAST_WEBSOCKET_IMPL_SSL_IPP_INCLUDED
|
||||
|
||||
#include <beast/core/async_completion.hpp>
|
||||
#include <beast/core/handler_alloc.hpp>
|
||||
#include <beast/core/handler_concepts.hpp>
|
||||
#include <beast/core/handler_ptr.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace websocket {
|
||||
@@ -38,31 +40,28 @@ class teardown_ssl_op
|
||||
|
||||
struct data
|
||||
{
|
||||
stream_type& stream;
|
||||
Handler h;
|
||||
bool cont;
|
||||
stream_type& stream;
|
||||
int state = 0;
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_,
|
||||
stream_type& stream_)
|
||||
: stream(stream_)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
, cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(h))
|
||||
data(Handler& handler, stream_type& stream_)
|
||||
: cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(handler))
|
||||
, stream(stream_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<data> d_;
|
||||
handler_ptr<data, Handler> d_;
|
||||
|
||||
public:
|
||||
template<class DeducedHandler>
|
||||
explicit
|
||||
teardown_ssl_op(
|
||||
DeducedHandler&& h, stream_type& stream)
|
||||
: d_(std::make_shared<data>(
|
||||
std::forward<DeducedHandler>(h), stream))
|
||||
: d_(make_handler_ptr<data, Handler>(
|
||||
std::forward<DeducedHandler>(
|
||||
h), stream))
|
||||
{
|
||||
(*this)(error_code{}, false);
|
||||
}
|
||||
@@ -75,7 +74,7 @@ public:
|
||||
teardown_ssl_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate(size, op->d_->h);
|
||||
allocate(size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -83,7 +82,7 @@ public:
|
||||
std::size_t size, teardown_ssl_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
deallocate(p, size, op->d_->h);
|
||||
deallocate(p, size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -99,7 +98,7 @@ public:
|
||||
teardown_ssl_op* op)
|
||||
{
|
||||
return boost_asio_handler_invoke_helpers::
|
||||
invoke(f, op->d_->h);
|
||||
invoke(f, op->d_.handler());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -120,7 +119,7 @@ operator()(error_code ec, bool again)
|
||||
return;
|
||||
}
|
||||
}
|
||||
d.h(ec);
|
||||
d_.invoke(ec);
|
||||
}
|
||||
|
||||
} // detail
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
#define BEAST_WEBSOCKET_IMPL_TEARDOWN_IPP
|
||||
|
||||
#include <beast/core/async_completion.hpp>
|
||||
#include <beast/core/handler_alloc.hpp>
|
||||
#include <beast/core/handler_concepts.hpp>
|
||||
#include <beast/core/handler_ptr.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace beast {
|
||||
@@ -20,37 +22,37 @@ namespace detail {
|
||||
template<class Handler>
|
||||
class teardown_tcp_op
|
||||
{
|
||||
using alloc_type =
|
||||
handler_alloc<char, Handler>;
|
||||
|
||||
using socket_type =
|
||||
boost::asio::ip::tcp::socket;
|
||||
|
||||
struct data
|
||||
{
|
||||
socket_type& socket;
|
||||
Handler h;
|
||||
char buf[8192];
|
||||
bool cont;
|
||||
socket_type& socket;
|
||||
char buf[2048];
|
||||
int state = 0;
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_, socket_type& socket_)
|
||||
: socket(socket_)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
, cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(h))
|
||||
data(Handler& handler, socket_type& socket_)
|
||||
: cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(handler))
|
||||
, socket(socket_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<data> d_;
|
||||
handler_ptr<data, Handler> d_;
|
||||
|
||||
public:
|
||||
template<class DeducedHandler>
|
||||
teardown_tcp_op(
|
||||
DeducedHandler&& h,
|
||||
socket_type& socket)
|
||||
: d_(std::make_shared<data>(
|
||||
std::forward<DeducedHandler>(h),
|
||||
socket))
|
||||
: d_(make_handler_ptr<data, Handler>(
|
||||
std::forward<DeducedHandler>(
|
||||
h), socket))
|
||||
{
|
||||
(*this)(error_code{}, 0, false);
|
||||
}
|
||||
@@ -63,7 +65,7 @@ public:
|
||||
teardown_tcp_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate(size, op->d_->h);
|
||||
allocate(size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -71,7 +73,7 @@ public:
|
||||
std::size_t size, teardown_tcp_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
deallocate(p, size, op->d_->h);
|
||||
deallocate(p, size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -86,7 +88,7 @@ public:
|
||||
teardown_tcp_op* op)
|
||||
{
|
||||
return boost_asio_handler_invoke_helpers::
|
||||
invoke(f, op->d_->h);
|
||||
invoke(f, op->d_.handler());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -119,7 +121,7 @@ operator()(error_code ec, std::size_t, bool again)
|
||||
d.socket.close(ec);
|
||||
ec = error_code{};
|
||||
}
|
||||
d.h(ec);
|
||||
d_.invoke(ec);
|
||||
}
|
||||
|
||||
} // detail
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <beast/core/buffer_concepts.hpp>
|
||||
#include <beast/core/consuming_buffers.hpp>
|
||||
#include <beast/core/handler_alloc.hpp>
|
||||
#include <beast/core/handler_ptr.hpp>
|
||||
#include <beast/core/prepare_buffers.hpp>
|
||||
#include <beast/core/static_streambuf.hpp>
|
||||
#include <beast/core/stream_concepts.hpp>
|
||||
@@ -97,31 +98,27 @@ template<class NextLayer>
|
||||
template<class Buffers, class Handler>
|
||||
class stream<NextLayer>::write_frame_op
|
||||
{
|
||||
using alloc_type =
|
||||
handler_alloc<char, Handler>;
|
||||
|
||||
struct data : op
|
||||
{
|
||||
Handler& handler;
|
||||
bool cont;
|
||||
stream<NextLayer>& ws;
|
||||
consuming_buffers<Buffers> cb;
|
||||
Handler h;
|
||||
detail::frame_header fh;
|
||||
detail::fh_streambuf fh_buf;
|
||||
detail::prepared_key_type key;
|
||||
void* tmp;
|
||||
std::size_t tmp_size;
|
||||
std::uint64_t remain;
|
||||
bool cont;
|
||||
int state = 0;
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_, stream<NextLayer>& ws_,
|
||||
data(Handler& handler_, stream<NextLayer>& ws_,
|
||||
bool fin, Buffers const& bs)
|
||||
: ws(ws_)
|
||||
, cb(bs)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
: handler(handler_)
|
||||
, cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(h))
|
||||
is_continuation(handler))
|
||||
, ws(ws_)
|
||||
, cb(bs)
|
||||
{
|
||||
using beast::detail::clamp;
|
||||
fh.op = ws.wr_.cont ?
|
||||
@@ -139,7 +136,7 @@ class stream<NextLayer>::write_frame_op
|
||||
detail::prepare_key(key, fh.key);
|
||||
tmp_size = clamp(fh.len, ws.wr_buf_size_);
|
||||
tmp = boost_asio_handler_alloc_helpers::
|
||||
allocate(tmp_size, h);
|
||||
allocate(tmp_size, handler);
|
||||
remain = fh.len;
|
||||
}
|
||||
else
|
||||
@@ -153,11 +150,11 @@ class stream<NextLayer>::write_frame_op
|
||||
{
|
||||
if(tmp)
|
||||
boost_asio_handler_alloc_helpers::
|
||||
deallocate(tmp, tmp_size, h);
|
||||
deallocate(tmp, tmp_size, handler);
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<data> d_;
|
||||
handler_ptr<data, Handler> d_;
|
||||
|
||||
public:
|
||||
write_frame_op(write_frame_op&&) = default;
|
||||
@@ -166,9 +163,9 @@ public:
|
||||
template<class DeducedHandler, class... Args>
|
||||
write_frame_op(DeducedHandler&& h,
|
||||
stream<NextLayer>& ws, Args&&... args)
|
||||
: d_(std::make_shared<data>(
|
||||
std::forward<DeducedHandler>(h), ws,
|
||||
std::forward<Args>(args)...))
|
||||
: d_(make_handler_ptr<data, Handler>(
|
||||
std::forward<DeducedHandler>(h),
|
||||
ws, std::forward<Args>(args)...))
|
||||
{
|
||||
(*this)(error_code{}, false);
|
||||
}
|
||||
@@ -187,7 +184,7 @@ public:
|
||||
std::size_t size, write_frame_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate(size, op->d_->h);
|
||||
allocate(size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -195,7 +192,7 @@ public:
|
||||
void* p, std::size_t size, write_frame_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
deallocate(p, size, op->d_->h);
|
||||
deallocate(p, size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -209,7 +206,7 @@ public:
|
||||
void asio_handler_invoke(Function&& f, write_frame_op* op)
|
||||
{
|
||||
return boost_asio_handler_invoke_helpers::
|
||||
invoke(f, op->d_->h);
|
||||
invoke(f, op->d_.handler());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -333,16 +330,10 @@ operator()(error_code ec, bool again)
|
||||
}
|
||||
}
|
||||
upcall:
|
||||
if(d.tmp)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::
|
||||
deallocate(d.tmp, d.tmp_size, d.h);
|
||||
d.tmp = nullptr;
|
||||
}
|
||||
if(d.ws.wr_block_ == &d)
|
||||
d.ws.wr_block_ = nullptr;
|
||||
d.ws.rd_op_.maybe_invoke();
|
||||
d.h(ec);
|
||||
d_.invoke(ec);
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
@@ -532,32 +523,26 @@ template<class NextLayer>
|
||||
template<class Buffers, class Handler>
|
||||
class stream<NextLayer>::write_op
|
||||
{
|
||||
using alloc_type =
|
||||
handler_alloc<char, Handler>;
|
||||
|
||||
struct data : op
|
||||
{
|
||||
bool cont;
|
||||
stream<NextLayer>& ws;
|
||||
consuming_buffers<Buffers> cb;
|
||||
Handler h;
|
||||
std::size_t remain;
|
||||
bool cont;
|
||||
int state = 0;
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_,
|
||||
stream<NextLayer>& ws_, Buffers const& bs)
|
||||
: ws(ws_)
|
||||
data(Handler& handler, stream<NextLayer>& ws_,
|
||||
Buffers const& bs)
|
||||
: cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(handler))
|
||||
, ws(ws_)
|
||||
, cb(bs)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
, remain(boost::asio::buffer_size(cb))
|
||||
, cont(boost_asio_handler_cont_helpers::
|
||||
is_continuation(h))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<data> d_;
|
||||
handler_ptr<data, Handler> d_;
|
||||
|
||||
public:
|
||||
write_op(write_op&&) = default;
|
||||
@@ -567,7 +552,7 @@ public:
|
||||
explicit
|
||||
write_op(DeducedHandler&& h,
|
||||
stream<NextLayer>& ws, Args&&... args)
|
||||
: d_(std::allocate_shared<data>(alloc_type{h},
|
||||
: d_(make_handler_ptr<data, Handler>(
|
||||
std::forward<DeducedHandler>(h), ws,
|
||||
std::forward<Args>(args)...))
|
||||
{
|
||||
@@ -581,7 +566,7 @@ public:
|
||||
std::size_t size, write_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate(size, op->d_->h);
|
||||
allocate(size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -589,7 +574,7 @@ public:
|
||||
void* p, std::size_t size, write_op* op)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
deallocate(p, size, op->d_->h);
|
||||
deallocate(p, size, op->d_.handler());
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -603,7 +588,7 @@ public:
|
||||
void asio_handler_invoke(Function&& f, write_op* op)
|
||||
{
|
||||
return boost_asio_handler_invoke_helpers::
|
||||
invoke(f, op->d_->h);
|
||||
invoke(f, op->d_.handler());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -637,7 +622,7 @@ operator()(error_code ec, bool again)
|
||||
break;
|
||||
}
|
||||
}
|
||||
d.h(ec);
|
||||
d_.invoke(ec);
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
|
||||
Reference in new issue
Block a user