Repository: ChaiScript/ChaiScript (2026-04-12T00:43:21Z)

Issue:
TSAN builds don't actually use threads
The default is that threading is disabled. We want at the very least the TSAN builds to have threading enabled, but we also need at least one windows build (MSVC) with threading enabled.



Discussion:
@leftibot add to the build matrix. Be intelligent, don't just double all build targets, I think. Make sure all reasonable possible combinations are covered for threading enabled/disabled with optimizations enabled/disabled and tsan enabled for linux/macos and optimizations enabled/disabled threading enabled/disabled on msvc



Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 62ae5d24..ff0c6778 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -9,17 +9,21 @@ on:
 
 jobs:
   linux:
-    name: Linux GCC ${{ matrix.build_type }}
+    name: Linux GCC ${{ matrix.build_type }} threads=${{ matrix.multithread }}
     runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       matrix:
         build_type: [Debug, Release]
+        multithread: [ON, OFF]
     steps:
       - uses: actions/checkout@v4
 
+      - name: Install Ninja
+        run: sudo apt-get install -y ninja-build
+
       - name: Configure
-        run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
+        run: cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DMULTITHREAD_SUPPORT_ENABLED=${{ matrix.multithread }}
 
       - name: Build
         run: cmake --build build -j
@@ -28,17 +32,21 @@ jobs:
         run: ctest --test-dir build --output-on-failure
 
   macos:
-    name: macOS AppleClang ${{ matrix.build_type }}
+    name: macOS AppleClang ${{ matrix.build_type }} threads=${{ matrix.multithread }}
     runs-on: macos-latest
     strategy:
       fail-fast: false
       matrix:
         build_type: [Debug, Release]
+        multithread: [ON, OFF]
     steps:
       - uses: actions/checkout@v4
 
+      - name: Install Ninja
+        run: brew install ninja
+
       - name: Configure
-        run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
+        run: cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DMULTITHREAD_SUPPORT_ENABLED=${{ matrix.multithread }}
 
       - name: Build
         run: cmake --build build -j
@@ -56,8 +64,11 @@ jobs:
     steps:
       - uses: actions/checkout@v4
 
+      - name: Install Ninja
+        run: sudo apt-get install -y ninja-build
+
       - name: Configure
-        run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DENABLE_ADDRESS_SANITIZER=ON -DENABLE_UNDEFINED_SANITIZER=ON
+        run: cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DENABLE_ADDRESS_SANITIZER=ON -DENABLE_UNDEFINED_SANITIZER=ON
 
       - name: Build
         run: cmake --build build -j
@@ -75,8 +86,11 @@ jobs:
     steps:
       - uses: actions/checkout@v4
 
+      - name: Install Ninja
+        run: brew install ninja
+
       - name: Configure
-        run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DENABLE_ADDRESS_SANITIZER=ON -DENABLE_UNDEFINED_SANITIZER=ON
+        run: cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DENABLE_ADDRESS_SANITIZER=ON -DENABLE_UNDEFINED_SANITIZER=ON
 
       - name: Build
         run: cmake --build build -j
@@ -85,17 +99,18 @@ jobs:
         run: ctest --test-dir build --output-on-failure
 
   windows:
-    name: Windows MSVC ${{ matrix.build_type }}
+    name: Windows MSVC ${{ matrix.build_type }} threads=${{ matrix.multithread }}
     runs-on: windows-latest
     strategy:
       fail-fast: false
       matrix:
         build_type: [Debug, Release]
+        multithread: [ON, OFF]
     steps:
       - uses: actions/checkout@v4
 
       - name: Configure
-        run: cmake -B build
+        run: cmake -B build -DMULTITHREAD_SUPPORT_ENABLED=${{ matrix.multithread }}
 
       - name: Build
         run: cmake --build build --config ${{ matrix.build_type }} -j
@@ -113,8 +128,11 @@ jobs:
     steps:
       - uses: actions/checkout@v4
 
+      - name: Install Ninja
+        run: sudo apt-get install -y ninja-build
+
       - name: Configure
-        run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DENABLE_THREAD_SANITIZER=ON
+        run: cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DENABLE_THREAD_SANITIZER=ON -DMULTITHREAD_SUPPORT_ENABLED=ON
 
       - name: Build
         run: cmake --build build -j
@@ -132,8 +150,11 @@ jobs:
     steps:
       - uses: actions/checkout@v4
 
+      - name: Install Ninja
+        run: brew install ninja
+
       - name: Configure
-        run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DENABLE_THREAD_SANITIZER=ON
+        run: cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DENABLE_THREAD_SANITIZER=ON -DMULTITHREAD_SUPPORT_ENABLED=ON
 
       - name: Build
         run: cmake --build build -j
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7fcb4bc2..4a4b6f55 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -292,6 +292,15 @@ endif()
 file(GLOB UNIT_TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/unittests/ ${CMAKE_CURRENT_SOURCE_DIR}/unittests/*.chai ${CMAKE_CURRENT_SOURCE_DIR}/unittests/3.x/*.chai)
 list(SORT UNIT_TESTS)
 
+if(NOT MULTITHREAD_SUPPORT_ENABLED)
+  list(REMOVE_ITEM UNIT_TESTS
+    async_engine_lifetime.chai
+    future.chai
+    list_push_front.chai
+    move_async.chai
+  )
+endif()
+
 file(GLOB PERFORMANCE_TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/performance_tests/ ${CMAKE_CURRENT_SOURCE_DIR}/performance_tests/*.chai)
 list(SORT PERFORMANCE_TESTS)
 
@@ -430,6 +439,10 @@ if(BUILD_TESTING)
     target_link_libraries(emscripten_eval_test ${LIBS})
     add_test(NAME Emscripten_Eval_Test COMMAND emscripten_eval_test)
 
+    add_executable(threading_config_test unittests/threading_config_test.cpp)
+    target_link_libraries(threading_config_test ${LIBS})
+    add_test(NAME Threading_Config_Test COMMAND threading_config_test)
+
     install(TARGETS test_module RUNTIME DESTINATION bin LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}/chaiscript")
   endif()
 endif()


Test patch:
diff --git a/unittests/threading_config_test.cpp b/unittests/threading_config_test.cpp
new file mode 100644
index 00000000..7696d13a
--- /dev/null
+++ b/unittests/threading_config_test.cpp
@@ -0,0 +1,26 @@
+#include <chaiscript/chaiscript.hpp>
+
+int main() {
+#ifndef CHAISCRIPT_NO_THREADS
+  // When threading is enabled, verify that async() is registered and functional
+  chaiscript::ChaiScript chai;
+  const auto result = chai.eval<int>(R"(
+    var f = async(fun() { return 42; });
+    f.get();
+  )");
+  if (result != 42) {
+    return EXIT_FAILURE;
+  }
+#else
+  // When threading is disabled, verify that async() is NOT registered
+  chaiscript::ChaiScript chai;
+  try {
+    chai.eval("async(fun() { return 0; })");
+    return EXIT_FAILURE;
+  } catch (const std::exception &) {
+    // Expected: async should not exist
+  }
+#endif
+
+  return EXIT_SUCCESS;
+}