diff --git a/src/inc/quic_platform.h b/src/inc/quic_platform.h index e65cb3095e..5411413382 100644 --- a/src/inc/quic_platform.h +++ b/src/inc/quic_platform.h @@ -93,7 +93,7 @@ typedef struct QUIC_SINGLE_LIST_ENTRY { #define QUIC_POOL_TLS_PRINCIPAL 'D1cQ' // Qc1D - QUIC Platform TLS Principal #define QUIC_POOL_TLS_CTX 'E1cQ' // Qc1E - QUIC Platform TLS Context #define QUIC_POOL_TLS_TRANSPARAMS 'F1cQ' // Qc1F - QUIC Platform TLS Transport Parameters -#define QUIC_POOL_TLS_RESUMPTION '02cQ' // Qc20 - QUIC Platform TLS Resumption Buffer +#define QUIC_POOL_CUSTOM_THREAD '02cQ' // Qc20 - QUIC Platform Customm Thread Context #define QUIC_POOL_TLS_SECCONF '12cQ' // Qc21 - QUIC Platform TLS Sec Config #define QUIC_POOL_TLS_PACKETKEY '22cQ' // Qc22 - QUIC Platform TLS Packet Key #define QUIC_POOL_TLS_KEY '32cQ' // Qc23 - QUIC Platform TLS Key diff --git a/src/inc/quic_platform_linux.h b/src/inc/quic_platform_linux.h index 1e13cf967c..75d25a9da5 100644 --- a/src/inc/quic_platform_linux.h +++ b/src/inc/quic_platform_linux.h @@ -633,6 +633,26 @@ typedef struct QUIC_THREAD_CONFIG { void* Context; } QUIC_THREAD_CONFIG; +#ifdef QUIC_USE_CUSTOM_THREAD_CONTEXT + +// +// Extension point that allows additional platform specific logic to be executed +// for every thread created. The platform must define QUIC_USE_CUSTOM_THREAD_CONTEXT +// and implement the QuicThreadCustomStart function. QuicThreadCustomStart MUST +// call the Callback passed in. QuicThreadCustomStart MUST also free +// CustomContext (via QUIC_FREE(CustomContext, QUIC_POOL_CUSTOM_THREAD)) before +// returning. +// + +typedef struct QUIC_THREAD_CUSTOM_CONTEXT { + LPTHREAD_START_ROUTINE Callback; + void* Context; +} QUIC_THREAD_CUSTOM_CONTEXT; + +QUIC_THREAD_CALLBACK(QuicThreadCustomStart, CustomContext); // QUIC_THREAD_CUSTOM_CONTEXT* CustomContext + +#endif // QUIC_USE_CUSTOM_THREAD_CONTEXT + QUIC_STATUS QuicThreadCreate( _In_ QUIC_THREAD_CONFIG* Config, diff --git a/src/inc/quic_platform_winuser.h b/src/inc/quic_platform_winuser.h index fbcadfcdb8..d55448ffb4 100644 --- a/src/inc/quic_platform_winuser.h +++ b/src/inc/quic_platform_winuser.h @@ -780,6 +780,26 @@ typedef HANDLE QUIC_THREAD; #define QUIC_THREAD_RETURN(Status) return (DWORD)(Status) +#ifdef QUIC_USE_CUSTOM_THREAD_CONTEXT + +// +// Extension point that allows additional platform specific logic to be executed +// for every thread created. The platform must define QUIC_USE_CUSTOM_THREAD_CONTEXT +// and implement the QuicThreadCustomStart function. QuicThreadCustomStart MUST +// call the Callback passed in. QuicThreadCustomStart MUST also free +// CustomContext (via QUIC_FREE(CustomContext, QUIC_POOL_CUSTOM_THREAD)) before +// returning. +// + +typedef struct QUIC_THREAD_CUSTOM_CONTEXT { + LPTHREAD_START_ROUTINE Callback; + void* Context; +} QUIC_THREAD_CUSTOM_CONTEXT; + +QUIC_THREAD_CALLBACK(QuicThreadCustomStart, CustomContext); // QUIC_THREAD_CUSTOM_CONTEXT* CustomContext + +#endif // QUIC_USE_CUSTOM_THREAD_CONTEXT + inline QUIC_STATUS QuicThreadCreate( @@ -787,6 +807,32 @@ QuicThreadCreate( _Out_ QUIC_THREAD* Thread ) { +#ifdef QUIC_USE_CUSTOM_THREAD_CONTEXT + QUIC_THREAD_CUSTOM_CONTEXT* CustomContext = + QUIC_ALLOC_NONPAGED(sizeof(QUIC_THREAD_CUSTOM_CONTEXT), QUIC_POOL_CUSTOM_THREAD); + if (CustomContext == NULL) { + QuicTraceEvent( + AllocFailure, + "Allocation of '%s' failed. (%llu bytes)", + "Custom thread context", + sizeof(QUIC_THREAD_CUSTOM_CONTEXT)); + return QUIC_STATUS_OUT_OF_MEMORY; + } + CustomContext->Callback = Config->Callback; + CustomContext->Context = Config->Context; + *Thread = + CreateThread( + NULL, + 0, + QuicThreadCustomStart, + CustomContext, + 0, + NULL); + if (*Thread == NULL) { + QUIC_FREE(CustomContext, QUIC_POOL_CUSTOM_THREAD); + return GetLastError(); + } +#else // QUIC_USE_CUSTOM_THREAD_CONTEXT *Thread = CreateThread( NULL, @@ -798,6 +844,7 @@ QuicThreadCreate( if (*Thread == NULL) { return GetLastError(); } +#endif // QUIC_USE_CUSTOM_THREAD_CONTEXT const QUIC_PROCESSOR_INFO* ProcInfo = &QuicProcessorInfo[Config->IdealProcessor]; GROUP_AFFINITY Group = {0}; if (Config->Flags & QUIC_THREAD_FLAG_SET_AFFINITIZE) { diff --git a/src/platform/platform_linux.c b/src/platform/platform_linux.c index b0031c1287..a0d6502f21 100644 --- a/src/platform/platform_linux.c +++ b/src/platform/platform_linux.c @@ -734,6 +734,33 @@ QuicThreadCreate( } } +#ifdef QUIC_USE_CUSTOM_THREAD_CONTEXT + + QUIC_THREAD_CUSTOM_CONTEXT* CustomContext = + QUIC_ALLOC_NONPAGED(sizeof(QUIC_THREAD_CUSTOM_CONTEXT), QUIC_POOL_CUSTOM_THREAD); + if (CustomContext == NULL) { + Status = QUIC_STATUS_OUT_OF_MEMORY; + QuicTraceEvent( + AllocFailure, + "Allocation of '%s' failed. (%llu bytes)", + "Custom thread context", + sizeof(QUIC_THREAD_CUSTOM_CONTEXT)); + } + CustomContext->Callback = Config->Callback; + CustomContext->Context = Config->Context; + + if (pthread_create(Thread, &Attr, QuicThreadCustomStart, CustomContext)) { + Status = errno; + QuicTraceEvent( + LibraryErrorStatus, + "[ lib] ERROR, %u, %s.", + Status, + "pthread_create failed"); + QUIC_FREE(CustomContext, QUIC_POOL_CUSTOM_THREAD); + } + +#else // QUIC_USE_CUSTOM_THREAD_CONTEXT + if (pthread_create(Thread, &Attr, Config->Callback, Config->Context)) { Status = errno; QuicTraceEvent( @@ -743,6 +770,8 @@ QuicThreadCreate( "pthread_create failed"); } +#endif // !QUIC_USE_CUSTOM_THREAD_CONTEXT + #ifndef __GLIBC__ if (Status == QUIC_STATUS_SUCCESS) { if (Config->Flags & QUIC_THREAD_FLAG_SET_AFFINITIZE) {