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