0
0
Fork 0
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:
Jason Volk 2018-12-07 12:03:25 -08:00
parent 418bbc0441
commit 9eabd745f5
3 changed files with 46 additions and 35 deletions

View file

@ -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);
} }

View file

@ -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

View file

@ -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;