Fix data race in http server examples

When using `beast::tcp_stream`, the user must make sure that async operations
are initiated from within the strand associated with the stream.

Signed-off-by: Damian Jarek <damian.jarek93@gmail.com>
This commit is contained in:
Damian Jarek
2019-07-14 20:19:58 +02:00
committed by Vinnie Falco
parent 9170a0daaa
commit 3817fb4c94
5 changed files with 73 additions and 15 deletions

View File

@ -19,6 +19,7 @@
#include <boost/beast/http.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/dispatch.hpp>
#include <boost/asio/strand.hpp>
#include <boost/config.hpp>
#include <algorithm>
@ -298,9 +299,24 @@ public:
// Start the asynchronous operation
void
run()
{
// We need to be executing within a strand to perform async operations
// on the I/O objects in this session. Although not strictly necessary
// for single-threaded contexts, this example code is written to be
// thread-safe by default.
net::dispatch(
stream_.get_executor(),
beast::bind_front_handler(
&session::on_run,
shared_from_this()));
}
void
on_run()
{
// Set the timeout.
beast::get_lowest_layer(stream_).expires_after(std::chrono::seconds(30));
beast::get_lowest_layer(stream_).expires_after(
std::chrono::seconds(30));
// Perform the SSL handshake
stream_.async_handshake(

View File

@ -16,6 +16,7 @@
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/dispatch.hpp>
#include <boost/asio/strand.hpp>
#include <boost/config.hpp>
#include <algorithm>
@ -273,7 +274,14 @@ public:
void
run()
{
do_read();
// We need to be executing within a strand to perform async operations
// on the I/O objects in this session. Although not strictly necessary
// for single-threaded contexts, this example code is written to be
// thread-safe by default.
net::dispatch(stream_.get_executor(),
beast::bind_front_handler(
&session::do_read,
shared_from_this()));
}
void

View File

@ -19,6 +19,7 @@
#include <boost/beast/http.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/dispatch.hpp>
#include <boost/asio/strand.hpp>
#include <boost/config.hpp>
#include <algorithm>
@ -396,7 +397,14 @@ public:
void
run()
{
do_read();
// We need to be executing within a strand to perform async operations
// on the I/O objects in this session. Although not strictly necessary
// for single-threaded contexts, this example code is written to be
// thread-safe by default.
net::dispatch(stream_.get_executor(),
beast::bind_front_handler(
&session::do_read,
shared_from_this()));
}
void
@ -442,17 +450,23 @@ public:
void
run()
{
auto self = shared_from_this();
// We need to be executing within a strand to perform async operations
// on the I/O objects in this session.
net::dispatch(stream_.get_executor(), [self]() {
// Set the timeout.
beast::get_lowest_layer(stream_).expires_after(std::chrono::seconds(30));
beast::get_lowest_layer(self->stream_).expires_after(
std::chrono::seconds(30));
// Perform the SSL handshake
// Note, this is the buffered version of the handshake.
stream_.async_handshake(
self->stream_.async_handshake(
ssl::stream_base::server,
buffer_.data(),
self->buffer_.data(),
beast::bind_front_handler(
&ssl_session::on_handshake,
shared_from_this()));
self));
});
}
void

View File

@ -20,6 +20,7 @@
#include <boost/beast/ssl.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/coroutine.hpp>
#include <boost/asio/dispatch.hpp>
#include <boost/asio/strand.hpp>
#include <boost/config.hpp>
#include <algorithm>
@ -304,7 +305,16 @@ public:
void
run()
{
loop({}, 0, false);
// We need to be executing within a strand to perform async operations
// on the I/O objects in this session.Although not strictly necessary
// for single-threaded contexts, this example code is written to be
// thread-safe by default.
net::dispatch(stream_.get_executor(),
beast::bind_front_handler(&session::loop,
shared_from_this(),
beast::error_code{},
0,
false));
}
#include <boost/asio/yield.hpp>

View File

@ -17,6 +17,7 @@
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/coroutine.hpp>
#include <boost/asio/dispatch.hpp>
#include <boost/asio/strand.hpp>
#include <boost/config.hpp>
#include <algorithm>
@ -278,7 +279,16 @@ public:
void
run()
{
loop(false, {}, 0);
// We need to be executing within a strand to perform async operations
// on the I/O objects in this session. Although not strictly necessary
// for single-threaded contexts, this example code is written to be
// thread-safe by default.
net::dispatch(stream_.get_executor(),
beast::bind_front_handler(&session::loop,
shared_from_this(),
false,
beast::error_code{},
0));
}
#include <boost/asio/yield.hpp>