Skip to content

Commit 78caed3

Browse files
call public API function and fallback if not available
1 parent c61f1e9 commit 78caed3

1 file changed

Lines changed: 16 additions & 8 deletions

File tree

profiling/src/php_ffi.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -631,14 +631,8 @@ __attribute__((weak)) zend_write_func_t zend_write;
631631
* This function is meant to be called in the GINIT phase of a PHP request, it is also safe to be
632632
* called in RINIT or during request processing, but its outcome won't change anymore after GINIT.
633633
* That being said, it being a costly function (module registry lookup, `dlsym()`,
634-
* `__tls_get_addr()`), the best usage pattern is to call this in GINIT and cache the result in a
635-
* thread local.
636-
*
637-
* Why not just `__attribute__((weak)) php_parallel_scheduler_context;`?
638-
* This would work if we could enforce the order of `dlopen()` calls for extensions (which we
639-
* can't). If the parallel extension is loaded before the profiler extension it works just nice
640-
* but if the profiler gets loaded first this will not resolve correct. Luckily `dlsym()` behaves
641-
* as a safe wrapper around this.
634+
* `__tls_get_addr()` in the fallback branch), the best usage pattern is to call this in GINIT and
635+
* cache the result in a thread local.
642636
*/
643637
bool ddog_php_prof_is_parallel_thread() {
644638
// Check if parallel extension is loaded to retrieve it's dl handle
@@ -648,6 +642,20 @@ bool ddog_php_prof_is_parallel_thread() {
648642
return false;
649643
}
650644

645+
// Try to find the new public API function first (available in parallel >= 1.2.9)
646+
zend_bool (*is_worker)(void) = DL_FETCH_SYMBOL(parallel_module->handle, "php_parallel_is_parallel_worker_thread");
647+
if (is_worker) {
648+
return is_worker();
649+
}
650+
651+
// Fallback: for older versions of parallel, we can access the TLS variable
652+
// `php_parallel_scheduler_context` and do a NULL check.
653+
654+
// Why not just `__attribute__((weak)) php_parallel_scheduler_context;`?
655+
// This would work if we could enforce the order of `dlopen()` calls for extensions (which we
656+
// can't). If the parallel extension is loaded before the profiler extension it works just nice
657+
// but if the profiler gets loaded first this will not resolve correct. Luckily `dlsym()`
658+
// behaves as a safe wrapper around this.
651659
void *tls_symbol = DL_FETCH_SYMBOL(parallel_module->handle, "php_parallel_scheduler_context");
652660

653661
if (tls_symbol == NULL) {

0 commit comments

Comments
 (0)