Lots of windows fixes and some more improvements.

This commit is contained in:
2025-06-24 15:20:42 +02:00
parent 36a908ab8a
commit 573c431dbd
14 changed files with 379 additions and 63 deletions

View File

@@ -24,6 +24,7 @@
#include "../memory/memutil.hpp"
#include "../util/flag.hpp"
#include "../util/iterators.hpp"
#include "../util/misc.hpp"
#include "../util/traits.hpp"
#if MIJIN_COROUTINE_ENABLE_DEBUG_INFO
#include "../debug/stacktrace.hpp"
@@ -269,7 +270,14 @@ struct TaskAllocatorTraits
{
return TAllocator<T>(taskLoop->getAllocator());
}
return TAllocator<T>();
if constexpr (std::is_default_constructible_v<TAllocator<T>>)
{
return TAllocator<T>();
}
else
{
MIJIN_FATAL("Could not create task allocator.");
}
}
};
@@ -501,6 +509,17 @@ private:
template<typename TTask, template<typename> typename TAllocator2>
friend class WrappedTask;
};
template<typename T>
struct is_task : std::false_type {};
template<typename TResult, template<typename...> typename TAllocator>
struct is_task<TaskBase<TResult, TAllocator>> : std::true_type {};
template<typename T>
inline constexpr bool is_task_v = is_task<T>::value;
template<typename T>
concept task_type = is_task_v<T>;
template<template<typename> typename TAllocator = MIJIN_DEFAULT_ALLOCATOR>
class WrappedTaskBase
@@ -573,16 +592,24 @@ public:
MIJIN_DEFINE_FLAG(IgnoreWaiting);
using wrapped_task_t = WrappedTaskBase<TAllocator>;
using wrapped_task_base_ptr_t = std::unique_ptr<wrapped_task_t, AllocatorDeleter<TAllocator<wrapped_task_t>>>;
using wrapped_allocator_t = TAllocator<wrapped_task_t>;
using wrapped_deleter_t = AllocatorDeleter<wrapped_allocator_t >;
using wrapped_task_base_ptr_t = std::unique_ptr<wrapped_task_t, wrapped_deleter_t>;
struct StoredTask
{
using set_future_t = std::function<void(StoredTask&)>;
wrapped_task_base_ptr_t task;
std::function<void(StoredTask&)> setFuture;
set_future_t setFuture;
std::any resultData;
StoredTask(wrapped_task_base_ptr_t&& task_, set_future_t&& setFuture_, std::any&& resultData_)
: task(std::move(task_)), setFuture(std::move(setFuture_)), resultData(std::move(resultData_)) {}
template<typename T>
StoredTask(TAllocator<T> allocator_) : task(nullptr, wrapped_deleter_t(wrapped_allocator_t(allocator_))) {}
};
using exception_handler_t = std::function<void(std::exception_ptr)>;
using allocator_t = TAllocator<int>;
using allocator_t = TAllocator<void>;
protected:
using task_vector_t = std::vector<StoredTask, TAllocator<StoredTask>>;
@@ -661,7 +688,8 @@ private:
std::thread::id threadId_;
public:
explicit BaseSimpleTaskLoop(const allocator_t& allocator = {}) MIJIN_NOEXCEPT_IF(std::is_nothrow_copy_constructible_v<allocator_t>)
: base_t(std::move(allocator)), tasks_(TAllocator<StoredTask>(allocator_)), newTasks_(TAllocator<StoredTask>(allocator_)) {}
: base_t(std::move(allocator)), tasks_(TAllocator<StoredTask>(allocator_)), newTasks_(TAllocator<StoredTask>(allocator_)),
queuedTasks_(constructArray<StoredTask, MessageQueue<StoredTask>::BUFFER_SIZE>(allocator_)) {}
public: // TaskLoop implementation
void transferCurrentTask(TaskLoop<TAllocator>& otherLoop) MIJIN_NOEXCEPT override;
void addStoredTask(StoredTask&& storedTask) MIJIN_NOEXCEPT override;
@@ -778,7 +806,7 @@ FuturePtr<TResult> TaskLoop<TAllocator>::addTaskImpl(TaskBase<TResult, TAllocato
MIJIN_ASSERT(!task.getLoop(), "Attempting to add task that already has a loop!");
task.setLoop(this);
auto future = std::allocate_shared<Future<TResult>>(TAllocator<Future<TResult>>(allocator_));
FuturePtr<TResult> future = std::allocate_shared<Future<TResult>>(TAllocator<Future<TResult>>(allocator_), allocator_);
auto setFuture = &setFutureHelper<TResult>;
if (outHandle != nullptr)
@@ -787,11 +815,8 @@ FuturePtr<TResult> TaskLoop<TAllocator>::addTaskImpl(TaskBase<TResult, TAllocato
}
// add tasks to a seperate vector first as we might be running another task right now
addStoredTask(StoredTask{
.task = wrapTask(TAllocator<WrappedTask<TaskBase<TResult, TAllocator>>>(allocator_), std::move(task)),
.setFuture = setFuture,
.resultData = future
});
TAllocator<WrappedTask<TaskBase<TResult, TAllocator>>> allocator(allocator_);
addStoredTask(StoredTask(wrapTask(std::move(allocator), std::move(task)), std::move(setFuture), std::move(future)));
return future;
}