0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-29 18:22:50 +01:00
construct/include/ircd/ctx/concurrent.h

89 lines
1.6 KiB
C
Raw Normal View History

2018-12-25 02:58:57 +01:00
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2019 Jason Volk <jason@zemos.net>
2018-12-25 02:58:57 +01:00
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
#pragma once
#define HAVE_IRCD_CTX_CONCURRENT_H
2018-12-25 02:58:57 +01:00
namespace ircd::ctx
{
template<class value> struct concurrent;
2018-12-25 02:58:57 +01:00
}
template<class value>
struct ircd::ctx::concurrent
2018-12-25 02:58:57 +01:00
{
using closure = std::function<void (value)>;
2018-12-25 02:58:57 +01:00
pool &p;
2018-12-25 02:58:57 +01:00
closure c;
dock d;
size_t snd {0};
size_t rcv {0};
size_t fin {0};
2018-12-25 02:58:57 +01:00
std::exception_ptr eptr;
template<class V> void operator()(V&&);
void wait();
2018-12-25 02:58:57 +01:00
concurrent(pool &, closure);
~concurrent() noexcept;
2018-12-25 02:58:57 +01:00
};
template<class value>
ircd::ctx::concurrent<value>::concurrent(pool &p,
closure c)
:p{p}
2018-12-25 02:58:57 +01:00
,c{std::move(c)}
{}
2018-12-25 02:58:57 +01:00
template<class value>
ircd::ctx::concurrent<value>::~concurrent<value>()
2018-12-25 02:58:57 +01:00
noexcept
{
const uninterruptible::nothrow ui;
this->wait();
}
template<class value>
void
ircd::ctx::concurrent<value>::wait()
2018-12-25 02:58:57 +01:00
{
d.wait([this]
{
return snd == fin;
2018-12-25 02:58:57 +01:00
});
}
template<class value>
template<class V>
2018-12-25 02:58:57 +01:00
void
ircd::ctx::concurrent<value>::operator()(V&& v)
2018-12-25 02:58:57 +01:00
{
++snd;
p([this, v(std::move(v))]
2018-12-25 02:58:57 +01:00
{
++rcv; try
{
c(std::move(v));
}
catch(...)
{
eptr = std::current_exception();
}
++fin;
d.notify_all();
2018-12-25 02:58:57 +01:00
});
if(eptr)
std::rethrow_exception(eptr);
}