mirror of
https://github.com/boostorg/beast.git
synced 2025-07-29 20:37:31 +02:00
@ -1,3 +1,9 @@
|
||||
1.0.0-b32
|
||||
|
||||
* Add io_service completion invariants test
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
1.0.0-b31
|
||||
|
||||
* Tidy up build settings
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <beast/test/yield_to.hpp>
|
||||
#include <beast/unit_test/suite.hpp>
|
||||
#include <boost/asio/spawn.hpp>
|
||||
#include <atomic>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
@ -374,6 +375,55 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure completion handlers are not leaked
|
||||
struct handler
|
||||
{
|
||||
static std::atomic<std::size_t>&
|
||||
count() { static std::atomic<std::size_t> n; return n; }
|
||||
handler() { ++count(); }
|
||||
~handler() { --count(); }
|
||||
handler(handler const&) { ++count(); }
|
||||
void operator()(error_code const&) const {}
|
||||
};
|
||||
|
||||
void
|
||||
testIoService()
|
||||
{
|
||||
{
|
||||
// Make sure handlers are not destroyed
|
||||
// after calling io_service::stop
|
||||
boost::asio::io_service ios;
|
||||
test::string_istream is{ios,
|
||||
"GET / HTTP/1.1\r\n\r\n"};
|
||||
BEAST_EXPECT(handler::count() == 0);
|
||||
streambuf sb;
|
||||
message<true, streambuf_body, fields> m;
|
||||
async_read(is, sb, m, handler{});
|
||||
BEAST_EXPECT(handler::count() > 0);
|
||||
ios.stop();
|
||||
BEAST_EXPECT(handler::count() > 0);
|
||||
ios.reset();
|
||||
BEAST_EXPECT(handler::count() > 0);
|
||||
ios.run_one();
|
||||
BEAST_EXPECT(handler::count() == 0);
|
||||
}
|
||||
{
|
||||
// Make sure uninvoked handlers are
|
||||
// destroyed when calling ~io_service
|
||||
{
|
||||
boost::asio::io_service ios;
|
||||
test::string_istream is{ios,
|
||||
"GET / HTTP/1.1\r\n\r\n"};
|
||||
BEAST_EXPECT(handler::count() == 0);
|
||||
streambuf sb;
|
||||
message<true, streambuf_body, fields> m;
|
||||
async_read(is, sb, m, handler{});
|
||||
BEAST_EXPECT(handler::count() > 0);
|
||||
}
|
||||
BEAST_EXPECT(handler::count() == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
testThrow();
|
||||
@ -382,6 +432,8 @@ public:
|
||||
yield_to(&read_test::testReadHeaders, this);
|
||||
yield_to(&read_test::testRead, this);
|
||||
yield_to(&read_test::testEof, this);
|
||||
|
||||
testIoService();
|
||||
}
|
||||
};
|
||||
|
||||
@ -389,4 +441,3 @@ BEAST_DEFINE_TESTSUITE(read,http,beast);
|
||||
|
||||
} // http
|
||||
} // beast
|
||||
|
||||
|
@ -639,6 +639,61 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure completion handlers are not leaked
|
||||
struct handler
|
||||
{
|
||||
static std::atomic<std::size_t>&
|
||||
count() { static std::atomic<std::size_t> n; return n; }
|
||||
handler() { ++count(); }
|
||||
~handler() { --count(); }
|
||||
handler(handler const&) { ++count(); }
|
||||
void operator()(error_code const&) const {}
|
||||
};
|
||||
|
||||
void
|
||||
testIoService()
|
||||
{
|
||||
{
|
||||
// Make sure handlers are not destroyed
|
||||
// after calling io_service::stop
|
||||
boost::asio::io_service ios;
|
||||
test::string_ostream os{ios};
|
||||
BEAST_EXPECT(handler::count() == 0);
|
||||
message<true, string_body, fields> m;
|
||||
m.method = "GET";
|
||||
m.version = 11;
|
||||
m.url = "/";
|
||||
m.fields["Content-Length"] = "5";
|
||||
m.body = "*****";
|
||||
async_write(os, m, handler{});
|
||||
BEAST_EXPECT(handler::count() > 0);
|
||||
ios.stop();
|
||||
BEAST_EXPECT(handler::count() > 0);
|
||||
ios.reset();
|
||||
BEAST_EXPECT(handler::count() > 0);
|
||||
ios.run_one();
|
||||
BEAST_EXPECT(handler::count() == 0);
|
||||
}
|
||||
{
|
||||
// Make sure uninvoked handlers are
|
||||
// destroyed when calling ~io_service
|
||||
{
|
||||
boost::asio::io_service ios;
|
||||
test::string_ostream is{ios};
|
||||
BEAST_EXPECT(handler::count() == 0);
|
||||
message<true, string_body, fields> m;
|
||||
m.method = "GET";
|
||||
m.version = 11;
|
||||
m.url = "/";
|
||||
m.fields["Content-Length"] = "5";
|
||||
m.body = "*****";
|
||||
async_write(is, m, handler{});
|
||||
BEAST_EXPECT(handler::count() > 0);
|
||||
}
|
||||
BEAST_EXPECT(handler::count() == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
yield_to(&write_test::testAsyncWriteHeaders, this);
|
||||
@ -647,6 +702,7 @@ public:
|
||||
testOutput();
|
||||
test_std_ostream();
|
||||
testOstream();
|
||||
testIoService();
|
||||
}
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user