Skip to content

Commit 9e866b3

Browse files
committed
Make it so that try_lock_until doesn't fail spuriously
Signed-off-by: Ted Lyngmo <ted@lyncon.se>
1 parent e450dfe commit 9e866b3

1 file changed

Lines changed: 9 additions & 14 deletions

File tree

include/beman/timed_lock_alg/mutex.hpp

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,40 +62,35 @@ using make_pack_of_rotating_index_sequences = typename rot_detail::make_pack_imp
6262
int friendly_try_lock(auto& l1) { return -static_cast<int>(l1.try_lock()); }
6363
int friendly_try_lock(auto&... ls) { return std::try_lock(ls...); }
6464
//-------------------------------------------------------------------------
65-
struct result {
66-
int idx;
67-
bool retry;
68-
};
69-
//-------------------------------------------------------------------------
7065
template <class Clock, class Duration, class Locks, class... Seqs>
7166
int try_lock_until_impl(const std::chrono::time_point<Clock, Duration>& end_time, Locks locks, type_pack<Seqs...>) {
7267
// an array with one function per lockable/sequence to try:
73-
constexpr std::array<result (*)(const std::chrono::time_point<Clock, Duration>&, Locks&), sizeof...(Seqs)> seqs{
68+
constexpr std::array<int (*)(const std::chrono::time_point<Clock, Duration>&, Locks&), sizeof...(Seqs)> seqs{
7469
{+[](const std::chrono::time_point<Clock, Duration>& tp, Locks& lks) {
7570
return []<class Tp, std::size_t I0, std::size_t... Is>(
76-
const Tp& itp, Locks& lcks, std::index_sequence<I0, Is...>) -> result {
71+
const Tp& itp, Locks& lcks, std::index_sequence<I0, Is...>) -> int {
7772
if (std::unique_lock first{std::get<I0>(lcks), itp}) {
7873
int res = friendly_try_lock(std::get<Is>(lcks)...);
7974
if (res == -1) {
8075
first.release();
81-
return {-1, false}; // success
76+
return -1; // success
8277
}
8378
// return the index to try_lock_until next round or the index which failed to lock
8479
// in case time has run out
8580
constexpr std::array idxs{static_cast<int>(Is)...};
86-
return {idxs[static_cast<std::size_t>(res)], Clock::now() < itp};
81+
return idxs[static_cast<std::size_t>(res)];
8782
}
88-
// timeout
89-
return {static_cast<int>(I0), false};
83+
// probable timeout
84+
return static_cast<int>(I0);
9085
}(tp, lks, Seqs{});
9186
}...}};
9287

9388
// try rotations in seqs while there is time to retry
94-
result ret{};
95-
while ((ret = seqs[static_cast<std::size_t>(ret.idx)](end_time, locks)).retry) {
89+
int idx = 0;
90+
while ((idx = seqs[static_cast<std::size_t>(idx)](end_time, locks)) != -1 && Clock::now() < end_time) {
9691
std::this_thread::yield();
9792
}
98-
return ret.idx;
93+
return idx;
9994
}
10095
} // namespace detail
10196

0 commit comments

Comments
 (0)