oom safety implementations
This commit is contained in:
parent
e45872d0c0
commit
86cb9e3d6e
|
@ -313,9 +313,9 @@ ErrorOr<AsyncIoContext> setupAsyncIo() {
|
||||||
|
|
||||||
EventLoop &loop_ref = io_provider->eventLoop();
|
EventLoop &loop_ref = io_provider->eventLoop();
|
||||||
|
|
||||||
return {std::move(io_provider), loop_ref, prt_ref};
|
return {{std::move(io_provider), loop_ref, prt_ref}};
|
||||||
} catch (std::bad_alloc &) {
|
} catch (std::bad_alloc &) {
|
||||||
return criticalError("");
|
return criticalError("Out of memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace gin
|
} // namespace gin
|
||||||
|
|
|
@ -276,13 +276,18 @@ void ConveyorSinks::fail(Error &&error) {
|
||||||
|
|
||||||
void ConveyorSinks::add(Conveyor<void> &&sink) {
|
void ConveyorSinks::add(Conveyor<void> &&sink) {
|
||||||
auto nas = Conveyor<void>::fromConveyor(std::move(sink));
|
auto nas = Conveyor<void>::fromConveyor(std::move(sink));
|
||||||
Own<SinkConveyorNode> sink_node =
|
|
||||||
heap<SinkConveyorNode>(std::move(nas.first), *this);
|
Own<SinkConveyorNode> sink_node = nullptr;
|
||||||
|
try {
|
||||||
|
sink_node = heap<SinkConveyorNode>(std::move(nas.first), *this);
|
||||||
|
}catch(std::bad_alloc&){
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (nas.second) {
|
if (nas.second) {
|
||||||
nas.second->setParent(sink_node.get());
|
nas.second->setParent(sink_node.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
sink_nodes.push_back(std::move(sink_node));
|
sink_nodes.emplace_back(std::move(sink_node));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConveyorSinks::fire() {
|
void ConveyorSinks::fire() {
|
||||||
|
|
|
@ -668,4 +668,4 @@ public:
|
||||||
|
|
||||||
} // namespace gin
|
} // namespace gin
|
||||||
|
|
||||||
#include "async.tmpl.h"
|
#include "async.tmpl.h"
|
||||||
|
|
|
@ -15,53 +15,16 @@ namespace gin {
|
||||||
classname(const classname &) = delete; \
|
classname(const classname &) = delete; \
|
||||||
classname &operator=(const classname &) = delete
|
classname &operator=(const classname &) = delete
|
||||||
|
|
||||||
template <typename T> using Maybe = std::optional<T>;
|
template<typename T> using Maybe = std::optional<T>;
|
||||||
|
|
||||||
template <typename T> class Own {
|
template <typename T> using Own = std::unique_ptr<T>;
|
||||||
private:
|
|
||||||
T *data = nullptr;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Own() = default;
|
|
||||||
Own(T *d) : data{d} {}
|
|
||||||
~Own() {
|
|
||||||
if (data) {
|
|
||||||
delete data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Own(Own<T> &&rhs) : data{rhs.data} { rhs.data = nullptr; }
|
|
||||||
|
|
||||||
Own<T> &operator=(Own<T> &&rhs) {
|
|
||||||
if (data) {
|
|
||||||
delete data;
|
|
||||||
}
|
|
||||||
|
|
||||||
data = rhs.data;
|
|
||||||
rhs.data = nullptr;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
T *operator->() const noexcept { return data; }
|
|
||||||
|
|
||||||
explicit operator bool() const noexcept { return data; }
|
|
||||||
|
|
||||||
T *get() noexcept { return data; }
|
|
||||||
|
|
||||||
typename std::add_lvalue_reference<T>::type operator*() const {
|
|
||||||
return *data;
|
|
||||||
}
|
|
||||||
|
|
||||||
GIN_FORBID_COPY(Own);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T> using Our = std::shared_ptr<T>;
|
template <typename T> using Our = std::shared_ptr<T>;
|
||||||
|
|
||||||
template <typename T> using Lent = std::weak_ptr<T>;
|
template <typename T> using Lent = std::weak_ptr<T>;
|
||||||
|
|
||||||
template <typename T, class... Args> Own<T> heap(Args &&...args) {
|
template <typename T, class... Args> Own<T> heap(Args &&...args) {
|
||||||
return Own<T>(new T{std::forward<Args>(args)...});
|
return Own<T>(new (std::nothrow) T(std::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, class... Args> Our<T> share(Args &&...args) {
|
template <typename T, class... Args> Our<T> share(Args &&...args) {
|
||||||
|
@ -90,4 +53,4 @@ template <typename T> using UnfixVoid = typename VoidUnfix<T>::Type;
|
||||||
template <typename Func, typename T>
|
template <typename Func, typename T>
|
||||||
using ReturnType = typename ReturnTypeHelper<Func, T>::Type;
|
using ReturnType = typename ReturnTypeHelper<Func, T>::Type;
|
||||||
|
|
||||||
} // namespace gin
|
} // namespace gin
|
||||||
|
|
|
@ -9,14 +9,24 @@ Error::Error(const std::string_view &msg, int8_t code)
|
||||||
Error::Error(std::string &&msg, int8_t code)
|
Error::Error(std::string &&msg, int8_t code)
|
||||||
: error_message{std::move(msg)}, error_{code} {}
|
: error_message{std::move(msg)}, error_{code} {}
|
||||||
|
|
||||||
Error::Error(const Error &error)
|
|
||||||
: error_message{error.error_message}, error_{error.error_} {}
|
|
||||||
|
|
||||||
Error::Error(Error &&error)
|
Error::Error(Error &&error)
|
||||||
: error_message{std::move(error.error_message)}, error_{std::move(
|
: error_message{std::move(error.error_message)}, error_{std::move(
|
||||||
error.error_)} {}
|
error.error_)} {}
|
||||||
|
|
||||||
const std::string_view Error::message() const { return error_message; }
|
const std::string_view Error::message() const {
|
||||||
|
|
||||||
|
return std::visit([this](auto&& arg) -> const std::string_view {
|
||||||
|
using T = std::decay_t<decltype(arg)>;
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<T, std::string>){
|
||||||
|
return std::string_view{arg};
|
||||||
|
}else if constexpr (std::is_same_v<T, std::string_view>){
|
||||||
|
return arg;
|
||||||
|
}else{
|
||||||
|
return "Error. Good luck :)";
|
||||||
|
}
|
||||||
|
}, error_message);
|
||||||
|
}
|
||||||
|
|
||||||
bool Error::failed() const { return error_ != 0; }
|
bool Error::failed() const { return error_ != 0; }
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
|
|
||||||
template <typename Formatter>
|
template <typename Formatter>
|
||||||
Error makeError(const Formatter &formatter, int8_t code,
|
Error makeError(const Formatter &formatter, int8_t code,
|
||||||
const std::string_view &generic = "") {
|
const std::string_view &generic) {
|
||||||
try {
|
try {
|
||||||
std::string error_msg = formatter();
|
std::string error_msg = formatter();
|
||||||
return Error{std::move(error_msg), code};
|
return Error{std::move(error_msg), code};
|
||||||
|
@ -53,7 +53,7 @@ Error criticalError(const std::string_view &generic) {
|
||||||
|
|
||||||
template <typename Formatter>
|
template <typename Formatter>
|
||||||
Error criticalError(const Formatter &formatter,
|
Error criticalError(const Formatter &formatter,
|
||||||
const std::string_view &generic = "") {
|
const std::string_view &generic) {
|
||||||
return makeError(formatter, -1, generic);
|
return makeError(formatter, -1, generic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ Error recoverableError(const std::string_view &generic) {
|
||||||
|
|
||||||
template <typename Formatter>
|
template <typename Formatter>
|
||||||
Error recoverableError(const Formatter &formatter,
|
Error recoverableError(const Formatter &formatter,
|
||||||
const std::string_view &generic = "") {
|
const std::string_view &generic) {
|
||||||
return makeError(formatter, -1, generic);
|
return makeError(formatter, -1, generic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,4 +116,4 @@ public:
|
||||||
const T &value() const { return std::get<T>(value_or_error); }
|
const T &value() const { return std::get<T>(value_or_error); }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gin
|
} // namespace gin
|
||||||
|
|
Loading…
Reference in New Issue