Skip to content

Lock the shared sets of the parallel STEP import - #499

Merged
dsn27 merged 1 commit into
masterfrom
fix/step-parallel-shared-sets
Oct 19, 2026
Merged

dsn27 merged 1 commit into
masterfrom
fix/step-parallel-shared-sets

Conversation

@dsn27

@dsn27 dsn27 commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator

Fixes an intermittent failure of StepCyclicReferenceTest.import_step_with_representations_that_map_each_other, a test from #498. The test failed now and then on the 2-core CI runner, on #468 and #472 so far:

System.NullReferenceException: Object reference not set to an instance of an object.
   at CADability.ImportStep.Read(String filename) in /_/CADability/ImportStep.cs:line 1683

Cause

With StepImport.Parallel, CreateEntity runs on several threads. Two places in it added to a shared HashSet<Item> without a lock:

  • mappedItems.Add(item) for every MAPPED_ITEM;
  • products.Add(relatingProduct) for assemblies. The other place that adds products already uses lock (products).

Concurrent Add calls can corrupt a HashSet. When Read later enumerates mappedItems (line 1683), it meets a null entry. The bug is older than #498. The new test makes it visible, because it imports a file with mapped items 20 times in parallel.

Fix

Both Add calls now run under a lock on their set, as the existing lock (products) does.

Verification

I limited the test process to 2 cores with taskset -c 0,1, as on the runner:

runs failed
without the fix 30 3
with the fix 60 0

CADability.ImportTests on Linux: 85 passed, 5 skipped, 0 failed.

Not covered here

The assembly branch of the parallel import changes other shared state without a lock: the parameter dictionary of a product ("_children") and the list of its children. That is a separate, pre-existing issue, and no test shows it, so this PR leaves it as it is.


Generated by Claude Code

With StepImport.Parallel, CreateEntity runs on several threads, but it added
mapped items to the HashSet mappedItems and, for assemblies, products to the
HashSet products without a lock (the other place that adds products locks
it). Concurrent Add calls can corrupt a HashSet, and the enumeration of
mappedItems after the creation then met a null entry: a
NullReferenceException in ImportStep.Read.

StepCyclicReferenceTest from #498 imports a file with mapped items 20 times
in parallel and showed this now and then on the 2-core CI runner. With the
test process limited to 2 cores, it failed 3 of 30 times without this change
and 0 of 60 times with it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YXvDW91oXpy7RquGHNxgR5
@dsn27
dsn27 merged commit de69410 into master Oct 19, 2026
2 checks passed
@dsn27
dsn27 deleted the fix/step-parallel-shared-sets branch October 19, 2026 08:37
@dsn27 dsn27 mentioned this pull request Oct 19, 2026
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.

2 participants