ircd:Ⓜ️:vm::notify: Add promise/future based notify interface.
This commit is contained in:
parent
2331de3f3e
commit
dcfae310ab
|
@ -13,6 +13,8 @@
|
|||
|
||||
namespace ircd::m::vm::notify
|
||||
{
|
||||
struct future;
|
||||
|
||||
using value_type = std::pair<const event::id, ctx::promise<> *>;
|
||||
using alloc_type = allocator::node<value_type>;
|
||||
using map_type = std::multimap<const event::id, ctx::promise<> *, std::less<>, alloc_type::allocator>;
|
||||
|
@ -24,6 +26,19 @@ namespace ircd::m::vm::notify
|
|||
bool wait(const event::id &, const milliseconds);
|
||||
}
|
||||
|
||||
class ircd::m::vm::notify::future
|
||||
:public ctx::future<>
|
||||
{
|
||||
node_type node;
|
||||
ctx::promise<> promise;
|
||||
unique_iterator<map_type> it;
|
||||
|
||||
public:
|
||||
future(const event::id &);
|
||||
future(future &&) = delete;
|
||||
future(const future &) = delete;
|
||||
};
|
||||
|
||||
/// Yields ctx until event was successfully evaluated. Returns false if
|
||||
/// timeout occurred.
|
||||
inline bool
|
||||
|
|
|
@ -112,6 +112,44 @@ ircd::m::vm::notify::wait(const vector_view<const event::id> &event_id,
|
|||
return exists;
|
||||
}
|
||||
|
||||
//
|
||||
// future::future
|
||||
//
|
||||
|
||||
ircd::m::vm::notify::future::future(const event::id &event_id)
|
||||
:ctx::future<>{ctx::already}
|
||||
{
|
||||
if(m::exists(event_id))
|
||||
return;
|
||||
|
||||
const auto &s
|
||||
{
|
||||
map.get_allocator().s
|
||||
};
|
||||
|
||||
assert(s);
|
||||
assert(!s->next);
|
||||
const scope_restore next
|
||||
{
|
||||
s->next, reinterpret_cast<notify::value_type *>(&node)
|
||||
};
|
||||
|
||||
it =
|
||||
{
|
||||
map, map.emplace(event_id, &promise)
|
||||
};
|
||||
|
||||
assert(it->second);
|
||||
static_cast<ctx::future<> &>(*this) = ctx::future<>
|
||||
{
|
||||
*it->second
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// internal
|
||||
//
|
||||
|
||||
void
|
||||
ircd::m::vm::notify::hook_handle(const m::event &event,
|
||||
vm::eval &)
|
||||
|
|
Loading…
Reference in New Issue