handle empty task list

This commit is contained in:
Martin Chang 2024-02-03 15:34:39 +08:00
parent df9f28a1a1
commit f981896697
2 changed files with 15 additions and 3 deletions

View File

@ -27,7 +27,6 @@
#include <mutex>
#include <type_traits>
#include <optional>
#include "drogon/DrTemplateBase.h"
namespace drogon
{
@ -953,6 +952,9 @@ inline Task<> when_all(std::vector<Awaiter> tasks,
}
}(eptr, counter, waiter, std::move(task));
}
// In case there's no task, we should still wait for the notify
if (tasks.empty())
waiter.notify();
co_await waiter;
if (loop)
co_await switchThreadCoro(loop);
@ -1007,6 +1009,9 @@ inline Task<std::vector<await_result_t<Awaiter>>> when_all(
}
}(eptr, counter, waiter, results, i, std::move(tasks[i]));
}
// In case there's no task, we should still wait for the notify
if (tasks.empty())
waiter.notify();
co_await waiter;
if (loop)
co_await switchThreadCoro(loop);

View File

@ -2,8 +2,6 @@
#include <drogon/utils/coroutine.h>
#include <drogon/HttpAppFramework.h>
#include <trantor/net/EventLoopThread.h>
#include <atomic>
#include <coroutine>
#include <functional>
#include <type_traits>
@ -50,6 +48,10 @@ DROGON_TEST(CroutineBasics)
STATIC_REQUIRE(is_int<await_result_t<Task<int>>>::value);
STATIC_REQUIRE(is_void<await_result_t<Task<>>>::value);
// Regular functions should not be awaitable
STATIC_REQUIRE(is_awaitable_v<std::function<void()>> == false);
STATIC_REQUIRE(is_awaitable_v<std::function<int()>> == false);
// No, you cannot await AsyncTask. By design
STATIC_REQUIRE(is_awaitable_v<AsyncTask> == false);
@ -133,6 +135,7 @@ DROGON_TEST(AwaiterTraits)
auto awaiter = sleepCoro(drogon::app().getLoop(), 0.001);
STATIC_REQUIRE(is_awaitable_v<decltype(awaiter)>);
STATIC_REQUIRE(std::is_void<await_result_t<decltype(awaiter)>>::value);
sync_wait(awaiter);
}
DROGON_TEST(CompilcatedCoroutineLifetime)
@ -289,4 +292,8 @@ DROGON_TEST(WhenAll)
tasks5.emplace_back(std::move(sleep));
tasks5.emplace_back(std::move(sleep2));
sync_wait(when_all(std::move(tasks5)));
// Check waiting on empty list works
std::vector<Task<>> tasks6;
sync_wait(when_all(std::move(tasks6)));
}