mirror of
https://github.com/matrix-construct/construct
synced 2024-12-27 07:54:05 +01:00
ircd::ctx: Fixes and assertions for shared_mutex upgrade lockable semantics.
This commit is contained in:
parent
926795f01a
commit
a776565ce0
1 changed files with 35 additions and 13 deletions
|
@ -120,28 +120,42 @@ noexcept
|
||||||
inline void
|
inline void
|
||||||
ircd::ctx::shared_mutex::unlock_upgrade_and_lock_shared()
|
ircd::ctx::shared_mutex::unlock_upgrade_and_lock_shared()
|
||||||
{
|
{
|
||||||
++s;
|
assert(u == current);
|
||||||
|
assert(s >= 0);
|
||||||
|
|
||||||
u = nullptr;
|
u = nullptr;
|
||||||
|
++s;
|
||||||
q.notify_one();
|
q.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
ircd::ctx::shared_mutex::unlock_upgrade_and_lock()
|
ircd::ctx::shared_mutex::unlock_upgrade_and_lock()
|
||||||
{
|
{
|
||||||
|
assert(u == current);
|
||||||
|
|
||||||
|
q.wait([this]
|
||||||
|
{
|
||||||
|
return can_lock();
|
||||||
|
});
|
||||||
|
|
||||||
s = std::numeric_limits<decltype(s)>::min();
|
s = std::numeric_limits<decltype(s)>::min();
|
||||||
u = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
ircd::ctx::shared_mutex::unlock_and_lock_upgrade()
|
ircd::ctx::shared_mutex::unlock_and_lock_upgrade()
|
||||||
{
|
{
|
||||||
|
assert(u == current);
|
||||||
|
assert(s == std::numeric_limits<decltype(s)>::min());
|
||||||
|
|
||||||
s = 0;
|
s = 0;
|
||||||
u = current;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
ircd::ctx::shared_mutex::unlock_and_lock_shared()
|
ircd::ctx::shared_mutex::unlock_and_lock_shared()
|
||||||
{
|
{
|
||||||
|
assert(u == current);
|
||||||
|
assert(s == std::numeric_limits<decltype(s)>::min());
|
||||||
|
|
||||||
s = 1;
|
s = 1;
|
||||||
q.notify_one();
|
q.notify_one();
|
||||||
}
|
}
|
||||||
|
@ -149,6 +163,8 @@ ircd::ctx::shared_mutex::unlock_and_lock_shared()
|
||||||
inline void
|
inline void
|
||||||
ircd::ctx::shared_mutex::unlock_upgrade()
|
ircd::ctx::shared_mutex::unlock_upgrade()
|
||||||
{
|
{
|
||||||
|
assert(u == current);
|
||||||
|
|
||||||
u = nullptr;
|
u = nullptr;
|
||||||
q.notify_one();
|
q.notify_one();
|
||||||
}
|
}
|
||||||
|
@ -156,6 +172,8 @@ ircd::ctx::shared_mutex::unlock_upgrade()
|
||||||
inline void
|
inline void
|
||||||
ircd::ctx::shared_mutex::unlock_shared()
|
ircd::ctx::shared_mutex::unlock_shared()
|
||||||
{
|
{
|
||||||
|
assert(s > 0);
|
||||||
|
|
||||||
--s;
|
--s;
|
||||||
q.notify_one();
|
q.notify_one();
|
||||||
}
|
}
|
||||||
|
@ -163,6 +181,9 @@ ircd::ctx::shared_mutex::unlock_shared()
|
||||||
inline void
|
inline void
|
||||||
ircd::ctx::shared_mutex::unlock()
|
ircd::ctx::shared_mutex::unlock()
|
||||||
{
|
{
|
||||||
|
assert(u == current);
|
||||||
|
assert(s == std::numeric_limits<decltype(s)>::min());
|
||||||
|
|
||||||
s = 0;
|
s = 0;
|
||||||
q.notify_all();
|
q.notify_all();
|
||||||
}
|
}
|
||||||
|
@ -218,7 +239,6 @@ ircd::ctx::shared_mutex::try_unlock_upgrade_and_lock()
|
||||||
if(!try_lock())
|
if(!try_lock())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
u = nullptr;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +258,9 @@ ircd::ctx::shared_mutex::try_unlock_shared_and_lock()
|
||||||
if(s != 1)
|
if(s != 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
s = 1;
|
assert(!u);
|
||||||
|
u = current;
|
||||||
|
s = std::numeric_limits<decltype(s)>::min();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,6 +294,7 @@ ircd::ctx::shared_mutex::lock()
|
||||||
return can_lock();
|
return can_lock();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
u = current;
|
||||||
s = std::numeric_limits<decltype(s)>::min();
|
s = std::numeric_limits<decltype(s)>::min();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +368,10 @@ ircd::ctx::shared_mutex::try_lock_until(time_point&& tp)
|
||||||
};
|
};
|
||||||
|
|
||||||
if(can_lock)
|
if(can_lock)
|
||||||
|
{
|
||||||
|
u = current;
|
||||||
s = std::numeric_limits<decltype(s)>::min();
|
s = std::numeric_limits<decltype(s)>::min();
|
||||||
|
}
|
||||||
|
|
||||||
return can_lock;
|
return can_lock;
|
||||||
}
|
}
|
||||||
|
@ -373,6 +399,7 @@ ircd::ctx::shared_mutex::try_lock()
|
||||||
{
|
{
|
||||||
if(can_lock())
|
if(can_lock())
|
||||||
{
|
{
|
||||||
|
u = current;
|
||||||
s = std::numeric_limits<decltype(s)>::min();
|
s = std::numeric_limits<decltype(s)>::min();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -383,13 +410,8 @@ inline bool
|
||||||
ircd::ctx::shared_mutex::can_lock_upgrade()
|
ircd::ctx::shared_mutex::can_lock_upgrade()
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
if(s < 0)
|
assert(u || can_lock_shared());
|
||||||
return false;
|
return !u;
|
||||||
|
|
||||||
if(u)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
|
@ -403,7 +425,7 @@ inline bool
|
||||||
ircd::ctx::shared_mutex::can_lock()
|
ircd::ctx::shared_mutex::can_lock()
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
return s == 0;
|
return s == 0 && (!u || u == current);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
|
|
Loading…
Reference in a new issue