mirror of
https://github.com/matrix-construct/construct
synced 2024-12-26 15:33:54 +01:00
ircd: Add exception tools which elide copying.
This commit is contained in:
parent
e752070d06
commit
cff17eaa40
6 changed files with 61 additions and 38 deletions
|
@ -41,6 +41,7 @@ namespace ircd
|
|||
std::system_error make_system_error(const boost::system::system_error &);
|
||||
template<class... args> std::exception_ptr make_system_eptr(args&&...);
|
||||
template<class... args> [[noreturn]] void throw_system_error(args&&...);
|
||||
template<class E, class... args> std::exception_ptr make_exception_ptr(args&&...);
|
||||
|
||||
string_view string(const mutable_buffer &, const std::error_code &);
|
||||
string_view string(const mutable_buffer &, const std::system_error &);
|
||||
|
@ -221,6 +222,19 @@ namespace ircd
|
|||
IRCD_PANICKING(panic, not_implemented)
|
||||
}
|
||||
|
||||
template<class E,
|
||||
class... args>
|
||||
std::exception_ptr
|
||||
ircd::make_exception_ptr(args&&... a)
|
||||
try
|
||||
{
|
||||
throw E{std::forward<args>(a)...};
|
||||
}
|
||||
catch(const E &)
|
||||
{
|
||||
return std::current_exception();
|
||||
};
|
||||
|
||||
template<class... args>
|
||||
void
|
||||
ircd::throw_system_error(args&&... a)
|
||||
|
|
|
@ -43,7 +43,7 @@ struct ircd::server::tag
|
|||
std::unique_ptr<char[]> cancellation;
|
||||
|
||||
void set_exception(std::exception_ptr);
|
||||
template<class... args> void set_exception(args&&...);
|
||||
template<class T, class... args> void set_exception(args&&...);
|
||||
template<class... args> void set_value(args&&...);
|
||||
|
||||
const_buffer make_write_content_buffer() const;
|
||||
|
|
|
@ -2039,16 +2039,20 @@ noexcept
|
|||
}
|
||||
|
||||
ircd::ctx::promise_base::~promise_base()
|
||||
noexcept
|
||||
noexcept try
|
||||
{
|
||||
if(!valid())
|
||||
return;
|
||||
|
||||
if(refcount(state()) == 1)
|
||||
set_exception(std::make_exception_ptr(broken_promise()));
|
||||
throw broken_promise{};
|
||||
else
|
||||
remove(state(), *this);
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
set_exception(std::current_exception());
|
||||
}
|
||||
|
||||
void
|
||||
ircd::ctx::promise_base::set_exception(std::exception_ptr eptr)
|
||||
|
|
|
@ -311,10 +311,7 @@ ircd::server::cancel(request &request)
|
|||
};
|
||||
*/
|
||||
|
||||
tag.set_exception(canceled
|
||||
{
|
||||
"Request canceled"
|
||||
});
|
||||
tag.set_exception<canceled>("Request canceled");
|
||||
|
||||
// We got off easy... The link's write loop won't start an abandoned
|
||||
// request. All that has to be done is indicate a full cancellation
|
||||
|
@ -414,10 +411,10 @@ void
|
|||
ircd::server::peer::cancel()
|
||||
{
|
||||
for(auto &link : this->links)
|
||||
link.cancel_all(std::make_exception_ptr(canceled
|
||||
{
|
||||
link.cancel_all(make_exception_ptr<canceled>
|
||||
(
|
||||
"Request was aborted due to interruption."
|
||||
}));
|
||||
));
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -503,10 +500,10 @@ try
|
|||
"No link to peer %s available", hostcanon
|
||||
};
|
||||
else
|
||||
request.tag->set_exception(unavailable
|
||||
{
|
||||
request.tag->set_exception<unavailable>
|
||||
(
|
||||
"No link to peer %s available", hostcanon
|
||||
});
|
||||
);
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
|
@ -854,10 +851,10 @@ void
|
|||
ircd::server::peer::disperse(link &link)
|
||||
{
|
||||
disperse_uncommitted(link);
|
||||
link.cancel_committed(std::make_exception_ptr(canceled
|
||||
{
|
||||
link.cancel_committed(make_exception_ptr<canceled>
|
||||
(
|
||||
"Request was aborted; though it was partially completed"
|
||||
}));
|
||||
));
|
||||
|
||||
assert(link.queue.empty());
|
||||
}
|
||||
|
@ -1738,9 +1735,9 @@ try
|
|||
assert(done || empty(overrun));
|
||||
return overrun;
|
||||
}
|
||||
catch(const buffer_overrun &e)
|
||||
catch(const buffer_overrun &)
|
||||
{
|
||||
tag.set_exception(e);
|
||||
tag.set_exception(std::current_exception());
|
||||
throw;
|
||||
}
|
||||
|
||||
|
@ -2573,13 +2570,13 @@ ircd::server::tag::read_content(const const_buffer &buffer,
|
|||
if(content_overflow() && !req.opt->truncate_content)
|
||||
{
|
||||
assert(state.content_read > size(content));
|
||||
set_exception(buffer_overrun
|
||||
{
|
||||
set_exception<buffer_overrun>
|
||||
(
|
||||
"buffer of %zu bytes too small for content-length %zu bytes by %zu bytes",
|
||||
size(content),
|
||||
state.content_length,
|
||||
content_overflow()
|
||||
});
|
||||
);
|
||||
}
|
||||
else set_value(state.status);
|
||||
}
|
||||
|
@ -3309,21 +3306,30 @@ ircd::server::tag::set_value(args&&... a)
|
|||
data(request->in.content), size(request->in.content)
|
||||
};
|
||||
|
||||
set_exception(http::error{code, std::string{content}});
|
||||
set_exception<http::error>(code, std::string{content});
|
||||
return;
|
||||
}
|
||||
|
||||
p.set_value(code);
|
||||
}
|
||||
|
||||
template<class... args>
|
||||
template<class E,
|
||||
class... args>
|
||||
void
|
||||
ircd::server::tag::set_exception(args&&... a)
|
||||
try
|
||||
{
|
||||
if(abandoned())
|
||||
return;
|
||||
|
||||
set_exception(std::make_exception_ptr(std::forward<args>(a)...));
|
||||
throw E
|
||||
{
|
||||
std::forward<args>(a)...
|
||||
};
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
set_exception(std::current_exception());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -65,13 +65,8 @@ ircd::net::dns::handle_ipport__A(callback_ipport_one callback,
|
|||
const hostport &hp,
|
||||
const rfc1035::record::A &record)
|
||||
{
|
||||
static const ircd::net::not_found no_record
|
||||
{
|
||||
"Host has no A record"
|
||||
};
|
||||
|
||||
if(!eptr && !record.ip4)
|
||||
eptr = std::make_exception_ptr(no_record);
|
||||
eptr = make_exception_ptr<not_found>("Host has no A record");
|
||||
|
||||
const ipport ipport
|
||||
{
|
||||
|
|
|
@ -101,10 +101,12 @@ ircd::net::dns::cache::_get(const hostport &hp,
|
|||
//TODO: we don't cache what the error was, assuming it's
|
||||
//TODO: NXDomain can be incorrect and in bad ways downstream...
|
||||
static const auto rcode{3}; //NXDomain
|
||||
eptr = std::make_exception_ptr(rfc1035::error
|
||||
{
|
||||
"protocol error #%u (cached) :%s", rcode, rfc1035::rcode.at(rcode)
|
||||
});
|
||||
eptr = make_exception_ptr<rfc1035::error>
|
||||
(
|
||||
"protocol error #%u (cached) :%s",
|
||||
rcode,
|
||||
rfc1035::rcode.at(rcode)
|
||||
);
|
||||
}
|
||||
|
||||
if(count < record.size())
|
||||
|
@ -143,10 +145,12 @@ ircd::net::dns::cache::_get(const hostport &hp,
|
|||
//TODO: we don't cache what the error was, assuming it's
|
||||
//TODO: NXDomain can be incorrect and in bad ways downstream...
|
||||
static const auto rcode{3}; //NXDomain
|
||||
eptr = std::make_exception_ptr(rfc1035::error
|
||||
{
|
||||
"protocol error #%u (cached) :%s", rcode, rfc1035::rcode.at(rcode)
|
||||
});
|
||||
eptr = make_exception_ptr<rfc1035::error>
|
||||
(
|
||||
"protocol error #%u (cached) :%s",
|
||||
rcode,
|
||||
rfc1035::rcode.at(rcode)
|
||||
);
|
||||
}
|
||||
|
||||
if(count < record.size())
|
||||
|
|
Loading…
Reference in a new issue