Skip to content

GH-50239: [R] Data race issue from R API requests in parallel region - #50488

Merged
thisisnic merged 1 commit into
apache:mainfrom
thisisnic:GH-50239-raceconditions
Sep 6, 2026
Merged

thisisnic merged 1 commit into
apache:mainfrom
thisisnic:GH-50239-raceconditions

Conversation

@thisisnic

@thisisnic thisisnic commented Jul 13, 2026 •

Copy link
Copy Markdown
Member

Rationale for this change

When use_threads = TRUE, parallel tasks are submitted to the thread pool immediately during RTasks::Append(). This means worker threads start reading R vector headers (via INTEGER(), REAL(), etc.) while the main thread is still assigning vectors into the output list via SET_VECTOR_ELT, which writes to the same header memory. ThreadSanitizer detects this as a data race.

What changes are included in this PR?

Delay submission of parallel tasks until RTasks::Finish(), matching the existing pattern for serial tasks. All R-side allocations and list assignments complete on the main thread before any worker threads start.

Are these changes tested?

Existing tests cover the affected code path.
I also ran some local benchmarks to see if this change affected performance, but seems fine.

Are there any user-facing changes?

No.

@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #50239 has been automatically assigned in GitHub to PR creator.

@thisisnic
thisisnic marked this pull request as ready for review July 13, 2026 08:40
@thisisnic
thisisnic requested a review from jonkeane as a code owner July 13, 2026 08:40
Copilot AI lite review requested due to automatic review settings July 13, 2026 08:41
@thisisnic

Copy link
Copy Markdown
Member Author

@ursabot please benchmark

@rok

rok commented Jul 13, 2026

Copy link
Copy Markdown
Member

Benchmark runs are scheduled for commit 824f648. Watch https://buildkite.com/apache-arrow and https://conbench.arrow-dev.org for updates. A comment will be posted here when the runs are complete.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a ThreadSanitizer-detected data race in the R bindings when use_threads = TRUE by preventing worker threads from touching R vectors until after all R-side allocations and list assignments are complete on the main thread.

Changes:

  • Delay scheduling of parallel RTasks work until RTasks::Finish() instead of submitting immediately in RTasks::Append().
  • Add storage for delayed parallel tasks and ensure it is cleared on Reset().

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
r/src/RTasks.cpp Queues parallel tasks in Append(), then submits them in Finish() after serial work completes; clears the new queue in Reset().
r/src/r_task_group.h Adds delayed_parallel_tasks_ to hold parallel tasks until Finish().

@conbench-apache-arrow

Copy link
Copy Markdown

Thanks for your patience. Conbench analyzed the 4 benchmarking runs that have been run so far on PR commit 824f648.

There were 7 benchmark results indicating a performance regression:

The full Conbench report has more details.

Copilot AI review requested due to automatic review settings August 18, 2026 12:11
@thisisnic
thisisnic force-pushed the GH-50239-raceconditions branch from 824f648 to d95aab3 Compare August 18, 2026 12:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (1)

r/src/RTasks.cpp:49

  • RTasks::Finish() will submit delayed parallel tasks even after a delayed serial task has failed (and stop has been requested). Since parallel tasks are now delayed, it’s safer to skip submission/Finish on the error path. Also consider clearing delayed_parallel_tasks_ after moving tasks so a second Finish() call can’t try to append moved-from tasks.
  if (use_threads_) {
    for (auto& task : delayed_parallel_tasks_) {
      parallel_tasks_->Append(std::move(task));
    }
    status &= parallel_tasks_->Finish();

@jonkeane

Copy link
Copy Markdown
Member

I'm fine with the changes here, but:

(1) I assume there aren't any regressions in the conbench data? But I haven't checked myself.

(2) Do you know why these workflows are awaiting approval??? I know that this happens with new contributors, but ... you're ... definitely not!

image

@rok

rok commented Aug 25, 2026

Copy link
Copy Markdown
Member

(2) Do you know why these workflows are awaiting approval??? I know that this happens with new contributors, but ... you're ... definitely not!

It's happening with everyone lately but noones been bothered enough yet.

@thisisnic

thisisnic commented Sep 6, 2026 •

Copy link
Copy Markdown
Member Author

Best I can assume is that those regressions above are existing ones given they're for the C++ benchmarks. I ran a few tests locally and is all good.

And the approval thing is to do with Copilot not being a committer and so some label runs won't trigger.

@thisisnic
thisisnic merged commit 4da2a7e into apache:main Sep 6, 2026
34 checks passed
@thisisnic thisisnic removed the awaiting committer review Awaiting committer review label Sep 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants