handle empty task list
This commit is contained in:
parent
df9f28a1a1
commit
f981896697
|
@ -27,7 +27,6 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include "drogon/DrTemplateBase.h"
|
|
||||||
|
|
||||||
namespace drogon
|
namespace drogon
|
||||||
{
|
{
|
||||||
|
@ -953,6 +952,9 @@ inline Task<> when_all(std::vector<Awaiter> tasks,
|
||||||
}
|
}
|
||||||
}(eptr, counter, waiter, std::move(task));
|
}(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;
|
co_await waiter;
|
||||||
if (loop)
|
if (loop)
|
||||||
co_await switchThreadCoro(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]));
|
}(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;
|
co_await waiter;
|
||||||
if (loop)
|
if (loop)
|
||||||
co_await switchThreadCoro(loop);
|
co_await switchThreadCoro(loop);
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
#include <drogon/utils/coroutine.h>
|
#include <drogon/utils/coroutine.h>
|
||||||
#include <drogon/HttpAppFramework.h>
|
#include <drogon/HttpAppFramework.h>
|
||||||
#include <trantor/net/EventLoopThread.h>
|
#include <trantor/net/EventLoopThread.h>
|
||||||
#include <atomic>
|
|
||||||
#include <coroutine>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
@ -50,6 +48,10 @@ DROGON_TEST(CroutineBasics)
|
||||||
STATIC_REQUIRE(is_int<await_result_t<Task<int>>>::value);
|
STATIC_REQUIRE(is_int<await_result_t<Task<int>>>::value);
|
||||||
STATIC_REQUIRE(is_void<await_result_t<Task<>>>::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
|
// No, you cannot await AsyncTask. By design
|
||||||
STATIC_REQUIRE(is_awaitable_v<AsyncTask> == false);
|
STATIC_REQUIRE(is_awaitable_v<AsyncTask> == false);
|
||||||
|
|
||||||
|
@ -133,6 +135,7 @@ DROGON_TEST(AwaiterTraits)
|
||||||
auto awaiter = sleepCoro(drogon::app().getLoop(), 0.001);
|
auto awaiter = sleepCoro(drogon::app().getLoop(), 0.001);
|
||||||
STATIC_REQUIRE(is_awaitable_v<decltype(awaiter)>);
|
STATIC_REQUIRE(is_awaitable_v<decltype(awaiter)>);
|
||||||
STATIC_REQUIRE(std::is_void<await_result_t<decltype(awaiter)>>::value);
|
STATIC_REQUIRE(std::is_void<await_result_t<decltype(awaiter)>>::value);
|
||||||
|
sync_wait(awaiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
DROGON_TEST(CompilcatedCoroutineLifetime)
|
DROGON_TEST(CompilcatedCoroutineLifetime)
|
||||||
|
@ -289,4 +292,8 @@ DROGON_TEST(WhenAll)
|
||||||
tasks5.emplace_back(std::move(sleep));
|
tasks5.emplace_back(std::move(sleep));
|
||||||
tasks5.emplace_back(std::move(sleep2));
|
tasks5.emplace_back(std::move(sleep2));
|
||||||
sync_wait(when_all(std::move(tasks5)));
|
sync_wait(when_all(std::move(tasks5)));
|
||||||
|
|
||||||
|
// Check waiting on empty list works
|
||||||
|
std::vector<Task<>> tasks6;
|
||||||
|
sync_wait(when_all(std::move(tasks6)));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue