rexglue-skate3/src/core/fiber_win32.cpp
2026-05-18 22:41:13 +01:00

64 lines
1.5 KiB
C++

/**
* @file rex/core/fiber_win32.cpp
* @brief Win32 backend for rex::thread::Fiber
*
* @copyright Copyright (c) 2026 Tom Clay <tomc@tctechstuff.com>
* All rights reserved.
*
* @license BSD 3-Clause License
* See LICENSE file in the project root for full license text.
*/
#include <rex/platform.h>
#if REX_PLATFORM_WIN32
#include <Windows.h>
#include <rex/thread/fiber.h>
#include <cassert>
namespace rex::thread {
thread_local Fiber* Fiber::tls_current_ = nullptr;
Fiber* Fiber::ConvertCurrentThread() {
auto* f = new Fiber();
f->handle_ = ::ConvertThreadToFiber(nullptr);
if (!f->handle_) {
delete f;
return nullptr;
}
f->is_thread_fiber_ = true;
tls_current_ = f;
return f;
}
Fiber* Fiber::Create(size_t stack_size, void (*entry)(void*), void* arg) {
auto* f = new Fiber();
f->handle_ = ::CreateFiber(stack_size, reinterpret_cast<LPFIBER_START_ROUTINE>(entry), arg);
if (!f->handle_) {
delete f;
return nullptr;
}
return f;
}
void Fiber::SwitchTo(Fiber* target) {
tls_current_ = target;
::SwitchToFiber(target->handle_);
}
void Fiber::Destroy() {
// Thread fibers are destroyed from the owning thread itself.
if (is_thread_fiber_) {
::ConvertFiberToThread();
tls_current_ = nullptr;
} else {
assert(this != tls_current_ && "Destroy called on the currently running fiber");
::DeleteFiber(handle_);
}
delete this;
}
} // namespace rex::thread
#endif // REX_PLATFORM_WIN32