Files
Aerofoil/AerofoilSDL/GpFiberStarter_SDL.cpp

71 lines
1.8 KiB
C++
Raw Normal View History

2020-09-26 16:45:52 -04:00
#include "GpFiberStarter.h"
#include "GpFiber_SDL.h"
#include "HostSystemServices.h"
2020-09-26 16:45:52 -04:00
#include "HostThreadEvent.h"
#include "SDL_thread.h"
#include <assert.h>
namespace GpFiberStarter_SDL
{
struct FiberStartState
{
GpFiberStarter::ThreadFunc_t m_threadFunc;
PortabilityLayer::HostThreadEvent *m_creatingReturnEvent;
PortabilityLayer::HostThreadEvent *m_creatingWakeEvent;
2020-09-26 16:45:52 -04:00
void *m_context;
};
static int SDLCALL FiberStartRoutine(void *lpThreadParameter)
{
const FiberStartState *tss = static_cast<const FiberStartState*>(lpThreadParameter);
GpFiberStarter::ThreadFunc_t threadFunc = tss->m_threadFunc;
PortabilityLayer::HostThreadEvent *creatingReturnEvent = tss->m_creatingReturnEvent;
PortabilityLayer::HostThreadEvent *wakeEvent = tss->m_creatingWakeEvent;
2020-09-26 16:45:52 -04:00
void *context = tss->m_context;
creatingReturnEvent->Signal();
wakeEvent->Wait();
2020-09-26 16:45:52 -04:00
threadFunc(context);
return 0;
}
}
IGpFiber *GpFiberStarter::StartFiber(PortabilityLayer::HostSystemServices *systemServices, ThreadFunc_t threadFunc, void *context, IGpFiber *creatingFiber)
2020-09-26 16:45:52 -04:00
{
PortabilityLayer::HostThreadEvent *returnEvent = systemServices->CreateThreadEvent(true, false);
if (!returnEvent)
return nullptr;
PortabilityLayer::HostThreadEvent *wakeEvent = systemServices->CreateThreadEvent(true, false);
if (!wakeEvent)
{
returnEvent->Destroy();
return nullptr;
}
2020-09-26 16:45:52 -04:00
GpFiberStarter_SDL::FiberStartState startState;
startState.m_context = context;
startState.m_creatingReturnEvent = returnEvent;
startState.m_creatingWakeEvent = wakeEvent;
2020-09-26 16:45:52 -04:00
startState.m_threadFunc = threadFunc;
SDL_Thread *thread = SDL_CreateThread(GpFiberStarter_SDL::FiberStartRoutine, "Fiber", &startState);
if (!thread)
{
returnEvent->Destroy();
wakeEvent->Destroy();
2020-09-26 16:45:52 -04:00
return nullptr;
}
2020-09-26 16:45:52 -04:00
returnEvent->Wait();
returnEvent->Destroy();
2020-09-26 16:45:52 -04:00
return new GpFiber_SDL(thread, wakeEvent);
2020-09-26 16:45:52 -04:00
}