Skip to content

add isForkedChild() for tbb fork-safety checks#244

Open
kevinushey wants to merge 1 commit intomasterfrom
feature/is-forked-child
Open

add isForkedChild() for tbb fork-safety checks#244
kevinushey wants to merge 1 commit intomasterfrom
feature/is-forked-child

Conversation

@kevinushey
Copy link
Copy Markdown
Contributor

Summary

  • Adds RcppParallel::isForkedChild() (C++) and isForkedChild() (R), returning TRUE when the current process is a fork() of the process in which RcppParallel (and TBB) was originally loaded.
  • Captures getpid() once in R_init_RcppParallel; the C++ surface is a non-inline function in src/init.cpp, declared in inst/include/RcppParallel/Fork.h (matches the existing tbbParallelFor pattern, resolved at runtime via RTLD_GLOBAL on Linux/macOS, linker-imported on Windows).
  • No-op on Windows (always returns FALSE) since Windows has no fork().

Closes #243.

Why this lives in RcppParallel

Downstream packages can't implement this themselves: RcppParallel may be loaded into the parent process long before the downstream package, so any baseline PID a downstream captures (e.g. in its own static initializer, or .onLoad) can already be a post-fork PID — exactly the false negative reproduced in the issue's library(RcppParallel); mclapply({ library(qs2); ... }) case. The baseline has to be captured by RcppParallel itself.

Suggested usage

#include <RcppParallel.h>

void doWork() {
  if (RcppParallel::isForkedChild()) {
    // serial fallback
    return;
  }
  RcppParallel::parallelFor(...);
}

Test plan

  • R CMD INSTALL succeeds on macOS
  • R: parent returns FALSE; both children in parallel::mclapply(1:2, ...) return TRUE
  • C++: same result via Rcpp::sourceCpp calling RcppParallel::isForkedChild()
  • CI: Linux + Windows builds

closes #243.

tbb does not support being used after fork(). downstream packages can't
reliably detect this themselves because rcppparallel — and therefore tbb —
may have been loaded into the parent long before the downstream package
gets a chance to record a baseline pid.

capture getpid() in R_init_RcppParallel and expose RcppParallel::isForkedChild()
(c++) plus isForkedChild() (r) so callers can fall back to a serial path
when running inside a fork()'d child (e.g. under parallel::mclapply).
windows is a no-op (always false) since it has no fork().
@kevinushey
Copy link
Copy Markdown
Contributor Author

@traversc Let me know if this looks sufficient?

@traversc
Copy link
Copy Markdown
Contributor

Looks good!

You might consider a different function name since it conflicts with parallelly::isForkedChild and has slightly different meaning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: add a check if the process has been forked for TBB safety

2 participants