0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-05-30 08:43:48 +02:00

ircd:Ⓜ️:vm::notify: Use ctx::future/promise rather than direct context notify.

This commit is contained in:
Jason Volk 2023-03-16 17:36:18 -07:00
parent 0b6669ca20
commit 2331de3f3e
2 changed files with 34 additions and 20 deletions

View file

@ -13,9 +13,10 @@
namespace ircd::m::vm::notify namespace ircd::m::vm::notify
{ {
using value_type = std::pair<const event::id, ctx::ctx *>; using value_type = std::pair<const event::id, ctx::promise<> *>;
using alloc_type = allocator::node<value_type>; using alloc_type = allocator::node<value_type>;
using map_type = std::multimap<event::id, ctx::ctx *, std::less<>, alloc_type::allocator>; using map_type = std::multimap<const event::id, ctx::promise<> *, std::less<>, alloc_type::allocator>;
using node_type = std::pair<map_type::node_type, value_type>;
extern map_type map; extern map_type map;

View file

@ -42,12 +42,7 @@ ircd::m::vm::notify::wait(const vector_view<const event::id> &event_id,
const milliseconds to) const milliseconds to)
{ {
using iterator_type = unique_iterator<map_type>; using iterator_type = unique_iterator<map_type>;
using node_type = std::pair<map_type::node_type, value_type>; static const size_t max_ids {64};
static const size_t max_ids
{
64
};
assume(event_id.size() <= max_ids); assume(event_id.size() <= max_ids);
const auto event_ids const auto event_ids
@ -60,14 +55,15 @@ ircd::m::vm::notify::wait(const vector_view<const event::id> &event_id,
m::exists(event_id) m::exists(event_id)
}; };
size_t exists(0);
node_type node[max_ids]; node_type node[max_ids];
iterator_type it[event_ids]; iterator_type it[event_ids];
ctx::future<> future[event_ids];
ctx::promise<> promise[event_ids];
for(size_t i(0); i < event_ids; ++i) for(size_t i(0); i < event_ids; ++i)
{ {
if(exists_mask & (1UL << i)) if(exists_mask & (1UL << i))
{ {
exists++; future[i] = ctx::future<>{ctx::already};
continue; continue;
} }
@ -85,17 +81,32 @@ ircd::m::vm::notify::wait(const vector_view<const event::id> &event_id,
it[i] = it[i] =
{ {
map, map.emplace(event_id[i], ctx::current) map, map.emplace(event_id[i], promise + i)
};
assert(it[i]->second);
future[i] = ctx::future<>
{
*it[i]->second
}; };
} }
bool timeout(false); auto all
const auto tp(now<system_point>() + to);
while(exists < event_ids && !timeout)
{ {
timeout = ctx::wait_until(tp, std::nothrow); ctx::when_all(future, future + event_ids)
exists = m::exists_count(event_id); };
}
const bool ok
{
all.wait_until(now<system_point>() + to, std::nothrow)
};
const size_t exists
{
!ok?
m::exists_count(event_id):
event_ids
};
assert(exists <= event_ids); assert(exists <= event_ids);
return exists; return exists;
@ -112,11 +123,13 @@ ircd::m::vm::notify::hook_handle(const m::event &event,
for(; pit.first != pit.second; ++pit.first) for(; pit.first != pit.second; ++pit.first)
{ {
const auto &[event_id, ctx] {*pit.first}; const auto &[event_id, promise] {*pit.first};
assert(promise);
assert(promise->valid());
assert(event_id == event.event_id); assert(event_id == event.event_id);
assert(ctx != nullptr);
ctx::notify(*ctx); if(likely(*promise))
promise->set_value();
} }
} }