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