mirror of
https://github.com/matrix-construct/construct
synced 2024-11-26 00:32:35 +01:00
ircd::ctx::shared_state_base: Add assertions; comments; minor cleanup.
This commit is contained in:
parent
7cc029d726
commit
5b2216fb63
3 changed files with 21 additions and 11 deletions
|
@ -43,12 +43,12 @@ namespace ircd::ctx
|
||||||
/// other party, and a pointer to the next instance of their own party.
|
/// other party, and a pointer to the next instance of their own party.
|
||||||
struct ircd::ctx::promise_base
|
struct ircd::ctx::promise_base
|
||||||
{
|
{
|
||||||
// Internal operations
|
|
||||||
static const promise_base *head(const shared_state_base &);
|
static const promise_base *head(const shared_state_base &);
|
||||||
static const promise_base *head(const promise_base &);
|
static const promise_base *head(const promise_base &);
|
||||||
|
static size_t refcount(const shared_state_base &);
|
||||||
|
|
||||||
static promise_base *head(shared_state_base &);
|
static promise_base *head(shared_state_base &);
|
||||||
static promise_base *head(promise_base &);
|
static promise_base *head(promise_base &);
|
||||||
static size_t refcount(const shared_state_base &);
|
|
||||||
|
|
||||||
shared_state_base *st {nullptr}; // the head of all sharing futures
|
shared_state_base *st {nullptr}; // the head of all sharing futures
|
||||||
promise_base *next {nullptr}; // next sharing promise
|
promise_base *next {nullptr}; // next sharing promise
|
||||||
|
@ -67,7 +67,7 @@ struct ircd::ctx::promise_base
|
||||||
bool operator!() const noexcept;
|
bool operator!() const noexcept;
|
||||||
explicit operator bool() const noexcept;
|
explicit operator bool() const noexcept;
|
||||||
|
|
||||||
void set_exception(std::exception_ptr eptr);
|
void set_exception(std::exception_ptr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
promise_base() = default;
|
promise_base() = default;
|
||||||
|
|
|
@ -57,7 +57,9 @@ enum class ircd::ctx::future_state
|
||||||
/// dereference the promise pointer (head promise) and follow the st->next
|
/// dereference the promise pointer (head promise) and follow the st->next
|
||||||
/// list. The only way to traverse the list of promises is to dereference a
|
/// list. The only way to traverse the list of promises is to dereference a
|
||||||
/// shared_state_base with a valid *p in future_state::PENDING and chase the
|
/// shared_state_base with a valid *p in future_state::PENDING and chase the
|
||||||
/// p->next list.
|
/// p->next list. Each side of the system relies on the other. This means any
|
||||||
|
/// proper iteration of the promise or future lists can only take place before
|
||||||
|
/// dissolution of the system.
|
||||||
struct ircd::ctx::shared_state_base
|
struct ircd::ctx::shared_state_base
|
||||||
{
|
{
|
||||||
static const shared_state_base *head(const shared_state_base &);
|
static const shared_state_base *head(const shared_state_base &);
|
||||||
|
|
22
ircd/ctx.cc
22
ircd/ctx.cc
|
@ -2127,8 +2127,7 @@ ircd::ctx::remove(promise_base &p)
|
||||||
else
|
else
|
||||||
invalidate_futures(p);
|
invalidate_futures(p);
|
||||||
}
|
}
|
||||||
|
else if(last)
|
||||||
if(last)
|
|
||||||
for(auto *next{last->next}; next; last = next, next = next->next)
|
for(auto *next{last->next}; next; last = next, next = next->next)
|
||||||
if(next == &p)
|
if(next == &p)
|
||||||
{
|
{
|
||||||
|
@ -2155,7 +2154,7 @@ ircd::ctx::update(promise_base &new_,
|
||||||
if(last == &old)
|
if(last == &old)
|
||||||
set_futures_promise(new_);
|
set_futures_promise(new_);
|
||||||
|
|
||||||
if(last)
|
else if(last)
|
||||||
for(auto *next{last->next}; next; last = next, next = last->next)
|
for(auto *next{last->next}; next; last = next, next = last->next)
|
||||||
if(next == &old)
|
if(next == &old)
|
||||||
{
|
{
|
||||||
|
@ -2174,6 +2173,7 @@ ircd::ctx::append(promise_base &new_,
|
||||||
promise_base &old)
|
promise_base &old)
|
||||||
{
|
{
|
||||||
assert(new_.st);
|
assert(new_.st);
|
||||||
|
assert(old.st);
|
||||||
if(!old.next)
|
if(!old.next)
|
||||||
{
|
{
|
||||||
old.next = &new_;
|
old.next = &new_;
|
||||||
|
@ -2196,8 +2196,10 @@ ircd::ctx::set_futures_promise(promise_base &p)
|
||||||
};
|
};
|
||||||
|
|
||||||
for(; next; next = next->next)
|
for(; next; next = next->next)
|
||||||
if(is(*next, future_state::PENDING))
|
{
|
||||||
next->p = std::addressof(p);
|
assert(is(*next, future_state::PENDING));
|
||||||
|
next->p = std::addressof(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2209,8 +2211,10 @@ ircd::ctx::invalidate_futures(promise_base &p)
|
||||||
};
|
};
|
||||||
|
|
||||||
for(; next; next = next->next)
|
for(; next; next = next->next)
|
||||||
if(is(*next, future_state::PENDING))
|
{
|
||||||
next->p = nullptr;
|
assert(is(*next, future_state::PENDING));
|
||||||
|
next->p = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -2353,6 +2357,9 @@ ircd::ctx::shared_state_base::operator=(promise_base &p)
|
||||||
{
|
{
|
||||||
this->~shared_state_base();
|
this->~shared_state_base();
|
||||||
new (this) shared_state_base{p};
|
new (this) shared_state_base{p};
|
||||||
|
|
||||||
|
assert(p.valid());
|
||||||
|
assert(is(*this, future_state::PENDING));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2480,6 +2487,7 @@ ircd::ctx::remove(shared_state_base &st)
|
||||||
shared_state_base::head(st)
|
shared_state_base::head(st)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
assert(last);
|
||||||
if(last == &st && is(st, future_state::PENDING))
|
if(last == &st && is(st, future_state::PENDING))
|
||||||
{
|
{
|
||||||
if(last->next)
|
if(last->next)
|
||||||
|
|
Loading…
Reference in a new issue