| 6 | #include "../../src/core/taskqueue.hpp" |
| 7 | |
| 8 | TEST(TaskQueue, Cancel) { |
| 9 | pop::TaskQueue<int> queue; |
| 10 | std::mutex mutex; |
| 11 | std::unique_lock lock(mutex); |
| 12 | std::condition_variable cvStarted; |
| 13 | std::condition_variable cvDone; |
| 14 | const size_t first = queue.enqueue([&mutex, &cvStarted, &cvDone] { |
| 15 | std::unique_lock firstLock(mutex); |
| 16 | cvStarted.notify_all(); |
| 17 | EXPECT_EQ(cvDone.wait_for(firstLock, std::chrono::seconds(1)), std::cv_status::no_timeout); |
| 18 | return 1; |
| 19 | }); |
| 20 | EXPECT_FALSE(queue.cancel(first)); // about to start |
| 21 | // ^ This is an implementation detail, but covers an additional branch. |
| 22 | // Note: after the second enqueue, cancel(first) may succeed |
| 23 | const size_t second = queue.enqueue([] { |
| 24 | return 2; |
| 25 | }); |
| 26 | ASSERT_EQ(cvStarted.wait_for(lock, std::chrono::seconds(1)), std::cv_status::no_timeout); |
| 27 | EXPECT_FALSE(queue.cancel(first)); // already running |
| 28 | EXPECT_TRUE(queue.cancel(second)); // ok, not running |
| 29 | EXPECT_FALSE(queue.cancel(second)); // already canceled |
| 30 | cvDone.notify_all(); |
| 31 | lock.unlock(); |
| 32 | queue.get(first); |
| 33 | EXPECT_FALSE(queue.cancel(first)); // already finished |
| 34 | } |
| 35 | |
| 36 | TEST(TaskQueue, TryGet) { |
| 37 | pop::TaskQueue<int> queue; |