Files
Aerofoil/AerofoilPortable/GpFiberStarter_Thread.cpp

69 lines
1.7 KiB
C++
Raw Normal View History

2020-09-26 16:45:52 -04:00
#include "GpFiberStarter.h"
2021-03-18 17:08:11 -04:00
#include "GpFiber_Thread.h"
2020-09-26 16:45:52 -04:00
#include "IGpSystemServices.h"
#include "IGpThreadEvent.h"
2020-09-26 16:45:52 -04:00
#include <assert.h>
2021-03-18 17:08:11 -04:00
namespace GpFiberStarter_Thread
2020-09-26 16:45:52 -04:00
{
struct FiberStartState
{
GpFiberStarter::ThreadFunc_t m_threadFunc;
IGpThreadEvent *m_creatingReturnEvent;
IGpThreadEvent *m_creatingWakeEvent;
2020-09-26 16:45:52 -04:00
void *m_context;
};
2021-03-18 17:08:11 -04:00
static int FiberStartRoutine(void *lpThreadParameter)
2020-09-26 16:45:52 -04:00
{
const FiberStartState *tss = static_cast<const FiberStartState*>(lpThreadParameter);
GpFiberStarter::ThreadFunc_t threadFunc = tss->m_threadFunc;
IGpThreadEvent *creatingReturnEvent = tss->m_creatingReturnEvent;
IGpThreadEvent *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(IGpSystemServices *systemServices, ThreadFunc_t threadFunc, void *context, IGpFiber *creatingFiber)
2020-09-26 16:45:52 -04:00
{
IGpThreadEvent *returnEvent = systemServices->CreateThreadEvent(true, false);
if (!returnEvent)
return nullptr;
IGpThreadEvent *wakeEvent = systemServices->CreateThreadEvent(true, false);
if (!wakeEvent)
{
returnEvent->Destroy();
return nullptr;
}
2020-09-26 16:45:52 -04:00
2021-03-18 17:08:11 -04:00
GpFiberStarter_Thread::FiberStartState startState;
2020-09-26 16:45:52 -04:00
startState.m_context = context;
startState.m_creatingReturnEvent = returnEvent;
startState.m_creatingWakeEvent = wakeEvent;
2020-09-26 16:45:52 -04:00
startState.m_threadFunc = threadFunc;
2021-03-18 17:08:11 -04:00
void *thread = systemServices->CreateThread(GpFiberStarter_Thread::FiberStartRoutine, &startState);
2020-09-26 16:45:52 -04:00
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
2021-03-18 17:08:11 -04:00
return new GpFiber_Thread(thread, wakeEvent);
2020-09-26 16:45:52 -04:00
}