#pragma once
#include "base.hpp"
#if !SOUP_WASM
#if SOUP_WINDOWS
#include <windows.h>
#else
#include <pthread.h>
#endif
#include <vector>
#include "Capture.hpp"
#include "TransientToken.hpp"
#include "UniquePtr.hpp"
NAMESPACE_SOUP
{
class Thread
{
public:
struct RunningData
{
void(*f)(Capture&&);
Capture f_cap;
TransientToken transient_token;
};
#if SOUP_WINDOWS
HANDLE handle = INVALID_HANDLE_VALUE;
#else
pthread_t handle{};
bool have_handle = false;
#endif
TransientTokenRef running_ref{};
explicit Thread() SOUP_EXCAL = default;
explicit Thread(void(*f)(Capture&&), Capture&& cap = {});
explicit Thread(const Thread& b) = delete;
explicit Thread(Thread&& b) noexcept;
void start(void(*f)(Capture&&), Capture&& cap = {});
~Thread() noexcept { awaitCompletion(); }
#if SOUP_WINDOWS || SOUP_LINUX
void setTimeCritical() noexcept;
#endif
[[nodiscard]] bool isAttached() const noexcept;
[[nodiscard]] bool isRunning() const noexcept { return running_ref.isValid(); }
void awaitCompletion() noexcept;
static void awaitCompletion(const std::vector<UniquePtr<Thread>>& threads) noexcept;
void detach() noexcept;
protected:
void forget() noexcept;
};
}
#endif