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::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)?
throw E{}:
ret;
@ -114,9 +118,11 @@ template<class E,
ircd::nothrow_overload<E, duration>
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);
}

View file

@ -118,6 +118,33 @@ catch(const std::exception &e)
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.
///
/// This context must be currently running otherwise bad things. Returns false
@ -153,33 +180,6 @@ ircd::ctx::ctx::wait()
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).
///
/// Returns true if this note was the first note received by this context
@ -190,16 +190,19 @@ ircd::ctx::ctx::note()
if(notes++ > 0)
return false;
wake();
return true;
if(this == current)
return true;
return wake();
}
/// Wakes a context without a note (internal)
void
bool
ircd::ctx::ctx::wake()
try
{
alarm.cancel();
return true;
}
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()
};
return false;
}
/// 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
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()
void jump(); // jump to context directly (returns on your 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;