104 lines
3.1 KiB
C++
104 lines
3.1 KiB
C++
#pragma once
|
|||
|
|
|
||
|
|
#if !IL2CPP_THREADS_STD && IL2CPP_THREADS_WIN32 && !RUNTIME_TINY
|
||
|
|
|
||
|
|
#include "os/ErrorCodes.h"
|
||
|
|
#include "os/Thread.h"
|
||
|
|
#include "os/WaitStatus.h"
|
||
|
|
#include "utils/NonCopyable.h"
|
||
|
|
|
||
|
|
#include "WindowsHeaders.h"
|
||
|
|
#include "os/Generic/WaitObject.h"
|
||
|
|
#include "Baselib.h"
|
||
|
|
#include "Cpp/CappedSemaphore.h"
|
||
|
|
#include "Cpp/Atomic.h"
|
||
|
|
|
||
|
|
#define IL2CPP_DEFAULT_STACK_SIZE ( 1 * 1024 * 1024) // default .NET stacksize is 1mb
|
||
|
|
|
||
|
|
namespace il2cpp
|
||
|
|
{
|
||
|
|
namespace os
|
||
|
|
{
|
||
|
|
class ThreadImpl : public il2cpp::utils::NonCopyable
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
ThreadImpl();
|
||
|
|
~ThreadImpl();
|
||
|
|
|
||
|
|
size_t Id();
|
||
|
|
ErrorCode Run(Thread::StartFunc func, void* arg, int64_t affinityMask);
|
||
|
|
void SetName(const char* name);
|
||
|
|
void SetPriority(ThreadPriority priority);
|
||
|
|
ThreadPriority GetPriority();
|
||
|
|
|
||
|
|
void SetStackSize(size_t newsize)
|
||
|
|
{
|
||
|
|
// only makes sense if it's called BEFORE the thread has been created
|
||
|
|
IL2CPP_ASSERT(m_ThreadHandle == NULL);
|
||
|
|
// if newsize is zero we use the per-platform default value for size of stack
|
||
|
|
if (newsize == 0)
|
||
|
|
{
|
||
|
|
newsize = IL2CPP_DEFAULT_STACK_SIZE;
|
||
|
|
}
|
||
|
|
m_StackSize = newsize;
|
||
|
|
}
|
||
|
|
|
||
|
|
void CheckForUserAPCAndHandle();
|
||
|
|
void SetWaitObject(WaitObject* waitObject);
|
||
|
|
void ReleaseSemaphore() {m_ConditionSemaphore.Release(1);}
|
||
|
|
void AcquireSemaphore() {m_ConditionSemaphore.Acquire();}
|
||
|
|
bool TryTimedAcquireSemaphore(uint32_t timeout) { return m_ConditionSemaphore.TryTimedAcquire(baselib::timeout_ms(timeout));}
|
||
|
|
|
||
|
|
static int GetMaxStackSize();
|
||
|
|
|
||
|
|
void QueueUserAPC(Thread::APCFunc func, void* context);
|
||
|
|
|
||
|
|
ApartmentState GetApartment();
|
||
|
|
ApartmentState GetExplicitApartment();
|
||
|
|
ApartmentState SetApartment(ApartmentState state);
|
||
|
|
void SetExplicitApartment(ApartmentState state);
|
||
|
|
|
||
|
|
static void Sleep(uint32_t ms, bool interruptible);
|
||
|
|
static size_t CurrentThreadId();
|
||
|
|
static ThreadImpl* CreateForCurrentThread();
|
||
|
|
static ThreadImpl* GetCurrentThread();
|
||
|
|
|
||
|
|
static bool YieldInternal();
|
||
|
|
|
||
|
|
#if IL2CPP_HAS_NATIVE_THREAD_CLEANUP
|
||
|
|
static void SetNativeThreadCleanup(Thread::ThreadCleanupFunc cleanupFunction);
|
||
|
|
static void RegisterCurrentThreadForCleanup(void* arg);
|
||
|
|
static void UnregisterCurrentThreadForCleanup();
|
||
|
|
static void OnCurrentThreadExiting();
|
||
|
|
#endif
|
||
|
|
|
||
|
|
baselib::atomic<WaitObject*> m_CurrentWaitObject;
|
||
|
|
struct APCRequest
|
||
|
|
{
|
||
|
|
Thread::APCFunc callback;
|
||
|
|
void* context;
|
||
|
|
|
||
|
|
APCRequest(Thread::APCFunc callback, void* context) :
|
||
|
|
callback(callback), context(context)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
baselib::Lock m_PendingAPCsMutex;
|
||
|
|
std::vector<APCRequest> m_PendingAPCs;
|
||
|
|
baselib::CappedSemaphore m_ConditionSemaphore;
|
||
|
|
|
||
|
|
private:
|
||
|
|
HANDLE m_ThreadHandle;
|
||
|
|
volatile DWORD m_ThreadId;
|
||
|
|
SIZE_T m_StackSize;
|
||
|
|
ApartmentState m_ApartmentState;
|
||
|
|
ThreadPriority m_Priority;
|
||
|
|
|
||
|
|
void SetNameForDebugger(const char* name);
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|