mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 07:11:52 +01:00
Fix a race with multiple threads pushing data into circular queue
If the 'end' changes when waiting for data to be consumed our 'waitNext' would be invalid leading to a deadlock.
This commit is contained in:
parent
f55b135243
commit
6ea1483c9a
@ -96,12 +96,15 @@ namespace skyline {
|
|||||||
|
|
||||||
void Push(const Type &item) {
|
void Push(const Type &item) {
|
||||||
Type *waitNext{};
|
Type *waitNext{};
|
||||||
|
Type *waitEnd{};
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (waitNext) {
|
if (waitNext) {
|
||||||
std::unique_lock consumeLock{consumptionMutex};
|
std::unique_lock consumeLock{consumptionMutex};
|
||||||
consumeCondition.wait(consumeLock, [=]() { return waitNext != start; });
|
|
||||||
|
consumeCondition.wait(consumeLock, [=]() { return waitNext != start || waitEnd != end; });
|
||||||
waitNext = nullptr;
|
waitNext = nullptr;
|
||||||
|
waitEnd = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::scoped_lock lock{productionMutex};
|
std::scoped_lock lock{productionMutex};
|
||||||
@ -109,6 +112,7 @@ namespace skyline {
|
|||||||
next = (next == reinterpret_cast<Type *>(vector.end().base())) ? reinterpret_cast<Type *>(vector.begin().base()) : next;
|
next = (next == reinterpret_cast<Type *>(vector.end().base())) ? reinterpret_cast<Type *>(vector.begin().base()) : next;
|
||||||
if (next == start) {
|
if (next == start) {
|
||||||
waitNext = next;
|
waitNext = next;
|
||||||
|
waitEnd = end;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
*next = item;
|
*next = item;
|
||||||
|
Loading…
Reference in New Issue
Block a user