mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2025-08-17 17:05:50 +00:00
Revert to legacy Windows behavior since Windows 10 allows CreateThread in Universal apps
This commit is contained in:
parent
7814cb3fae
commit
25612824ca
@ -10,7 +10,6 @@ struct sockaddr_storage RemoteAddr;
|
||||
SOCKADDR_LEN RemoteAddrLen;
|
||||
int ServerMajorVersion;
|
||||
STREAM_CONFIGURATION StreamConfig;
|
||||
PLATFORM_CALLBACKS PlatformCallbacks;
|
||||
CONNECTION_LISTENER_CALLBACKS ListenerCallbacks;
|
||||
DECODER_RENDERER_CALLBACKS VideoCallbacks;
|
||||
AUDIO_RENDERER_CALLBACKS AudioCallbacks;
|
||||
@ -119,11 +118,6 @@ static void ClInternalConnectionTerminated(long errorCode)
|
||||
originalTerminationCallback(errorCode);
|
||||
}
|
||||
|
||||
void LiCompleteThreadStart(void)
|
||||
{
|
||||
PltRunThreadProc();
|
||||
}
|
||||
|
||||
static int resolveHostName(const char *host)
|
||||
{
|
||||
struct addrinfo hints, *res;
|
||||
@ -153,7 +147,7 @@ static int resolveHostName(const char *host)
|
||||
|
||||
/* Starts the connection to the streaming machine */
|
||||
int LiStartConnection(const char* host, PSTREAM_CONFIGURATION streamConfig, PCONNECTION_LISTENER_CALLBACKS clCallbacks,
|
||||
PDECODER_RENDERER_CALLBACKS drCallbacks, PAUDIO_RENDERER_CALLBACKS arCallbacks, PPLATFORM_CALLBACKS plCallbacks,
|
||||
PDECODER_RENDERER_CALLBACKS drCallbacks, PAUDIO_RENDERER_CALLBACKS arCallbacks,
|
||||
void* renderContext, int drFlags, int _serverMajorVersion) {
|
||||
int err;
|
||||
|
||||
@ -161,8 +155,7 @@ int LiStartConnection(const char* host, PSTREAM_CONFIGURATION streamConfig, PCON
|
||||
memcpy(&StreamConfig, streamConfig, sizeof(StreamConfig));
|
||||
|
||||
// Replace missing callbacks with placeholders
|
||||
fixupMissingCallbacks(&drCallbacks, &arCallbacks, &clCallbacks, &plCallbacks);
|
||||
memcpy(&PlatformCallbacks, plCallbacks, sizeof(PlatformCallbacks));
|
||||
fixupMissingCallbacks(&drCallbacks, &arCallbacks, &clCallbacks);
|
||||
memcpy(&VideoCallbacks, drCallbacks, sizeof(VideoCallbacks));
|
||||
memcpy(&AudioCallbacks, arCallbacks, sizeof(AudioCallbacks));
|
||||
|
||||
|
@ -38,16 +38,8 @@ static CONNECTION_LISTENER_CALLBACKS fakeClCallbacks = {
|
||||
.displayTransientMessage = fakeClDisplayTransientMessage,
|
||||
};
|
||||
|
||||
static void fakePlThreadStart(void) {}
|
||||
static void fakePlDebugPrint(char* string) {}
|
||||
|
||||
static PLATFORM_CALLBACKS fakePlCallbacks = {
|
||||
.threadStart = fakePlThreadStart,
|
||||
.debugPrint = fakePlDebugPrint,
|
||||
};
|
||||
|
||||
void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS *drCallbacks, PAUDIO_RENDERER_CALLBACKS *arCallbacks,
|
||||
PCONNECTION_LISTENER_CALLBACKS *clCallbacks, PPLATFORM_CALLBACKS *plCallbacks)
|
||||
PCONNECTION_LISTENER_CALLBACKS *clCallbacks)
|
||||
{
|
||||
if (*drCallbacks == NULL) {
|
||||
*drCallbacks = &fakeDrCallbacks;
|
||||
@ -105,16 +97,4 @@ void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS *drCallbacks, PAUDIO_REND
|
||||
(*clCallbacks)->displayTransientMessage = fakeClDisplayTransientMessage;
|
||||
}
|
||||
}
|
||||
|
||||
if (*plCallbacks == NULL) {
|
||||
*plCallbacks = &fakePlCallbacks;
|
||||
}
|
||||
else {
|
||||
if ((*plCallbacks)->threadStart == NULL) {
|
||||
(*plCallbacks)->threadStart = fakePlThreadStart;
|
||||
}
|
||||
if ((*plCallbacks)->debugPrint == NULL) {
|
||||
(*plCallbacks)->debugPrint = fakePlDebugPrint;
|
||||
}
|
||||
}
|
||||
}
|
@ -11,7 +11,6 @@ extern struct sockaddr_storage RemoteAddr;
|
||||
extern SOCKADDR_LEN RemoteAddrLen;
|
||||
extern int ServerMajorVersion;
|
||||
extern STREAM_CONFIGURATION StreamConfig;
|
||||
extern PLATFORM_CALLBACKS PlatformCallbacks;
|
||||
extern CONNECTION_LISTENER_CALLBACKS ListenerCallbacks;
|
||||
extern DECODER_RENDERER_CALLBACKS VideoCallbacks;
|
||||
extern AUDIO_RENDERER_CALLBACKS AudioCallbacks;
|
||||
@ -19,7 +18,7 @@ extern AUDIO_RENDERER_CALLBACKS AudioCallbacks;
|
||||
int isBeforeSignedInt(int numA, int numB, int ambiguousCase);
|
||||
|
||||
void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS *drCallbacks, PAUDIO_RENDERER_CALLBACKS *arCallbacks,
|
||||
PCONNECTION_LISTENER_CALLBACKS *clCallbacks, PPLATFORM_CALLBACKS *plCallbacks);
|
||||
PCONNECTION_LISTENER_CALLBACKS *clCallbacks);
|
||||
|
||||
char* getSdpPayloadForStreamConfig(int rtspClientVersion, int *length);
|
||||
|
||||
|
@ -132,19 +132,6 @@ typedef struct _CONNECTION_LISTENER_CALLBACKS {
|
||||
ConnListenerDisplayTransientMessage displayTransientMessage;
|
||||
} CONNECTION_LISTENER_CALLBACKS, *PCONNECTION_LISTENER_CALLBACKS;
|
||||
|
||||
// This is a Windows-only callback used to indicate that the client
|
||||
// should call LiCompleteThreadStart() from a new thread as soon as possible.
|
||||
typedef void(*PlatformThreadStart)(void);
|
||||
|
||||
// This is a Windows-only callback used to display a debug message for
|
||||
// developer use.
|
||||
typedef void(*PlatformDebugPrint)(char* string);
|
||||
|
||||
typedef struct _PLATFORM_CALLBACKS {
|
||||
PlatformThreadStart threadStart;
|
||||
PlatformDebugPrint debugPrint;
|
||||
} PLATFORM_CALLBACKS, *PPLATFORM_CALLBACKS;
|
||||
|
||||
// This function begins streaming.
|
||||
//
|
||||
// Callbacks are all optional. Pass NULL for individual callbacks within each struct or pass NULL for the entire struct
|
||||
@ -153,8 +140,7 @@ typedef struct _PLATFORM_CALLBACKS {
|
||||
// _serverMajorVersion is the major version number of the 'appversion' tag in the /serverinfo request
|
||||
//
|
||||
int LiStartConnection(const char* host, PSTREAM_CONFIGURATION streamConfig, PCONNECTION_LISTENER_CALLBACKS clCallbacks,
|
||||
PDECODER_RENDERER_CALLBACKS drCallbacks, PAUDIO_RENDERER_CALLBACKS arCallbacks, PPLATFORM_CALLBACKS plCallbacks,
|
||||
void* renderContext, int drFlags, int _serverMajorVersion);
|
||||
PDECODER_RENDERER_CALLBACKS drCallbacks, PAUDIO_RENDERER_CALLBACKS arCallbacks, void* renderContext, int drFlags, int _serverMajorVersion);
|
||||
|
||||
// This function stops streaming.
|
||||
void LiStopConnection(void);
|
||||
@ -163,11 +149,6 @@ void LiStopConnection(void);
|
||||
// from the integer passed to the ConnListenerStageXXX callbacks
|
||||
const char* LiGetStageName(int stage);
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Call in the context of a new thread */
|
||||
void LiCompleteThreadStart(void);
|
||||
#endif
|
||||
|
||||
// This function queues a mouse move event to be sent to the remote server.
|
||||
int LiSendMouseMoveEvent(short deltaX, short deltaY);
|
||||
|
||||
|
@ -1,17 +1,26 @@
|
||||
#include "PlatformThreads.h"
|
||||
#include "Platform.h"
|
||||
|
||||
#if defined(LC_WINDOWS)
|
||||
WCHAR DbgBuf[512];
|
||||
#endif
|
||||
|
||||
int initializePlatformSockets(void);
|
||||
void cleanupPlatformSockets(void);
|
||||
|
||||
#if defined(LC_WINDOWS_PHONE) || defined(LC_WINDOWS)
|
||||
CHAR DbgBuf[512];
|
||||
#endif
|
||||
#if defined(LC_WINDOWS)
|
||||
PLT_MUTEX thread_list_lock;
|
||||
PLT_THREAD *thread_head;
|
||||
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
static PLT_MUTEX thread_list_lock;
|
||||
static PLT_THREAD *pending_thread_head;
|
||||
static PLT_THREAD *thread_head;
|
||||
DWORD WINAPI ThreadProc(LPVOID lpParameter) {
|
||||
struct thread_context *ctx = (struct thread_context *)lpParameter;
|
||||
|
||||
ctx->entry(ctx->context);
|
||||
|
||||
free(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
void* ThreadProc(void* context) {
|
||||
struct thread_context *ctx = (struct thread_context *)context;
|
||||
@ -25,7 +34,7 @@ void* ThreadProc(void* context) {
|
||||
#endif
|
||||
|
||||
void PltSleepMs(int ms) {
|
||||
#if defined(LC_WINDOWS) || defined (LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
WaitForSingleObjectEx(GetCurrentThread(), ms, FALSE);
|
||||
#else
|
||||
useconds_t usecs = ms * 1000;
|
||||
@ -34,7 +43,7 @@ void PltSleepMs(int ms) {
|
||||
}
|
||||
|
||||
int PltCreateMutex(PLT_MUTEX *mutex) {
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
*mutex = CreateMutexEx(NULL, NULL, 0, MUTEX_ALL_ACCESS);
|
||||
if (!*mutex) {
|
||||
return -1;
|
||||
@ -46,7 +55,7 @@ int PltCreateMutex(PLT_MUTEX *mutex) {
|
||||
}
|
||||
|
||||
void PltDeleteMutex(PLT_MUTEX *mutex) {
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
CloseHandle(*mutex);
|
||||
#else
|
||||
pthread_mutex_destroy(mutex);
|
||||
@ -54,7 +63,7 @@ void PltDeleteMutex(PLT_MUTEX *mutex) {
|
||||
}
|
||||
|
||||
void PltLockMutex(PLT_MUTEX *mutex) {
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
int err;
|
||||
err = WaitForSingleObjectEx(*mutex, INFINITE, FALSE);
|
||||
if (err != WAIT_OBJECT_0) {
|
||||
@ -66,7 +75,7 @@ void PltLockMutex(PLT_MUTEX *mutex) {
|
||||
}
|
||||
|
||||
void PltUnlockMutex(PLT_MUTEX *mutex) {
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
ReleaseMutex(*mutex);
|
||||
#else
|
||||
pthread_mutex_unlock(mutex);
|
||||
@ -74,16 +83,15 @@ void PltUnlockMutex(PLT_MUTEX *mutex) {
|
||||
}
|
||||
|
||||
void PltJoinThread(PLT_THREAD *thread) {
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
// Wait for the thread to leave our code
|
||||
WaitForSingleObjectEx(thread->termCompleted, INFINITE, FALSE);
|
||||
#if defined(LC_WINDOWS)
|
||||
WaitForSingleObjectEx(thread->handle, INFINITE, FALSE);
|
||||
#else
|
||||
pthread_join(*thread, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PltCloseThread(PLT_THREAD *thread) {
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
PLT_THREAD *current_thread;
|
||||
|
||||
PltLockMutex(&thread_list_lock);
|
||||
@ -114,13 +122,13 @@ void PltCloseThread(PLT_THREAD *thread) {
|
||||
PltUnlockMutex(&thread_list_lock);
|
||||
|
||||
CloseHandle(thread->termRequested);
|
||||
CloseHandle(thread->termCompleted);
|
||||
CloseHandle(thread->handle);
|
||||
#else
|
||||
#endif
|
||||
}
|
||||
|
||||
int PltIsThreadInterrupted(PLT_THREAD *thread) {
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
return thread->cancelled;
|
||||
#else
|
||||
// The thread will die here if a cancellation was requested
|
||||
@ -130,7 +138,7 @@ int PltIsThreadInterrupted(PLT_THREAD *thread) {
|
||||
}
|
||||
|
||||
void PltInterruptThread(PLT_THREAD *thread) {
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
thread->cancelled = 1;
|
||||
SetEvent(thread->termRequested);
|
||||
#else
|
||||
@ -138,41 +146,6 @@ void PltInterruptThread(PLT_THREAD *thread) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void PltRunThreadProc(void) {
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
PLT_THREAD *thread;
|
||||
|
||||
// Grab the first entry from the pending list and move it
|
||||
// to the active list
|
||||
PltLockMutex(&thread_list_lock);
|
||||
thread = pending_thread_head;
|
||||
|
||||
// If there's no pending thread, something is seriously wrong
|
||||
LC_ASSERT(thread != NULL);
|
||||
|
||||
pending_thread_head = pending_thread_head->next;
|
||||
|
||||
thread->next = thread_head;
|
||||
thread_head = thread;
|
||||
PltUnlockMutex(&thread_list_lock);
|
||||
|
||||
// Set up final thread state before running
|
||||
thread->tid = GetCurrentThreadId();
|
||||
|
||||
// Now we're going to invoke the thread proc
|
||||
thread->ctx->entry(thread->ctx->context);
|
||||
free(thread->ctx);
|
||||
|
||||
// Signal the event to indicate the thread has "terminated"
|
||||
SetEvent(thread->termCompleted);
|
||||
|
||||
// PltCloseThread() frees this state
|
||||
#else
|
||||
// This code shouldn't be called on *NIX
|
||||
LC_ASSERT(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
int PltCreateThread(ThreadEntry entry, void* context, PLT_THREAD *thread) {
|
||||
struct thread_context *ctx;
|
||||
int err;
|
||||
@ -185,7 +158,7 @@ int PltCreateThread(ThreadEntry entry, void* context, PLT_THREAD *thread) {
|
||||
ctx->entry = entry;
|
||||
ctx->context = context;
|
||||
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
{
|
||||
thread->termRequested = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
|
||||
if (thread->termRequested == NULL) {
|
||||
@ -193,26 +166,27 @@ int PltCreateThread(ThreadEntry entry, void* context, PLT_THREAD *thread) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
thread->termCompleted = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
|
||||
if (thread->termCompleted == NULL) {
|
||||
thread->cancelled = 0;
|
||||
|
||||
thread->handle = CreateThread(NULL, 0, ThreadProc, ctx, CREATE_SUSPENDED, &thread->tid);
|
||||
if (thread->handle == NULL) {
|
||||
CloseHandle(thread->termRequested);
|
||||
free(ctx);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
// Add this thread to the thread list
|
||||
PltLockMutex(&thread_list_lock);
|
||||
thread->next = thread_head;
|
||||
thread_head = thread;
|
||||
PltUnlockMutex(&thread_list_lock);
|
||||
|
||||
thread->cancelled = 0;
|
||||
thread->ctx = ctx;
|
||||
// Now the thread can run
|
||||
ResumeThread(thread->handle);
|
||||
|
||||
// Queue on the pending threads list
|
||||
PltLockMutex(&thread_list_lock);
|
||||
thread->next = pending_thread_head;
|
||||
pending_thread_head = thread;
|
||||
PltUnlockMutex(&thread_list_lock);
|
||||
err = 0;
|
||||
}
|
||||
|
||||
// Make a callback to managed code to ask for a thread to grab this
|
||||
PlatformCallbacks.threadStart();
|
||||
|
||||
err = 0;
|
||||
}
|
||||
#else
|
||||
{
|
||||
@ -227,7 +201,7 @@ int PltCreateThread(ThreadEntry entry, void* context, PLT_THREAD *thread) {
|
||||
}
|
||||
|
||||
int PltCreateEvent(PLT_EVENT *event) {
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
*event = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
|
||||
if (!*event) {
|
||||
return -1;
|
||||
@ -243,7 +217,7 @@ int PltCreateEvent(PLT_EVENT *event) {
|
||||
}
|
||||
|
||||
void PltCloseEvent(PLT_EVENT *event) {
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
CloseHandle(*event);
|
||||
#else
|
||||
pthread_mutex_destroy(&event->mutex);
|
||||
@ -252,7 +226,7 @@ void PltCloseEvent(PLT_EVENT *event) {
|
||||
}
|
||||
|
||||
void PltSetEvent(PLT_EVENT *event) {
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
SetEvent(*event);
|
||||
#else
|
||||
event->signalled = 1;
|
||||
@ -261,7 +235,7 @@ void PltSetEvent(PLT_EVENT *event) {
|
||||
}
|
||||
|
||||
void PltClearEvent(PLT_EVENT *event) {
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
ResetEvent(*event);
|
||||
#else
|
||||
event->signalled = 0;
|
||||
@ -269,7 +243,7 @@ void PltClearEvent(PLT_EVENT *event) {
|
||||
}
|
||||
|
||||
int PltWaitForEvent(PLT_EVENT *event) {
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
DWORD error;
|
||||
PLT_THREAD *current_thread;
|
||||
HANDLE objects[2];
|
||||
@ -311,7 +285,7 @@ int PltWaitForEvent(PLT_EVENT *event) {
|
||||
}
|
||||
|
||||
uint64_t PltGetMillis(void) {
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
return GetTickCount64();
|
||||
#else
|
||||
struct timeval tv;
|
||||
@ -330,7 +304,7 @@ int initializePlatform(void) {
|
||||
return err;
|
||||
}
|
||||
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
return PltCreateMutex(&thread_list_lock);
|
||||
#else
|
||||
return 0;
|
||||
@ -340,8 +314,7 @@ int initializePlatform(void) {
|
||||
void cleanupPlatform(void) {
|
||||
cleanupPlatformSockets();
|
||||
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
LC_ASSERT(pending_thread_head == NULL);
|
||||
#if defined(LC_WINDOWS)
|
||||
LC_ASSERT(thread_head == NULL);
|
||||
|
||||
PltDeleteMutex(&thread_list_lock);
|
||||
|
@ -27,18 +27,17 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include "Limelight.h"
|
||||
#if defined(LC_WINDOWS_PHONE) || defined(LC_WINDOWS)
|
||||
extern char DbgBuf[512];
|
||||
extern PLATFORM_CALLBACKS PlatformCallbacks;
|
||||
#if defined(LC_WINDOWS)
|
||||
extern WCHAR DbgBuf[512];
|
||||
#define Limelog(s, ...) \
|
||||
sprintf(DbgBuf, s, ##__VA_ARGS__); \
|
||||
PlatformCallbacks.debugPrint(DbgBuf)
|
||||
swprintf(DbgBuf, sizeof(DbgBuf) / sizeof(WCHAR), L ## s, ##__VA_ARGS__); \
|
||||
OutputDebugStringW(DbgBuf)
|
||||
#else
|
||||
#define Limelog(s, ...) \
|
||||
fprintf(stderr, s, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if defined(LC_WINDOWS_PHONE) || defined(LC_WINDOWS)
|
||||
#if defined(LC_WINDOWS)
|
||||
#include <crtdbg.h>
|
||||
#define LC_ASSERT(x) __analysis_assume(x); \
|
||||
_ASSERTE(x)
|
||||
|
@ -108,7 +108,7 @@ int enableNoDelay(SOCKET s) {
|
||||
}
|
||||
|
||||
int initializePlatformSockets(void) {
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
WSADATA data;
|
||||
return WSAStartup(MAKEWORD(2, 0), &data);
|
||||
#elif defined(LC_POSIX)
|
||||
@ -129,7 +129,7 @@ int initializePlatformSockets(void) {
|
||||
}
|
||||
|
||||
void cleanupPlatformSockets(void) {
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
WSACleanup();
|
||||
#else
|
||||
#endif
|
||||
|
@ -10,14 +10,12 @@ struct thread_context {
|
||||
void* context;
|
||||
};
|
||||
|
||||
#if defined(LC_WINDOWS) || defined(LC_WINDOWS_PHONE)
|
||||
#if defined(LC_WINDOWS)
|
||||
typedef struct _PLT_THREAD {
|
||||
HANDLE handle;
|
||||
int cancelled;
|
||||
DWORD tid;
|
||||
HANDLE termRequested;
|
||||
HANDLE termCompleted;
|
||||
|
||||
struct thread_context *ctx;
|
||||
|
||||
struct _PLT_THREAD *next;
|
||||
} PLT_THREAD;
|
||||
|
Loading…
x
Reference in New Issue
Block a user