0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-07-02 16:58:19 +02:00

ircd::db: Assert synchronization for sequential file operations; update offset on PositionedRead().

This commit is contained in:
Jason Volk 2018-12-02 17:18:37 -08:00
parent c1d915db7a
commit e8088ce52a
2 changed files with 47 additions and 4 deletions

View file

@ -24,6 +24,7 @@ struct ircd::db::database::env::sequential_file final
static const fs::fd::opts default_opts; static const fs::fd::opts default_opts;
database &d; database &d;
ctx::mutex mutex;
fs::fd::opts opts; fs::fd::opts opts;
fs::fd fd; fs::fd fd;
size_t _buffer_align; size_t _buffer_align;

View file

@ -5980,6 +5980,20 @@ ircd::db::database::env::sequential_file::Read(size_t length,
noexcept try noexcept try
{ {
const ctx::uninterruptible::nothrow ui; const ctx::uninterruptible::nothrow ui;
const std::unique_lock<decltype(mutex)> lock
{
mutex, std::try_to_lock
};
// RocksDB sez that this call requires "External synchronization" i.e the
// caller, not this class is responsible for exclusion. We assert anyway.
if(unlikely(!bool(lock)))
throw assertive
{
"'%s': Unexpected concurrent access to seqfile %p",
d.name,
this
};
assert(result); assert(result);
assert(scratch); assert(scratch);
@ -6001,13 +6015,13 @@ noexcept try
scratch, length scratch, length
}; };
const auto read const const_buffer read
{ {
fs::read(fd, buf, offset) fs::read(fd, buf, offset)
}; };
*result = slice(read); *result = slice(read);
offset += length; this->offset += size(read);
return Status::OK(); return Status::OK();
} }
catch(const fs::error &e) catch(const fs::error &e)
@ -6051,15 +6065,28 @@ ircd::db::database::env::sequential_file::PositionedRead(uint64_t offset,
noexcept try noexcept try
{ {
const ctx::uninterruptible::nothrow ui; const ctx::uninterruptible::nothrow ui;
const std::unique_lock<decltype(mutex)> lock
{
mutex, std::try_to_lock
};
if(unlikely(!bool(lock)))
throw assertive
{
"'%s': Unexpected concurrent access to seqfile %p",
d.name,
this
};
assert(result); assert(result);
assert(scratch); assert(scratch);
#ifdef RB_DEBUG_DB_ENV #ifdef RB_DEBUG_DB_ENV
log::debug log::debug
{ {
log, "'%s': seqfile:%p positioned read:%p offset:%zu length:%zu scratch:%p", log, "'%s': seqfile:%p offset:%zu positioned read:%p offset:%zu length:%zu scratch:%p",
d.name, d.name,
this, this,
this->offset,
result, result,
offset, offset,
length, length,
@ -6072,12 +6099,13 @@ noexcept try
scratch, length scratch, length
}; };
const auto read const const_buffer read
{ {
fs::read(fd, buf, offset) fs::read(fd, buf, offset)
}; };
*result = slice(read); *result = slice(read);
this->offset = std::max(this->offset, off_t(offset + size(read)));
return Status::OK(); return Status::OK();
} }
catch(const fs::error &e) catch(const fs::error &e)
@ -6118,6 +6146,20 @@ ircd::db::database::env::sequential_file::Skip(uint64_t size)
noexcept noexcept
{ {
const ctx::uninterruptible::nothrow ui; const ctx::uninterruptible::nothrow ui;
const std::unique_lock<decltype(mutex)> lock
{
mutex, std::try_to_lock
};
// RocksDB sez that this call requires "External synchronization" i.e the
// caller, not this class is responsible for exclusion. We assert anyway.
if(unlikely(!bool(lock)))
throw assertive
{
"'%s': Unexpected concurrent access to seqfile %p",
d.name,
this
};
#ifdef RB_DEBUG_DB_ENV #ifdef RB_DEBUG_DB_ENV
log::debug log::debug