mirror of
https://github.com/matrix-construct/construct
synced 2024-11-12 04:51:08 +01:00
ircd::ctx: Switch from steady_timer to deadline_timer.
This commit is contained in:
parent
320af9e9b8
commit
39ade19ae3
14 changed files with 80 additions and 52 deletions
|
@ -144,14 +144,14 @@ void
|
||||||
ircd::ctx::future<T>::wait()
|
ircd::ctx::future<T>::wait()
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
this->wait_until(steady_point::max());
|
this->wait_until(system_point::max());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
ircd::ctx::future<void>::wait()
|
ircd::ctx::future<void>::wait()
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
this->wait_until(steady_point::max());
|
this->wait_until(system_point::max());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
@ -160,7 +160,7 @@ void
|
||||||
ircd::ctx::future<T>::wait(const duration &d)
|
ircd::ctx::future<T>::wait(const duration &d)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
this->wait_until(now<steady_point>() + d);
|
this->wait_until(now<system_point>() + d);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class duration>
|
template<class duration>
|
||||||
|
@ -168,7 +168,7 @@ void
|
||||||
ircd::ctx::future<void>::wait(const duration &d)
|
ircd::ctx::future<void>::wait(const duration &d)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
this->wait_until(now<steady_point>() + d);
|
this->wait_until(now<system_point>() + d);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
@ -178,7 +178,7 @@ ircd::ctx::future<T>::wait(const duration &d,
|
||||||
std::nothrow_t)
|
std::nothrow_t)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
return this->wait_until(now<steady_point>() + d, std::nothrow);
|
return this->wait_until(now<system_point>() + d, std::nothrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class duration>
|
template<class duration>
|
||||||
|
@ -187,7 +187,7 @@ ircd::ctx::future<void>::wait(const duration &d,
|
||||||
std::nothrow_t)
|
std::nothrow_t)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
return this->wait_until(now<steady_point>() + d, std::nothrow);
|
return this->wait_until(now<system_point>() + d, std::nothrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
|
|
@ -108,7 +108,7 @@ template<class duration>
|
||||||
bool
|
bool
|
||||||
ircd::ctx::mutex::try_lock_for(const duration &d)
|
ircd::ctx::mutex::try_lock_for(const duration &d)
|
||||||
{
|
{
|
||||||
return try_lock_until(steady_clock::now() + d);
|
return try_lock_until(system_clock::now() + d);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class time_point>
|
template<class time_point>
|
||||||
|
|
|
@ -171,21 +171,21 @@ template<class duration>
|
||||||
bool
|
bool
|
||||||
ircd::ctx::shared_mutex::try_unlock_upgrade_and_lock_for(duration&& d)
|
ircd::ctx::shared_mutex::try_unlock_upgrade_and_lock_for(duration&& d)
|
||||||
{
|
{
|
||||||
return try_unlock_upgrade_and_lock_until(steady_clock::now() + d);
|
return try_unlock_upgrade_and_lock_until(system_clock::now() + d);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class duration>
|
template<class duration>
|
||||||
bool
|
bool
|
||||||
ircd::ctx::shared_mutex::try_unlock_shared_and_lock_upgrade_for(duration&& d)
|
ircd::ctx::shared_mutex::try_unlock_shared_and_lock_upgrade_for(duration&& d)
|
||||||
{
|
{
|
||||||
return try_unlock_shared_and_lock_upgrade_until(steady_clock::now() + d);
|
return try_unlock_shared_and_lock_upgrade_until(system_clock::now() + d);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class duration>
|
template<class duration>
|
||||||
bool
|
bool
|
||||||
ircd::ctx::shared_mutex::try_unlock_shared_and_lock_for(duration&& d)
|
ircd::ctx::shared_mutex::try_unlock_shared_and_lock_for(duration&& d)
|
||||||
{
|
{
|
||||||
return try_unlock_shared_and_lock_until(steady_clock::now() + d);
|
return try_unlock_shared_and_lock_until(system_clock::now() + d);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class time_point>
|
template<class time_point>
|
||||||
|
@ -279,21 +279,21 @@ template<class duration>
|
||||||
bool
|
bool
|
||||||
ircd::ctx::shared_mutex::try_lock_upgrade_for(duration&& d)
|
ircd::ctx::shared_mutex::try_lock_upgrade_for(duration&& d)
|
||||||
{
|
{
|
||||||
return try_lock_upgrade_until(steady_clock::now() + d);
|
return try_lock_upgrade_until(system_clock::now() + d);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class duration>
|
template<class duration>
|
||||||
bool
|
bool
|
||||||
ircd::ctx::shared_mutex::try_lock_shared_for(duration&& d)
|
ircd::ctx::shared_mutex::try_lock_shared_for(duration&& d)
|
||||||
{
|
{
|
||||||
return try_lock_shared_until(steady_clock::now() + d);
|
return try_lock_shared_until(system_clock::now() + d);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class duration>
|
template<class duration>
|
||||||
bool
|
bool
|
||||||
ircd::ctx::shared_mutex::try_lock_for(duration&& d)
|
ircd::ctx::shared_mutex::try_lock_for(duration&& d)
|
||||||
{
|
{
|
||||||
return try_lock_until(steady_clock::now() + d);
|
return try_lock_until(system_clock::now() + d);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class time_point>
|
template<class time_point>
|
||||||
|
|
|
@ -31,12 +31,12 @@ inline namespace this_ctx
|
||||||
template<class E = timeout, class duration> throw_overload<E, duration> wait(const duration &);
|
template<class E = timeout, class duration> throw_overload<E, duration> wait(const duration &);
|
||||||
|
|
||||||
// Returns false if notified; true if time point reached, timeout thrown on throw_overloads
|
// Returns false if notified; true if time point reached, timeout thrown on throw_overloads
|
||||||
bool wait_until(const steady_point &tp, const std::nothrow_t &);
|
bool wait_until(const system_point &tp, const std::nothrow_t &);
|
||||||
template<class E> nothrow_overload<E, bool> wait_until(const steady_point &tp);
|
template<class E> nothrow_overload<E, bool> wait_until(const system_point &tp);
|
||||||
template<class E = timeout> throw_overload<E> wait_until(const steady_point &tp);
|
template<class E = timeout> throw_overload<E> wait_until(const system_point &tp);
|
||||||
|
|
||||||
// Ignores notes. Throws if interrupted.
|
// Ignores notes. Throws if interrupted.
|
||||||
void sleep_until(const steady_point &tp);
|
void sleep_until(const system_point &tp);
|
||||||
template<class duration> void sleep(const duration &);
|
template<class duration> void sleep(const duration &);
|
||||||
void sleep(const int &secs);
|
void sleep(const int &secs);
|
||||||
}}
|
}}
|
||||||
|
@ -68,7 +68,7 @@ template<class duration>
|
||||||
void
|
void
|
||||||
ircd::ctx::this_ctx::sleep(const duration &d)
|
ircd::ctx::this_ctx::sleep(const duration &d)
|
||||||
{
|
{
|
||||||
sleep_until(steady_clock::now() + d);
|
sleep_until(system_clock::now() + d);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wait for a notification until a point in time. If there is a notification
|
/// Wait for a notification until a point in time. If there is a notification
|
||||||
|
@ -77,7 +77,7 @@ ircd::ctx::this_ctx::sleep(const duration &d)
|
||||||
/// interruption point.
|
/// interruption point.
|
||||||
template<class E>
|
template<class E>
|
||||||
ircd::throw_overload<E>
|
ircd::throw_overload<E>
|
||||||
ircd::ctx::this_ctx::wait_until(const steady_point &tp)
|
ircd::ctx::this_ctx::wait_until(const system_point &tp)
|
||||||
{
|
{
|
||||||
if(wait_until<std::nothrow_t>(tp))
|
if(wait_until<std::nothrow_t>(tp))
|
||||||
throw E{};
|
throw E{};
|
||||||
|
@ -88,7 +88,7 @@ ircd::ctx::this_ctx::wait_until(const steady_point &tp)
|
||||||
/// interruption point. this is not noexcept.
|
/// interruption point. this is not noexcept.
|
||||||
template<class E>
|
template<class E>
|
||||||
ircd::nothrow_overload<E, bool>
|
ircd::nothrow_overload<E, bool>
|
||||||
ircd::ctx::this_ctx::wait_until(const steady_point &tp)
|
ircd::ctx::this_ctx::wait_until(const system_point &tp)
|
||||||
{
|
{
|
||||||
return wait_until(tp, std::nothrow);
|
return wait_until(tp, std::nothrow);
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ T &
|
||||||
ircd::ctx::view<T, mutex>::wait_for(lock &l,
|
ircd::ctx::view<T, mutex>::wait_for(lock &l,
|
||||||
const duration &dur)
|
const duration &dur)
|
||||||
{
|
{
|
||||||
return wait_until(l, now<steady_point>() + dur);
|
return wait_until(l, now<system_point>() + dur);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T,
|
template<class T,
|
||||||
|
|
66
ircd/ctx.cc
66
ircd/ctx.cc
|
@ -667,25 +667,11 @@ ircd::ctx::current;
|
||||||
|
|
||||||
/// Yield the currently running context until `time_point` ignoring notes
|
/// Yield the currently running context until `time_point` ignoring notes
|
||||||
void
|
void
|
||||||
ircd::ctx::this_ctx::sleep_until(const steady_clock::time_point &tp)
|
ircd::ctx::this_ctx::sleep_until(const system_point &tp)
|
||||||
{
|
{
|
||||||
while(!wait_until(tp, std::nothrow));
|
while(!wait_until(tp, std::nothrow));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Yield the currently running context until notified or `time_point`.
|
|
||||||
///
|
|
||||||
/// Returns true if this function returned because `time_point` was hit or
|
|
||||||
/// false because this context was notified.
|
|
||||||
bool
|
|
||||||
ircd::ctx::this_ctx::wait_until(const steady_clock::time_point &tp,
|
|
||||||
const std::nothrow_t &)
|
|
||||||
{
|
|
||||||
auto &c(cur());
|
|
||||||
c.alarm.expires_at(tp);
|
|
||||||
c.wait(); // now you're yielding with portals
|
|
||||||
return steady_clock::now() >= tp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Yield the currently running context for `duration` or until notified.
|
/// Yield the currently running context for `duration` or until notified.
|
||||||
///
|
///
|
||||||
/// Returns the duration remaining if notified, or <= 0 if suspended for
|
/// Returns the duration remaining if notified, or <= 0 if suspended for
|
||||||
|
@ -694,15 +680,57 @@ ircd::microseconds
|
||||||
ircd::ctx::this_ctx::wait(const microseconds &duration,
|
ircd::ctx::this_ctx::wait(const microseconds &duration,
|
||||||
const std::nothrow_t &)
|
const std::nothrow_t &)
|
||||||
{
|
{
|
||||||
|
const boost::posix_time::microseconds ptime_duration
|
||||||
|
{
|
||||||
|
duration.count()
|
||||||
|
};
|
||||||
|
|
||||||
auto &c(cur());
|
auto &c(cur());
|
||||||
c.alarm.expires_from_now(duration);
|
c.alarm.expires_from_now(ptime_duration);
|
||||||
c.wait(); // now you're yielding with portals
|
c.wait(); // now you're yielding with portals
|
||||||
const auto ret(c.alarm.expires_from_now());
|
const auto &ret
|
||||||
|
{
|
||||||
|
c.alarm.expires_from_now()
|
||||||
|
};
|
||||||
|
|
||||||
// return remaining duration.
|
// return remaining duration.
|
||||||
// this is > 0 if notified
|
// this is > 0 if notified
|
||||||
// this is unchanged if a note prevented any wait at all
|
// this is unchanged if a note prevented any wait at all
|
||||||
return duration_cast<microseconds>(ret);
|
return microseconds(ret.total_microseconds());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Yield the currently running context until notified or `time_point`.
|
||||||
|
///
|
||||||
|
/// Returns true if this function returned because `time_point` was hit or
|
||||||
|
/// false because this context was notified.
|
||||||
|
bool
|
||||||
|
ircd::ctx::this_ctx::wait_until(const system_point &tp,
|
||||||
|
const std::nothrow_t &)
|
||||||
|
{
|
||||||
|
const auto &diff
|
||||||
|
{
|
||||||
|
tp - now<system_point>()
|
||||||
|
};
|
||||||
|
|
||||||
|
const boost::posix_time::microseconds duration
|
||||||
|
{
|
||||||
|
duration_cast<microseconds>(diff).count()
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto &expires_at
|
||||||
|
{
|
||||||
|
boost::posix_time::microsec_clock::universal_time() + duration
|
||||||
|
};
|
||||||
|
|
||||||
|
auto &c(cur());
|
||||||
|
c.alarm.expires_at(expires_at);
|
||||||
|
c.wait(); // now you're yielding with portals
|
||||||
|
const auto &ret
|
||||||
|
{
|
||||||
|
c.alarm.expires_from_now()
|
||||||
|
};
|
||||||
|
|
||||||
|
return ret <= boost::posix_time::microseconds(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Yield the currently running context until notified.
|
/// Yield the currently running context until notified.
|
||||||
|
@ -710,7 +738,7 @@ void
|
||||||
ircd::ctx::this_ctx::wait()
|
ircd::ctx::this_ctx::wait()
|
||||||
{
|
{
|
||||||
auto &c(cur());
|
auto &c(cur());
|
||||||
c.alarm.expires_at(steady_clock::time_point::max());
|
c.alarm.expires_at(boost::posix_time::pos_infin);
|
||||||
c.wait(); // now you're yielding with portals
|
c.wait(); // now you're yielding with portals
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ struct ircd::ctx::ctx
|
||||||
context::flags flags; // User given flags
|
context::flags flags; // User given flags
|
||||||
int32_t notes {0}; // norm: 0 = asleep; 1 = awake; inc by others; dec by self
|
int32_t notes {0}; // norm: 0 = asleep; 1 = awake; inc by others; dec by self
|
||||||
boost::asio::io_service::strand strand; // mutex/serializer
|
boost::asio::io_service::strand strand; // mutex/serializer
|
||||||
boost::asio::steady_timer alarm; // acting semaphore (64B)
|
boost::asio::deadline_timer alarm; // acting semaphore (64B)
|
||||||
boost::asio::yield_context *yc {nullptr}; // boost interface
|
boost::asio::yield_context *yc {nullptr}; // boost interface
|
||||||
continuation *cont {nullptr}; // valid when asleep; invalid when awake
|
continuation *cont {nullptr}; // valid when asleep; invalid when awake
|
||||||
list::node node; // node for ctx::list
|
list::node node; // node for ctx::list
|
||||||
|
|
|
@ -297,7 +297,7 @@ noexcept
|
||||||
assert_main_thread();
|
assert_main_thread();
|
||||||
mu->AssertHeld();
|
mu->AssertHeld();
|
||||||
const std::chrono::microseconds us(abs_time_us);
|
const std::chrono::microseconds us(abs_time_us);
|
||||||
const std::chrono::steady_clock::time_point tp(us);
|
const std::chrono::system_clock::time_point tp(us);
|
||||||
const ctx::uninterruptible::nothrow ui;
|
const ctx::uninterruptible::nothrow ui;
|
||||||
return cv.wait_until(mu->mu, tp) == std::cv_status::timeout;
|
return cv.wait_until(mu->mu, tp) == std::cv_status::timeout;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ recv_response(const string_view &,
|
||||||
m::v1::user::keys::claim &,
|
m::v1::user::keys::claim &,
|
||||||
failure_map &,
|
failure_map &,
|
||||||
json::stack::object &,
|
json::stack::object &,
|
||||||
const steady_point &);
|
const system_point &);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
recv_responses(query_map &,
|
recv_responses(query_map &,
|
||||||
|
@ -190,9 +190,9 @@ recv_responses(query_map &queries,
|
||||||
json::stack::object &out,
|
json::stack::object &out,
|
||||||
const milliseconds &timeout)
|
const milliseconds &timeout)
|
||||||
{
|
{
|
||||||
const steady_point timedout
|
const system_point timedout
|
||||||
{
|
{
|
||||||
ircd::now<steady_point>() + timeout
|
ircd::now<system_point>() + timeout
|
||||||
};
|
};
|
||||||
|
|
||||||
json::stack::object one_time_keys
|
json::stack::object one_time_keys
|
||||||
|
@ -215,7 +215,7 @@ recv_response(const string_view &remote,
|
||||||
m::v1::user::keys::claim &request,
|
m::v1::user::keys::claim &request,
|
||||||
failure_map &failures,
|
failure_map &failures,
|
||||||
json::stack::object &object,
|
json::stack::object &object,
|
||||||
const steady_point &timeout)
|
const system_point &timeout)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
request.wait_until(timeout);
|
request.wait_until(timeout);
|
||||||
|
|
|
@ -199,9 +199,9 @@ recv_responses(query_map &queries,
|
||||||
const milliseconds &timeout)
|
const milliseconds &timeout)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const steady_point timedout
|
const system_point timedout
|
||||||
{
|
{
|
||||||
ircd::now<steady_point>() + timeout
|
ircd::now<system_point>() + timeout
|
||||||
};
|
};
|
||||||
|
|
||||||
json::stack::object response_keys
|
json::stack::object response_keys
|
||||||
|
|
|
@ -1113,7 +1113,7 @@ try
|
||||||
|
|
||||||
ret = std::min(ret, milliseconds(timeout_max));
|
ret = std::min(ret, milliseconds(timeout_max));
|
||||||
ret = std::max(ret, milliseconds(timeout_min));
|
ret = std::max(ret, milliseconds(timeout_min));
|
||||||
return now<steady_point>() + ret;
|
return now<system_point>() + ret;
|
||||||
}()}
|
}()}
|
||||||
,full_state
|
,full_state
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,7 +51,7 @@ struct ircd::m::sync::args
|
||||||
|
|
||||||
/// The point in time at which this /sync should stop longpolling and return
|
/// The point in time at which this /sync should stop longpolling and return
|
||||||
/// an empty'ish response to the client.
|
/// an empty'ish response to the client.
|
||||||
steady_point timesout;
|
system_point timesout;
|
||||||
|
|
||||||
/// 6.2.1 Controls whether to include the full state for all rooms the user is a member of.
|
/// 6.2.1 Controls whether to include the full state for all rooms the user is a member of.
|
||||||
/// If this is set to true, then all state events will be returned, even if since is non-empty.
|
/// If this is set to true, then all state events will be returned, even if since is non-empty.
|
||||||
|
|
|
@ -12614,7 +12614,7 @@ console_cmd__fed__sync(opt &out, const string_view &line)
|
||||||
|
|
||||||
const auto when
|
const auto when
|
||||||
{
|
{
|
||||||
now<steady_point>() + timeout
|
now<system_point>() + timeout
|
||||||
};
|
};
|
||||||
|
|
||||||
bfrequest.wait_until(when);
|
bfrequest.wait_until(when);
|
||||||
|
|
|
@ -358,7 +358,7 @@ ircd::m::feds::handler(request_list &reqs,
|
||||||
{
|
{
|
||||||
const auto when
|
const auto when
|
||||||
{
|
{
|
||||||
now<steady_point>() + timeout
|
now<system_point>() + timeout
|
||||||
};
|
};
|
||||||
|
|
||||||
while(!reqs.empty())
|
while(!reqs.empty())
|
||||||
|
|
Loading…
Reference in a new issue