Don't use typeid

This commit is contained in:
Vinnie Falco
2018-02-18 18:46:12 -08:00
parent 1a88cb147b
commit a4eb96fcb9
8 changed files with 40 additions and 38 deletions

View File

@@ -1,3 +1,9 @@
Version 156:
* Don't use typeid
--------------------------------------------------------------------------------
Version 155:
* Fix memory leak in advanced server examples

View File

@@ -17,7 +17,6 @@
#include <boost/beast/core/buffers_suffix.hpp>
#include <boost/beast/core/error.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/type_index.hpp>
#include <cstdint>
#include <memory>
@@ -27,57 +26,57 @@ namespace websocket {
namespace detail {
// used to order reads and writes
class type_mutex
class soft_mutex
{
boost::typeindex::type_index ti_ = typeid(type_mutex);
int id_ = 0;
public:
type_mutex() = default;
type_mutex(type_mutex const&) = delete;
type_mutex& operator=(type_mutex const&) = delete;
soft_mutex() = default;
soft_mutex(soft_mutex const&) = delete;
soft_mutex& operator=(soft_mutex const&) = delete;
type_mutex(type_mutex&& other) noexcept
: ti_(other.ti_)
soft_mutex(soft_mutex&& other) noexcept
: id_(other.id_)
{
other.ti_ = boost::typeindex::type_id<void>();
other.id_ = 0;
}
type_mutex& operator=(type_mutex&& other) noexcept
soft_mutex& operator=(soft_mutex&& other) noexcept
{
ti_ = other.ti_;
other.ti_ = boost::typeindex::type_id<void>();
id_ = other.id_;
other.id_ = 0;
return *this;
}
// VFALCO I'm not too happy that this function is needed
void reset()
{
ti_ = typeid(void);
id_ = 0;
}
bool is_locked() const
{
return ti_ != boost::typeindex::type_id<void>();
return id_ != 0;
}
template<class T>
bool is_locked(T const*) const
{
return ti_ == boost::typeindex::type_id<T>();
return id_ == T::id;
}
template<class T>
void lock(T const*)
{
BOOST_ASSERT(ti_ == boost::typeindex::type_id<void>());
ti_ = typeid(T);
BOOST_ASSERT(id_ == 0);
id_ = T::id;
}
template<class T>
void unlock(T const*)
{
BOOST_ASSERT(ti_ == boost::typeindex::type_id<T>());
ti_ = typeid(void);
BOOST_ASSERT(id_ == T::id);
id_ = 0;
}
template<class T>
@@ -89,19 +88,19 @@ public:
// for an async_read to complete before performing another
// async_read.
//
BOOST_ASSERT(ti_ != boost::typeindex::type_id<T>());
if(ti_ != boost::typeindex::type_id<void>())
BOOST_ASSERT(id_ != T::id);
if(id_ != 0)
return false;
ti_ = typeid(T);
id_ = T::id;
return true;
}
template<class T>
bool try_unlock(T const*)
{
if(ti_ != boost::typeindex::type_id<T>())
if(id_ != T::id)
return false;
ti_ = boost::typeindex::type_id<void>();
id_ = 0;
return true;
}
};

View File

@@ -61,6 +61,8 @@ class stream<NextLayer, deflateSupported>::close_op
handler_ptr<state, Handler> d_;
public:
static constexpr int id = 4; // for soft_mutex
close_op(close_op&&) = default;
close_op(close_op const&) = delete;

View File

@@ -59,6 +59,8 @@ class stream<NextLayer, deflateSupported>::ping_op
handler_ptr<state, Handler> d_;
public:
static constexpr int id = 3; // for soft_mutex
ping_op(ping_op&&) = default;
ping_op(ping_op const&) = delete;

View File

@@ -90,6 +90,8 @@ class stream<NextLayer, deflateSupported>::read_some_op
bool cont_ = false;
public:
static constexpr int id = 1; // for soft_mutex
read_some_op(read_some_op&&) = default;
read_some_op(read_some_op const&) = delete;

View File

@@ -152,6 +152,8 @@ class stream<NextLayer, deflateSupported>::write_some_op
bool cont_ = false;
public:
static constexpr int id = 2; // for soft_mutex
write_some_op(write_some_op&&) = default;
write_some_op(write_some_op const&) = delete;

View File

@@ -180,14 +180,14 @@ class stream
= true;
bool rd_close_ // did we read a close frame?
= false;
detail::type_mutex rd_block_; // op currenly reading
detail::soft_mutex rd_block_; // op currently reading
role_type role_ // server or client
= role_type::client;
status status_
= status::closed;
detail::type_mutex wr_block_; // op currenly writing
detail::soft_mutex wr_block_; // op currently writing
bool wr_close_ // did we write a close frame?
= false;
bool wr_cont_ // next write is a continuation
@@ -3331,10 +3331,8 @@ public:
private:
template<class, class> class accept_op;
template<class> class close_op;
template<class> class fail_op;
template<class> class handshake_op;
template<class> class ping_op;
template<class> class read_fh_op;
template<class, class> class read_some_op;
template<class, class> class read_op;
template<class> class response_op;

View File

@@ -384,15 +384,6 @@ public:
++count;
BEAST_EXPECTS(ec == error::closed,
ec.message());
// Pings after a close are aborted
ws.async_ping("",
[&](error_code ec)
{
++count;
BEAST_EXPECTS(ec == boost::asio::
error::operation_aborted,
ec.message());
});
});
if(! BEAST_EXPECT(run_until(ioc, 100,
[&]{ return ws.wr_close_; })))
@@ -420,7 +411,7 @@ public:
std::size_t n;
for(n = 0; n < limit; ++n)
{
if(count >= 4)
if(count >= 3)
break;
ioc.run_one();
}