diff --git a/src/fibers/fiber.cpp b/src/fibers/fiber.cpp index 4cc9259..b8d4409 100644 --- a/src/fibers/fiber.cpp +++ b/src/fibers/fiber.cpp @@ -1265,8 +1265,21 @@ void FiberScheduler::sleep(uint64_t nanoseconds, SleepFuture * future) noexcept void FiberScheduler::cancelSleep(SleepFuture * future) noexcept { - uint32_t prev = future->state.fetch_or(SleepFuture::CANCELLED, std::memory_order_acq_rel); - if (prev & SleepFuture::IN_TABLE) + uint32_t expected = future->state.load(std::memory_order_relaxed); + for (;;) + { + if (expected & SleepFuture::CANCELLED) + { + return; + } + if (future->state.compare_exchange_weak( + expected, expected | SleepFuture::CANCELLED, std::memory_order_acq_rel, std::memory_order_relaxed)) + { + break; + } + } + + if (expected & SleepFuture::IN_TABLE) { ProcessorState * processor = &scheduler->processorState[future->processorNumber]; processor->cancelQueue.push(future); diff --git a/src/fibers/sequencer.cpp b/src/fibers/sequencer.cpp index f34df2a..677f435 100644 --- a/src/fibers/sequencer.cpp +++ b/src/fibers/sequencer.cpp @@ -59,8 +59,21 @@ bool FiberSequencer::advance(uint64_t value) noexcept void FiberSequencer::cancelWait(Future * future) noexcept { - uint32_t prev = future->state.fetch_or(Future::CANCELLED, std::memory_order_acq_rel); - if (prev & Future::IN_TABLE) + uint32_t expected = future->state.load(std::memory_order_relaxed); + for (;;) + { + if (expected & Future::CANCELLED) + { + return; + } + if (future->state.compare_exchange_weak( + expected, expected | Future::CANCELLED, std::memory_order_acq_rel, std::memory_order_relaxed)) + { + break; + } + } + + if (expected & Future::IN_TABLE) { cancelQueue.push(future); }