/* SPDX-License-Identifier: MPL-2.0 */
 
#ifndef __ZMQ_DBUFFER_HPP_INCLUDED__
#define __ZMQ_DBUFFER_HPP_INCLUDED__
 
#include <stdlib.h>
#include <stddef.h>
#include <algorithm>
 
#include "mutex.hpp"
#include "msg.hpp"
 
namespace zmq
{
//  dbuffer is a single-producer single-consumer double-buffer
//  implementation.
//
//  The producer writes to a back buffer and then tries to swap
//  pointers between the back and front buffers. If it fails,
//  due to the consumer reading from the front buffer, it just
//  gives up, which is ok since writes are many and redundant.
//
//  The reader simply reads from the front buffer.
//
//  has_msg keeps track of whether there has been a not yet read
//  value written, it is used by ypipe_conflate to mimic ypipe
//  functionality regarding a reader being asleep
 
template <typename T> class dbuffer_t;
 
template <> class dbuffer_t<msg_t>
{
  public:
    dbuffer_t () : _back (&_storage[0]), _front (&_storage[1]), _has_msg (false)
    {
        _back->init ();
        _front->init ();
    }
 
    ~dbuffer_t ()
    {
        _back->close ();
        _front->close ();
    }
 
    void write (const msg_t &value_)
    {
        zmq_assert (value_.check ());
        *_back = value_;
 
        zmq_assert (_back->check ());
 
        if (_sync.try_lock ()) {
            _front->move (*_back);
            _has_msg = true;
 
            _sync.unlock ();
        }
    }
 
    bool read (msg_t *value_)
    {
        if (!value_)
            return false;
 
        {
            scoped_lock_t lock (_sync);
            if (!_has_msg)
                return false;
 
            zmq_assert (_front->check ());
 
            *value_ = *_front;
            _front->init (); // avoid double free
 
            _has_msg = false;
            return true;
        }
    }
 
 
    bool check_read ()
    {
        scoped_lock_t lock (_sync);
 
        return _has_msg;
    }
 
    bool probe (bool (*fn_) (const msg_t &))
    {
        scoped_lock_t lock (_sync);
        return (*fn_) (*_front);
    }
 
 
  private:
    msg_t _storage[2];
    msg_t *_back, *_front;
 
    mutex_t _sync;
    bool _has_msg;
 
    ZMQ_NON_COPYABLE_NOR_MOVABLE (dbuffer_t)
};
}
 
#endif

↑ V730 Not all members of a class are initialized inside the constructor. Consider inspecting: _storage.