mirror of
https://github.com/Zygo/bees.git
synced 2025-05-18 05:45:45 +02:00
bytevector: add some fugly mutexes
We are using ByteVectors from multiple threads in some cases. Mostly these are the status and progress threads which read the ByteVector object references embedded in BEESNOTE macros. Since it's not clear what the data race implications are, protect the shared_ptr in ByteVector with a mutex for now. Signed-off-by: Zygo Blaxell <bees@furryterror.org>
This commit is contained in:
parent
d1015b683f
commit
a59d89ea81
@ -2,6 +2,7 @@
|
|||||||
#define _CRUCIBLE_BYTEVECTOR_H_
|
#define _CRUCIBLE_BYTEVECTOR_H_
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -21,6 +22,8 @@ namespace crucible {
|
|||||||
using iterator = value_type*;
|
using iterator = value_type*;
|
||||||
|
|
||||||
ByteVector() = default;
|
ByteVector() = default;
|
||||||
|
ByteVector(const ByteVector &that);
|
||||||
|
ByteVector& operator=(const ByteVector &that);
|
||||||
ByteVector(size_t size);
|
ByteVector(size_t size);
|
||||||
ByteVector(const ByteVector &that, size_t start, size_t length);
|
ByteVector(const ByteVector &that, size_t start, size_t length);
|
||||||
ByteVector(iterator begin, iterator end, size_t min_size = 0);
|
ByteVector(iterator begin, iterator end, size_t min_size = 0);
|
||||||
@ -49,6 +52,8 @@ namespace crucible {
|
|||||||
private:
|
private:
|
||||||
Pointer m_ptr;
|
Pointer m_ptr;
|
||||||
size_t m_size = 0;
|
size_t m_size = 0;
|
||||||
|
mutable mutex m_mutex;
|
||||||
|
friend ostream & operator<<(ostream &os, const ByteVector &bv);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@ -66,8 +71,6 @@ namespace crucible {
|
|||||||
{
|
{
|
||||||
return reinterpret_cast<T*>(data());
|
return reinterpret_cast<T*>(data());
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream & operator<<(ostream &os, const ByteVector &bv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _CRUCIBLE_BYTEVECTOR_H_
|
#endif // _CRUCIBLE_BYTEVECTOR_H_
|
||||||
|
@ -4,36 +4,43 @@
|
|||||||
#include "crucible/hexdump.h"
|
#include "crucible/hexdump.h"
|
||||||
#include "crucible/string.h"
|
#include "crucible/string.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
namespace crucible {
|
namespace crucible {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
ByteVector::iterator
|
ByteVector::iterator
|
||||||
ByteVector::begin() const
|
ByteVector::begin() const
|
||||||
{
|
{
|
||||||
|
unique_lock<mutex> lock(m_mutex);
|
||||||
return m_ptr.get();
|
return m_ptr.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteVector::iterator
|
ByteVector::iterator
|
||||||
ByteVector::end() const
|
ByteVector::end() const
|
||||||
{
|
{
|
||||||
|
unique_lock<mutex> lock(m_mutex);
|
||||||
return m_ptr.get() + m_size;
|
return m_ptr.get() + m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
ByteVector::size() const
|
ByteVector::size() const
|
||||||
{
|
{
|
||||||
|
unique_lock<mutex> lock(m_mutex);
|
||||||
return m_size;
|
return m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ByteVector::empty() const
|
ByteVector::empty() const
|
||||||
{
|
{
|
||||||
|
unique_lock<mutex> lock(m_mutex);
|
||||||
return !m_ptr || !m_size;
|
return !m_ptr || !m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ByteVector::clear()
|
ByteVector::clear()
|
||||||
{
|
{
|
||||||
|
unique_lock<mutex> lock(m_mutex);
|
||||||
m_ptr.reset();
|
m_ptr.reset();
|
||||||
m_size = 0;
|
m_size = 0;
|
||||||
}
|
}
|
||||||
@ -41,9 +48,28 @@ namespace crucible {
|
|||||||
ByteVector::value_type&
|
ByteVector::value_type&
|
||||||
ByteVector::operator[](size_t size) const
|
ByteVector::operator[](size_t size) const
|
||||||
{
|
{
|
||||||
|
unique_lock<mutex> lock(m_mutex);
|
||||||
return m_ptr.get()[size];
|
return m_ptr.get()[size];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ByteVector::ByteVector(const ByteVector &that)
|
||||||
|
{
|
||||||
|
unique_lock<mutex> lock(that.m_mutex);
|
||||||
|
m_ptr = that.m_ptr;
|
||||||
|
m_size = that.m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteVector&
|
||||||
|
ByteVector::operator=(const ByteVector &that)
|
||||||
|
{
|
||||||
|
unique_lock<mutex> lock_this(m_mutex, defer_lock);
|
||||||
|
unique_lock<mutex> lock_that(that.m_mutex, defer_lock);
|
||||||
|
lock(lock_this, lock_that);
|
||||||
|
m_ptr = that.m_ptr;
|
||||||
|
m_size = that.m_size;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
ByteVector::ByteVector(const ByteVector &that, size_t start, size_t length)
|
ByteVector::ByteVector(const ByteVector &that, size_t start, size_t length)
|
||||||
{
|
{
|
||||||
THROW_CHECK0(out_of_range, that.m_ptr);
|
THROW_CHECK0(out_of_range, that.m_ptr);
|
||||||
@ -62,6 +88,7 @@ namespace crucible {
|
|||||||
ByteVector::value_type&
|
ByteVector::value_type&
|
||||||
ByteVector::at(size_t size) const
|
ByteVector::at(size_t size) const
|
||||||
{
|
{
|
||||||
|
unique_lock<mutex> lock(m_mutex);
|
||||||
THROW_CHECK0(out_of_range, m_ptr);
|
THROW_CHECK0(out_of_range, m_ptr);
|
||||||
THROW_CHECK2(out_of_range, size, m_size, size < m_size);
|
THROW_CHECK2(out_of_range, size, m_size, size < m_size);
|
||||||
return m_ptr.get()[size];
|
return m_ptr.get()[size];
|
||||||
@ -100,6 +127,9 @@ namespace crucible {
|
|||||||
bool
|
bool
|
||||||
ByteVector::operator==(const ByteVector &that) const
|
ByteVector::operator==(const ByteVector &that) const
|
||||||
{
|
{
|
||||||
|
unique_lock<mutex> lock_this(m_mutex, defer_lock);
|
||||||
|
unique_lock<mutex> lock_that(that.m_mutex, defer_lock);
|
||||||
|
lock(lock_this, lock_that);
|
||||||
if (!m_ptr) {
|
if (!m_ptr) {
|
||||||
return !that.m_ptr;
|
return !that.m_ptr;
|
||||||
}
|
}
|
||||||
@ -118,6 +148,7 @@ namespace crucible {
|
|||||||
void
|
void
|
||||||
ByteVector::erase(iterator begin, iterator end)
|
ByteVector::erase(iterator begin, iterator end)
|
||||||
{
|
{
|
||||||
|
unique_lock<mutex> lock(m_mutex);
|
||||||
const size_t size = end - begin;
|
const size_t size = end - begin;
|
||||||
if (!size) return;
|
if (!size) return;
|
||||||
THROW_CHECK0(out_of_range, m_ptr);
|
THROW_CHECK0(out_of_range, m_ptr);
|
||||||
@ -144,11 +175,13 @@ namespace crucible {
|
|||||||
ByteVector::value_type*
|
ByteVector::value_type*
|
||||||
ByteVector::data() const
|
ByteVector::data() const
|
||||||
{
|
{
|
||||||
|
unique_lock<mutex> lock(m_mutex);
|
||||||
return m_ptr.get();
|
return m_ptr.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream&
|
ostream&
|
||||||
operator<<(ostream &os, const ByteVector &bv) {
|
operator<<(ostream &os, const ByteVector &bv) {
|
||||||
|
unique_lock<mutex> lock(bv.m_mutex);
|
||||||
hexdump(os, bv);
|
hexdump(os, bv);
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user