diff --git a/limelight-common/Connection.c b/limelight-common/Connection.c index 48162a2..7edc9df 100644 --- a/limelight-common/Connection.c +++ b/limelight-common/Connection.c @@ -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)); diff --git a/limelight-common/FakeCallbacks.c b/limelight-common/FakeCallbacks.c index f62290d..fdd04d7 100644 --- a/limelight-common/FakeCallbacks.c +++ b/limelight-common/FakeCallbacks.c @@ -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; - } - } } \ No newline at end of file diff --git a/limelight-common/Limelight-internal.h b/limelight-common/Limelight-internal.h index d3baf9c..c4b865c 100644 --- a/limelight-common/Limelight-internal.h +++ b/limelight-common/Limelight-internal.h @@ -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); diff --git a/limelight-common/Limelight.h b/limelight-common/Limelight.h index 700e5f0..7ce3e35 100644 --- a/limelight-common/Limelight.h +++ b/limelight-common/Limelight.h @@ -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); diff --git a/limelight-common/Platform.c b/limelight-common/Platform.c index 86ccc17..05a900c 100644 --- a/limelight-common/Platform.c +++ b/limelight-common/Platform.c @@ -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); diff --git a/limelight-common/Platform.h b/limelight-common/Platform.h index fc9f623..aa13a1c 100644 --- a/limelight-common/Platform.h +++ b/limelight-common/Platform.h @@ -27,18 +27,17 @@ #include #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 #define LC_ASSERT(x) __analysis_assume(x); \ _ASSERTE(x) diff --git a/limelight-common/PlatformSockets.c b/limelight-common/PlatformSockets.c index 387406d..91294da 100644 --- a/limelight-common/PlatformSockets.c +++ b/limelight-common/PlatformSockets.c @@ -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 diff --git a/limelight-common/PlatformThreads.h b/limelight-common/PlatformThreads.h index 4c29246..4e4a8f1 100644 --- a/limelight-common/PlatformThreads.h +++ b/limelight-common/PlatformThreads.h @@ -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;