Fix ForeignThreadExceptions test (#25074)
authorJan Vorlicek <janvorli@microsoft.com>
Tue, 11 Jun 2019 22:42:46 +0000 (00:42 +0200)
committerJan Kotas <jkotas@microsoft.com>
Tue, 11 Jun 2019 22:42:46 +0000 (15:42 -0700)
This test creates a native thread on which it calls a managed callback. It uses
std::thread to create the thread. The problem is that on MUSL based Linux distros,
the default stack size for secondary threads is 80kB, which is not enough for this
test.
Since std::thread has no way to set the thread stack size, the fix is to use
pthreads on Unix and keep the std::thread for Windows only.

tests/src/Exceptions/ForeignThread/CMakeLists.txt
tests/src/Exceptions/ForeignThread/ForeignThreadExceptionsNative.cpp

index 66d249c..a8ab5a1 100644 (file)
@@ -11,6 +11,10 @@ endif(CLR_CMAKE_PLATFORM_DARWIN)
 
 set(SOURCES ForeignThreadExceptionsNative.cpp)
 
+if(NOT WIN32)
+add_compile_options(-pthread)
+endif()
+
 # add the executable
 add_library (ForeignThreadExceptionsNative SHARED ${SOURCES})
 
index 67a92e3..546935b 100644 (file)
@@ -3,11 +3,16 @@
 // See the LICENSE file in the project root for more information.
 
 #include "stdio.h"
+#include <stdlib.h>
 
+#ifdef _WIN32
 #pragma warning(push)
 #pragma warning(disable:4265 4577)
- #include <thread>
+#include <thread>
 #pragma warning(pop)
+#else // _WIN32
+#include <pthread.h>
+#endif // _WIN32
 
 // Work around typedef redefinition: platformdefines.h defines error_t
 // as unsigned while it's defined as int in errno.h.
 #undef error_t
 
 typedef void (*PFNACTION1)();
-
 extern "C" DLL_EXPORT void InvokeCallback(PFNACTION1 callback)
 {
     callback();
 }
 
+#ifndef _WIN32
+void* InvokeCallbackUnix(void* callback)
+{
+    InvokeCallback((PFNACTION1)callback);
+    return NULL;
+}
+
+#define AbortIfFail(st) if (st != 0) abort()
+
+#endif // !_WIN32
+
 extern "C" DLL_EXPORT void InvokeCallbackOnNewThread(PFNACTION1 callback)
 {
+#ifdef _WIN32
     std::thread t1(InvokeCallback, callback);
     t1.join();
-}
\ No newline at end of file
+#else // _WIN32
+    // For Unix, we need to use pthreads to create the thread so that we can set its stack size.
+    // We need to set the stack size due to the very small (80kB) default stack size on MUSL
+    // based Linux distros.
+    pthread_attr_t attr;
+    int st = pthread_attr_init(&attr);
+    AbortIfFail(st);
+
+    // set stack size to 1.5MB
+    st = pthread_attr_setstacksize(&attr, 0x180000);
+    AbortIfFail(st);
+
+    pthread_t t;
+    st = pthread_create(&t, &attr, InvokeCallbackUnix, (void*)callback);
+    AbortIfFail(st);
+
+    st = pthread_join(t, NULL);
+    AbortIfFail(st);
+#endif // _WIN32
+}