Embedding Julia: GC race conditions

I’m trying to understand how GC interaction from C works in case of multiple threads. How are race conditions avoided?

The manual says:

When writing code that embeds Julia, it is generally safe to use jl_value_t* values in between jl_... calls (as GC will only get triggered by those calls). But in order to make sure that values can survive jl_... calls, we have to tell Julia that we still hold a reference to Julia root values, a process called “GC rooting”. Rooting a value will ensure that the garbage collector does not accidentally identify this value as unused and free the memory backing that value. This can be done using the JL_GC_PUSH macros:

jl_value_t *ret = jl_eval_string("sqrt(2.0)");
JL_GC_PUSH1(&ret);
// Do something with ret
JL_GC_POP();

Is this not a race condition? If a jl_... call is made in another thread, just after the jl_eval_string call here, can’t we have the GC running before the JL_GC_PUSH1 is in effect?

(Note that a jl_... call occuring in another thread is indeed possible: further down this page of the manual it shows how this can happen from threads started by Julia itself.)