Async-Trampoline
view release on metacpan or search on metacpan
src/Async_Initialization.cpp view on Meta::CPAN
static void Async_Cancel_clear (Async* self);
static void Async_Error_clear (Async* self);
static void Async_Value_clear (Async* self);
// Polymorphic
auto Async::clear() -> void
{
ASYNC_LOG_DEBUG("clear() " ASYNC_FORMAT "\n",
ASYNC_FORMAT_ARGS(this));
switch (type) {
case Async_Type::IS_UNINITIALIZED:
break;
case Async_Type::CATEGORY_INITIALIZED:
assert(0);
break;
case Async_Type::IS_PTR:
Async_Ptr_clear(this);
break;
case Async_Type::IS_RAWTHUNK:
Async_RawThunk_clear(this);
break;
case Async_Type::IS_THUNK:
Async_Thunk_clear(this);
break;
case Async_Type::IS_CONCAT:
Async_Binary_clear(*this, type);
break;
case Async_Type::IS_FLOW:
Async_Flow_clear(*this);
break;
case Async_Type::CATEGORY_COMPLETE:
assert(0);
break;
case Async_Type::IS_CANCEL:
Async_Cancel_clear(this);
break;
case Async_Type::CATEGORY_RESOLVED:
assert(0);
break;
case Async_Type::IS_ERROR:
Async_Error_clear(this);
break;
case Async_Type::IS_VALUE:
Async_Value_clear(this);
break;
default:
assert(0);
}
}
auto Async::set_from(Async&& other) -> void
{
assert(type == Async_Type::IS_UNINITIALIZED);
assert(other.blocked.size() == 0);
switch (other.type)
{
case Async_Type::IS_UNINITIALIZED:
break;
case Async_Type::CATEGORY_INITIALIZED:
assert(0);
break;
case Async_Type::IS_PTR:
set_to_Ptr(std::move(other.as_ptr));
Async_Ptr_clear(&other);
break;
case Async_Type::IS_RAWTHUNK:
assert(0); // TODO not implemented
break;
case Async_Type::IS_THUNK:
set_to_Thunk(
std::move(other.as_thunk.callback),
std::move(other.as_thunk.dependency));
Async_Thunk_clear(&other);
break;
case Async_Type::IS_CONCAT:
set_to_Binary(
*this,
other.type,
std::move(other.as_binary.left),
std::move(other.as_binary.right));
Async_Binary_clear(other, other.type);
break;
case Async_Type::IS_FLOW:
set_to_Flow(std::move(other.as_flow));
Async_Flow_clear(other);
break;
case Async_Type::CATEGORY_COMPLETE:
assert(0);
break;
case Async_Type::IS_CANCEL:
set_to_Cancel();
Async_Cancel_clear(&other);
break;
case Async_Type::CATEGORY_RESOLVED:
assert(0);
break;
case Async_Type::IS_ERROR:
set_to_Error(std::move(other.as_error));
Async_Error_clear(&other);
break;
case Async_Type::IS_VALUE:
set_to_Value(std::move(other.as_value));
Async_Value_clear(&other);
break;
default:
assert(0);
}
}
auto Async::operator=(Async& other) -> Async&
{
ASYNC_LOG_DEBUG("unify " ASYNC_FORMAT " with " ASYNC_FORMAT "\n",
ASYNC_FORMAT_ARGS(this),
ASYNC_FORMAT_ARGS(&other));
// as a special case, CANCEL holds no resources and can always be copied
if (other.has_type(Async_Type::IS_CANCEL))
{
clear();
set_to_Cancel();
return *this;
}
if (other.refcount > 1)
{
AsyncRef ref{&other}; // keep ref in case we own it
clear();
set_to_Ptr(std::move(ref));
return *this;
}
assert(other.refcount == 1); // caller is the only owner
// save other in case we might own it, because we clear() ourself.
AsyncRef unref_me{};
if (type != Async_Type::IS_UNINITIALIZED)
unref_me = &other;
clear();
set_from(std::move(other));
return *this;
}
// Ptr
void Async::set_to_Ptr(
AsyncRef target)
{
ASSERT_INIT(this);
assert(target);
target.fold();
ASYNC_LOG_DEBUG("init %p to Ptr: target=" ASYNC_FORMAT "\n",
this,
ASYNC_FORMAT_ARGS(target.decay()));
type = Async_Type::IS_PTR;
new (&as_ptr) AsyncRef { std::move(target) };
// // transfer all dependencies to target
// Async& target_ref = ptr_follow();
// for (auto& depref : blocked)
// target_ref.add_blocked(std::move(depref));
// blocked.clear();
}
void
Async_Ptr_clear(
Async* self)
{
assert(self);
assert(self->type == Async_Type::IS_PTR);
ASYNC_LOG_DEBUG("clear %p of Ptr: target=" ASYNC_FORMAT "\n",
self,
ASYNC_FORMAT_ARGS(self->as_ptr.decay()));
self->type = Async_Type::IS_UNINITIALIZED;
self->as_ptr.~AsyncRef();
}
// RawThunk
void Async::set_to_RawThunk(
Async_RawThunk::Callback callback,
AsyncRef dependency)
{
ASSERT_INIT(this);
assert(callback);
UNUSED(dependency);
assert(0); // TODO not implemented
}
void
Async_RawThunk_clear(
Async* self)
{
assert(self);
assert(self->type == Async_Type::IS_RAWTHUNK);
assert(0); // TODO not implemented
}
// Thunk
void Async::set_to_Thunk(
Async_Thunk::Callback callback,
AsyncRef dependency)
{
ASSERT_INIT(this);
assert(callback);
if (dependency)
dependency.fold();
ASYNC_LOG_DEBUG(
"init %p to Thunk: callback=??? dependency=" ASYNC_FORMAT "\n",
this,
ASYNC_FORMAT_ARGS(dependency.decay()));
type = Async_Type::IS_THUNK;
new (&as_thunk) Async_Thunk{
( run in 1.385 second using v1.01-cache-2.11-cpan-13bb782fe5a )