External Issue: [Bug]: C interop code not running in same thread

27242, "Iainmon", "[Bug]: C interop code not running in same thread", "2025-05-15T06:45:38Z"

Summary of Problem

C code that I call from Chapel is not running in the same thread as the calling code. I would have expected the called C code to be run in the same thread. Is there a way to do this?

I am trying to put together a live demo of a ChAI based style transfer model. It needs the computer's webcam and a window on the screen that it can write to for every new frame. I have a working demo of this in C++, but have been trying to move it into Chapel. So far I haven't been able to invoke the C++ demo, or even a webcam screen from Chapel. Maybe someone knows of a better way to do this?

Any suggestions would be appreciated! :slight_smile:

Steps to Reproduce

Source Code:

mirror.h

#ifdef __cplusplus
extern "C" {
#endif
int run_mirror(void);
#ifdef __cplusplus
}
#endif

mirror.cpp

#include "mirror.h"
#include <opencv2/opencv.hpp>
#include <iostream>

extern "C" int run_mirror(void) {

    cv::VideoCapture cap(0); // Open the default camera
    if (!cap.isOpened()) {
        std::cerr << "Error: Could not open camera" << std::endl;
        return -1;
    }

    // Create a window to display the video
    const std::string windowName = "Mirror";
    cv::namedWindow(windowName, cv::WINDOW_AUTOSIZE);

    cv::Mat frame;
    while (true) {
        // Capture a new frame from the camera
        cap >> frame;
        if (frame.empty()) {
            std::cout << "Error: Blank frame grabbed" << std::endl;
            break;
        }

        // Show the frame in the window
        cv::imshow(windowName, frame);


        // Wait for 30ms. Exit if any key is pressed.
        if (cv::waitKey(30) >= 0) {
            std::cout << "Key pressed, exiting..." << std::endl;
            break;
        }
    }
    cap.release();
    cv::destroyAllWindows();
    return 0;
}

mirror.chpl

extern proc run_mirror(): int;

proc main(args: [] string) {
    writeln("Hello, world!");
    var x = run_mirror();
    writeln("x: ", x);
    writeln("Done!");
}
g++ -std=c++20 -c -fPIC mirror.cpp -o mirror.o $(pkg-config --cflags opencv4)
chpl mirror.h mirror.o mirror.chpl --print-commands --ldflags $(pkg-config --cflags --libs opencv4) -lstdc++

Issue:

Hello, world!
2025-05-14 23:32:52.749 mirror[6141:7361084] WARNING: AVCaptureDeviceTypeExternal is deprecated for Continuity Cameras. Please use AVCaptureDeviceTypeContinuityCamera and add NSCameraUseContinuityCameraDeviceType to your Info.plist.
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'NSWindow should only be instantiated on the main thread!'
*** First throw call stack:
(
)
libc++abi: terminating due to uncaught exception of type NSException
[1]    6141 abort      ./mirror

Is this issue currently blocking your progress?

Yes

Configuration Information

  • Output of chpl --version:
  • Output of $CHPL_HOME/util/printchplenv --anonymize:
  • Back-end compiler and version, e.g. gcc --version or clang --version:
  • (For Cray systems only) Output of module list:
chpl version 2.4.0
  built with LLVM version 19.1.7
  available LLVM targets: xcore, x86-64, x86, wasm64, wasm32, ve, systemz, sparcel, sparcv9, sparc, riscv64, riscv32, ppc64le, ppc64, ppc32le, ppc32, nvptx64, nvptx, msp430, mips64el, mips64, mipsel, mips, loongarch64, loongarch32, lanai, hexagon, bpfeb, bpfel, bpf, avr, thumbeb, thumb, armeb, arm, amdgcn, r600, aarch64_32, aarch64_be, aarch64, arm64_32, arm64
Copyright 2020-2025 Hewlett Packard Enterprise Development LP
Copyright 2004-2019 Cray Inc.
(See LICENSE file for more details)

MacOS, M2