Commit 2ae0c4e2 authored by Simon Giesecke's avatar Simon Giesecke

Problem: unnecessarily complex inheritance hierarchy in decoders, warning C4355 with VS2010

Solution: make allocator a member of decoder_base_t
parent d96a0301
......@@ -57,23 +57,23 @@ template <typename T, typename A = c_single_allocator>
class decoder_base_t : public i_decoder
{
public:
explicit decoder_base_t (A *allocator_) :
explicit decoder_base_t (const size_t buf_size_) :
next (NULL),
read_pos (NULL),
to_read (0),
allocator (allocator_)
allocator (buf_size_)
{
buf = allocator->allocate ();
buf = allocator.allocate ();
}
// The destructor doesn't have to be virtual. It is made virtual
// just to keep ICC and code checking tools from complaining.
virtual ~decoder_base_t () { allocator->deallocate (); }
virtual ~decoder_base_t () { allocator.deallocate (); }
// Returns a buffer to be filled with binary data.
void get_buffer (unsigned char **data_, std::size_t *size_)
{
buf = allocator->allocate ();
buf = allocator.allocate ();
// If we are expected to read large message, we'll opt for zero-
// copy, i.e. we'll ask caller to fill the data directly to the
......@@ -83,14 +83,14 @@ class decoder_base_t : public i_decoder
// As a consequence, large messages being received won't block
// other engines running in the same I/O thread for excessive
// amounts of time.
if (to_read >= allocator->size ()) {
if (to_read >= allocator.size ()) {
*data_ = read_pos;
*size_ = to_read;
return;
}
*data_ = buf;
*size_ = allocator->size ();
*size_ = allocator.size ();
}
// Processes the data in the buffer previously allocated using
......@@ -151,7 +151,7 @@ class decoder_base_t : public i_decoder
virtual void resize_buffer (std::size_t new_size)
{
allocator->resize (new_size);
allocator.resize (new_size);
}
protected:
......@@ -168,6 +168,8 @@ class decoder_base_t : public i_decoder
next = next_;
}
A &get_allocator () { return allocator; }
private:
// Next step. If set to NULL, it means that associated data stream
// is dead. Note that there can be still data in the process in such
......@@ -181,7 +183,7 @@ class decoder_base_t : public i_decoder
std::size_t to_read;
// The duffer for data to decode.
A *allocator;
A allocator;
unsigned char *buf;
decoder_base_t (const decoder_base_t &);
......
......@@ -39,8 +39,7 @@
#include "err.hpp"
zmq::v1_decoder_t::v1_decoder_t (size_t bufsize_, int64_t maxmsgsize_) :
c_single_allocator (bufsize_),
decoder_base_t<v1_decoder_t> (this),
decoder_base_t<v1_decoder_t> (bufsize_),
maxmsgsize (maxmsgsize_)
{
int rc = in_progress.init ();
......
......@@ -36,8 +36,7 @@ namespace zmq
{
// Decoder for ZMTP/1.0 protocol. Converts data batches into messages.
class v1_decoder_t : public zmq::c_single_allocator,
public decoder_base_t<v1_decoder_t>
class v1_decoder_t : public decoder_base_t<v1_decoder_t>
{
public:
v1_decoder_t (size_t bufsize_, int64_t maxmsgsize_);
......
......@@ -41,8 +41,7 @@
zmq::v2_decoder_t::v2_decoder_t (size_t bufsize_,
int64_t maxmsgsize_,
bool zero_copy_) :
shared_message_memory_allocator (bufsize_),
decoder_base_t<v2_decoder_t, shared_message_memory_allocator> (this),
decoder_base_t<v2_decoder_t, shared_message_memory_allocator> (bufsize_),
msg_flags (0),
zero_copy (zero_copy_),
maxmsgsize (maxmsgsize_)
......@@ -114,9 +113,10 @@ int zmq::v2_decoder_t::size_ready (uint64_t msg_size,
// the current message can exceed the current buffer. We have to copy the buffer
// data into a new message and complete it in the next receive.
if (unlikely (
!zero_copy
|| ((unsigned char *) read_pos + msg_size > (data () + size ())))) {
shared_message_memory_allocator &allocator = get_allocator ();
if (unlikely (!zero_copy
|| ((unsigned char *) read_pos + msg_size
> (allocator.data () + allocator.size ())))) {
// a new message has started, but the size would exceed the pre-allocated arena
// this happens every time when a message does not fit completely into the buffer
rc = in_progress.init_size (static_cast<size_t> (msg_size));
......@@ -124,15 +124,16 @@ int zmq::v2_decoder_t::size_ready (uint64_t msg_size,
// construct message using n bytes from the buffer as storage
// increase buffer ref count
// if the message will be a large message, pass a valid refcnt memory location as well
rc = in_progress.init (const_cast<unsigned char *> (read_pos),
static_cast<size_t> (msg_size),
shared_message_memory_allocator::call_dec_ref,
buffer (), provide_content ());
rc =
in_progress.init (const_cast<unsigned char *> (read_pos),
static_cast<size_t> (msg_size),
shared_message_memory_allocator::call_dec_ref,
allocator.buffer (), allocator.provide_content ());
// For small messages, data has been copied and refcount does not have to be increased
if (in_progress.is_zcmsg ()) {
advance_content ();
inc_ref ();
allocator.advance_content ();
allocator.inc_ref ();
}
}
......
......@@ -38,10 +38,8 @@ namespace zmq
// Decoder for ZMTP/2.x framing protocol. Converts data stream into messages.
// The class has to inherit from shared_message_memory_allocator because
// the base class calls allocate in its constructor.
class v2_decoder_t :
// inherit first from allocator to ensure that it is constructed before decoder_base_t
public shared_message_memory_allocator,
public decoder_base_t<v2_decoder_t, shared_message_memory_allocator>
class v2_decoder_t
: public decoder_base_t<v2_decoder_t, shared_message_memory_allocator>
{
public:
v2_decoder_t (size_t bufsize_, int64_t maxmsgsize_, bool zero_copy_);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment