mirror of
https://github.com/matrix-construct/construct
synced 2024-11-29 10:12:39 +01:00
ircd::ctx: Minor cleanup.
This commit is contained in:
parent
418bbc0441
commit
9eabd745f5
3 changed files with 46 additions and 35 deletions
|
@ -99,7 +99,11 @@ template<class E,
|
||||||
ircd::throw_overload<E, duration>
|
ircd::throw_overload<E, duration>
|
||||||
ircd::ctx::this_ctx::wait(const duration &d)
|
ircd::ctx::this_ctx::wait(const duration &d)
|
||||||
{
|
{
|
||||||
const auto ret(wait<std::nothrow_t>(d));
|
const auto ret
|
||||||
|
{
|
||||||
|
wait<std::nothrow_t>(d)
|
||||||
|
};
|
||||||
|
|
||||||
return ret <= duration(0)?
|
return ret <= duration(0)?
|
||||||
throw E{}:
|
throw E{}:
|
||||||
ret;
|
ret;
|
||||||
|
@ -114,9 +118,11 @@ template<class E,
|
||||||
ircd::nothrow_overload<E, duration>
|
ircd::nothrow_overload<E, duration>
|
||||||
ircd::ctx::this_ctx::wait(const duration &d)
|
ircd::ctx::this_ctx::wait(const duration &d)
|
||||||
{
|
{
|
||||||
using std::chrono::duration_cast;
|
const auto ret
|
||||||
|
{
|
||||||
|
wait(duration_cast<microseconds>(d), std::nothrow)
|
||||||
|
};
|
||||||
|
|
||||||
const auto ret(wait(duration_cast<microseconds>(d), std::nothrow));
|
|
||||||
return duration_cast<duration>(ret);
|
return duration_cast<duration>(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
65
ircd/ctx.cc
65
ircd/ctx.cc
|
@ -118,6 +118,33 @@ catch(const std::exception &e)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Direct context switch to this context.
|
||||||
|
///
|
||||||
|
/// This currently doesn't work yet because the suspension state of this
|
||||||
|
/// context has to be ready to be jumped to and that isn't implemented yet.
|
||||||
|
void
|
||||||
|
ircd::ctx::ctx::jump()
|
||||||
|
{
|
||||||
|
assert(this->yc);
|
||||||
|
assert(current != this); // can't jump to self
|
||||||
|
|
||||||
|
auto &yc(*this->yc);
|
||||||
|
auto &target(*yc.coro_.lock());
|
||||||
|
|
||||||
|
// Jump from the currently running context (source) to *this (target)
|
||||||
|
// with continuation of source after target
|
||||||
|
{
|
||||||
|
current->notes = 0; // Unconditionally cleared here
|
||||||
|
const continuation continuation;
|
||||||
|
target();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(current != this);
|
||||||
|
assert(current->notes == 1); // notes = 1; set by continuation dtor on wakeup
|
||||||
|
|
||||||
|
interruption_point();
|
||||||
|
}
|
||||||
|
|
||||||
/// Yield (suspend) this context until notified.
|
/// Yield (suspend) this context until notified.
|
||||||
///
|
///
|
||||||
/// This context must be currently running otherwise bad things. Returns false
|
/// This context must be currently running otherwise bad things. Returns false
|
||||||
|
@ -153,33 +180,6 @@ ircd::ctx::ctx::wait()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Direct context switch to this context.
|
|
||||||
///
|
|
||||||
/// This currently doesn't work yet because the suspension state of this
|
|
||||||
/// context has to be ready to be jumped to and that isn't implemented yet.
|
|
||||||
void
|
|
||||||
ircd::ctx::ctx::jump()
|
|
||||||
{
|
|
||||||
assert(this->yc);
|
|
||||||
assert(current != this); // can't jump to self
|
|
||||||
|
|
||||||
auto &yc(*this->yc);
|
|
||||||
auto &target(*yc.coro_.lock());
|
|
||||||
|
|
||||||
// Jump from the currently running context (source) to *this (target)
|
|
||||||
// with continuation of source after target
|
|
||||||
{
|
|
||||||
current->notes = 0; // Unconditionally cleared here
|
|
||||||
const continuation continuation;
|
|
||||||
target();
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(current != this);
|
|
||||||
assert(current->notes == 1); // notes = 1; set by continuation dtor on wakeup
|
|
||||||
|
|
||||||
interruption_point();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Notifies this context to resume (wake up from waiting).
|
/// Notifies this context to resume (wake up from waiting).
|
||||||
///
|
///
|
||||||
/// Returns true if this note was the first note received by this context
|
/// Returns true if this note was the first note received by this context
|
||||||
|
@ -190,16 +190,19 @@ ircd::ctx::ctx::note()
|
||||||
if(notes++ > 0)
|
if(notes++ > 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
wake();
|
if(this == current)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
return wake();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wakes a context without a note (internal)
|
/// Wakes a context without a note (internal)
|
||||||
void
|
bool
|
||||||
ircd::ctx::ctx::wake()
|
ircd::ctx::ctx::wake()
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
alarm.cancel();
|
alarm.cancel();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
catch(const boost::system::system_error &e)
|
catch(const boost::system::system_error &e)
|
||||||
{
|
{
|
||||||
|
@ -207,6 +210,8 @@ catch(const boost::system::system_error &e)
|
||||||
{
|
{
|
||||||
"ctx::wake(%p): %s", this, e.what()
|
"ctx::wake(%p): %s", this, e.what()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Throws if this context has been flagged for interruption and clears
|
/// Throws if this context has been flagged for interruption and clears
|
||||||
|
|
|
@ -64,10 +64,10 @@ struct ircd::ctx::ctx
|
||||||
bool termination_point(std::nothrow_t); // Check for terminate
|
bool termination_point(std::nothrow_t); // Check for terminate
|
||||||
void interruption_point(); // throws interrupted or terminated
|
void interruption_point(); // throws interrupted or terminated
|
||||||
|
|
||||||
void wake(); // jump to context by queueing with ios (use note())
|
bool wake(); // jump to context by queueing with ios (use note())
|
||||||
bool note(); // properly request wake()
|
bool note(); // properly request wake()
|
||||||
void jump(); // jump to context directly (returns on your resume)
|
|
||||||
bool wait(); // yield context to ios queue (returns on this resume)
|
bool wait(); // yield context to ios queue (returns on this resume)
|
||||||
|
void jump(); // jump to context directly (returns on your resume)
|
||||||
|
|
||||||
void operator()(boost::asio::yield_context, const std::function<void ()>) noexcept;
|
void operator()(boost::asio::yield_context, const std::function<void ()>) noexcept;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue