# Julia's Interaction with Foreign Threads

**URL:** https://discourse.julialang.org/t/julias-interaction-with-foreign-threads/133888
**Category:** General Usage
**Tags:** ffi, api, rust, compiler
**Created:** [November 14, 2025, 7:35pm UTC](https://discourse.julialang.org/t/julias-interaction-with-foreign-threads/133888 "2025-11-14T19:35:29Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![Chrysoberyl](https://avatars.discourse-cdn.com/v4/letter/c/ed655f/32.png) [@Chrysoberyl](https://discourse.julialang.org/u/Chrysoberyl)
#### Post date: [November 14, 2025, 7:35pm UTC](https://discourse.julialang.org/t/julias-interaction-with-foreign-threads/133888/1 "2025-11-14T19:35:29Z")

</div>

In my use case, I’m creating a Julia library for Julia code to interact with Rust code. It has 3 types of threads:

1. Threads created by Julia, which can handle foreign objects via [`ForeignType`](https://taaitaaiger.github.io/jlrs-tutorial/11-julia-module/opaque-and-foreign-types/foreign-type.html)
2. Threads created by Rust, which can call into Julia
3. Threads created by Rust/C which do not interact with any Julia data. Some of these threads come from external libraries and I have no control over them.

A MWE (Rust 1.89, Julia 1.11.7) is given here: [GitHub - lenianiva/MiniJlrs at thread-runtime](https://github.com/lenianiva/MiniJlrs/tree/thread-runtime)

For type (2) threads, upon the threads creation they call into Julia to be adopted:

```rust
			let mut ptls = unsafe { jlrs_get_ptls_states() };
			if ptls.is_null() {
				let pgcstack = unsafe { jl_adopt_thread() };
				ptls = unsafe { jlrs_ptls_from_gcstack(pgcstack) };
			}
			unsafe { jl_gc_safe_enter(ptls) };

```

where

```c
    JL_CONST_FUNC jl_tls_states_t *jlrs_get_ptls_states(void)
    {
        jl_gcframe_t **pgcstack = jl_get_pgcstack();
        if (pgcstack == NULL)
        {
            return NULL;
        }

        jl_task_t *task = container_of(pgcstack, jl_task_t, gcstack);
        return task->ptls;
    }

    jl_tls_states_t *jlrs_ptls_from_gcstack(jl_gcframe_t **pgcstack)
    {
        jl_task_t *task = container_of(pgcstack, jl_task_t, gcstack);
        return task->ptls;
    }

```

In this MWE, there are no (2) threads, but when some Julia code spawns the runtime (which launches threads), it occasionally ends in a segmentation fault:

```julia-auto
double free or corruption (out)

[866026] signal 6 (-6): Aborted
in expression starting at none:0

```

Does this mean the creation of (3) threads require special attention from Julia? I also tried calling `jl_enter_threaded_region` before creating the threads but it had no effect on the segmentation fault. Any help for narrowing down the problem is appreciated.

---

<div class="post-metadata">

### Author: ![Chrysoberyl](https://avatars.discourse-cdn.com/v4/letter/c/ed655f/32.png) [@Chrysoberyl](https://discourse.julialang.org/u/Chrysoberyl)
#### Post date: [November 20, 2025, 4:04am UTC](https://discourse.julialang.org/t/julias-interaction-with-foreign-threads/133888/2 "2025-11-20T04:04:28Z")

</div>

I found out about the source of the bug. It was not because of multithreading, but rather double free: [fix: Double free due to not cloning by lenianiva · Pull Request #229 · Taaitaaiger/jlrs · GitHub](https://github.com/Taaitaaiger/jlrs/pull/229)
