Skip to content

Conversation

mehmet-karaman
Copy link
Contributor

@mehmet-karaman mehmet-karaman commented Oct 13, 2025

  • This PR will fix multithreading issues described in Sporadically thrown NPE and NSEE during issue processing after validation. eclipse-xtext/xtext#3524
  • added synchronize block to methods in AnnotationModel, wherever reads / writes could happen in multiple threads.
  • changed execution order, to be able to synchronize only necessary code blocks.
  • Removed dead code in AnnotationModel.cleanup because mapLock can't be null.
  • Added new javadoc to IAnnotationMap.getLockObject().
  • added assert.isLegal check to AnnotationMAp.setLockObject()

@laeubi
Copy link
Contributor

laeubi commented Oct 13, 2025

@mehmet-karaman can you please more explain the rationale behind the changes? I think we can assume code is there for a reason so if we change fundamental things we should carefully describe the reasons and causes and why it is not a bug of the caller for example as otherwise we might run into deadlocks if code that previously run outside locks now run under lock conditions.

@iloveeclipse
Copy link
Member

The change here is coming from eclipse-xtext/xtext#3524 investigation.

@iloveeclipse
Copy link
Member

@szarnekow : if you have time, would be good if you could check this PR.

@laeubi
Copy link
Contributor

laeubi commented Oct 13, 2025

It still would be good to more explain the individual changes and why they are required / needed. Also I think some changes are better a separate PR (as they are easier to review then e.g. "Removed dead code" or API documentation enhancements)

@iloveeclipse
Copy link
Member

Also I think some changes are better a separate PR

Could you please point which exactly?

@laeubi
Copy link
Contributor

laeubi commented Oct 13, 2025

Each of those can be an own PR

  • Removed dead code in AnnotationModel.cleanup because mapLock can't be null.
  • Added new javadoc to IAnnotationMap.getLockObject()
  • added assert.isLegal check to AnnotationMAp.setLockObject()

All of these seem independent and local enough to be quickly reviewed and merged and likely will improve things without risk for regression. And even if they are easier to revert in isolation.

Then might be the next thing

  • changed execution order, to be able to synchronize only necessary code blocks.

and finally

  • added synchronize block to methods in AnnotationModel, wherever reads / writes could happen in multiple threads.

This will make each PR small, focused and likely better to understand the implications and its easier to write a concise commit message.

@iloveeclipse
Copy link
Member

Each of those can be an own PR

  • Removed dead code in AnnotationModel.cleanup because mapLock can't be null.
  • Added new javadoc to IAnnotationMap.getLockObject()
  • added assert.isLegal check to AnnotationMAp.setLockObject()

I believe these could be seperated from the main PR, but should go in one PR, because they all require each other.

@laeubi
Copy link
Contributor

laeubi commented Oct 13, 2025

I believe these could be seperated from the main PR, but should go in one PR, because they all require each other.

Sure at laest I think these are more "cleanup" and currently make the PR harder to review than it should.

Copy link
Contributor

github-actions bot commented Oct 13, 2025

Test Results

 3 018 files  ±0   3 018 suites  ±0   2h 28m 55s ⏱️ + 7m 28s
 8 226 tests ±0   7 976 ✅  - 1  249 💤 ±0  1 ❌ +1 
23 598 runs  ±0  22 803 ✅  - 1  794 💤 ±0  1 ❌ +1 

For more details on these failures, see this check.

Results for commit 5fa4d84. ± Comparison against base commit 554e227.

♻️ This comment has been updated with latest results.

@iloveeclipse iloveeclipse force-pushed the fix_multithreading_problems_in_annotations branch 2 times, most recently from 34fc4f0 to 4082003 Compare October 16, 2025 15:43
@iloveeclipse
Copy link
Member

I've rebased on #3399 state, fixed merge conflicts & my own comment above.

@iloveeclipse iloveeclipse enabled auto-merge (rebase) October 16, 2025 16:36
@iloveeclipse iloveeclipse disabled auto-merge October 16, 2025 16:39
@iloveeclipse iloveeclipse force-pushed the fix_multithreading_problems_in_annotations branch 2 times, most recently from f3ef6e9 to e5d2191 Compare October 17, 2025 07:43
@iloveeclipse
Copy link
Member

Test failures on Windows are unrelated.

@mehmet-karaman, @laeubi : please feel free to review.

Copy link
Contributor

@laeubi laeubi left a comment

Choose a reason for hiding this comment

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

It looks ok in general but I have not testes it.

@mehmet-karaman mehmet-karaman force-pushed the fix_multithreading_problems_in_annotations branch from e5d2191 to 703a1ad Compare October 20, 2025 07:23
@mehmet-karaman
Copy link
Contributor Author

mehmet-karaman commented Oct 20, 2025

Resolved two remaining comments and rebased on latest master.

@iloveeclipse
Copy link
Member

@mehmet-karaman : you have now two commits, I assume by mistake. Can you please have one?

- added synchronize block to methods in AnnotationModel, wherever reads
/ writes could happen in multiple threads.
- changed execution order, to be able to synchronize only necessary code
blocks.

Co-authored-by: Andrey Loskutov <loskutov@gmx.de>
@mehmet-karaman mehmet-karaman force-pushed the fix_multithreading_problems_in_annotations branch from 703a1ad to 5fa4d84 Compare October 20, 2025 07:42
@mehmet-karaman
Copy link
Contributor Author

squashed the two commits.

@laeubi laeubi requested a review from Copilot October 20, 2025 08:08
Copy link

@Copilot Copilot AI left a comment

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 multithreading issues in the AnnotationModel class by adding proper synchronization to prevent race conditions during concurrent access to annotation data. The changes ensure thread safety while maintaining performance by minimizing the scope of synchronized blocks.

Key changes:

  • Added synchronized blocks around critical sections that access shared data structures
  • Reorganized execution order to minimize time spent in synchronized blocks
  • Removed dead code and added validation checks

if (fireModelChanged && forkNotification) {
removeAnnotations(deleted, false, false);
synchronized (getLockObject()) {
synchronized (mapLock) {
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

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

Using 'mapLock' directly instead of 'getLockObject()' is inconsistent with the synchronization pattern used throughout the rest of the class. This should use 'getLockObject()' for consistency and to ensure the same lock object is used.

Suggested change
synchronized (mapLock) {
synchronized (annotations.getLockObject()) {

Copilot uses AI. Check for mistakes.

IDocument document= fDocument;
if (document != null) {
for (int i= 0; i < fOpenConnections; i++) {
ret.disconnect(fDocument);
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

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

Using 'fDocument' instead of the local 'document' variable creates a potential race condition. The local 'document' variable was captured to avoid accessing the field multiple times, but this line still uses the field directly.

Suggested change
ret.disconnect(fDocument);
ret.disconnect(document);

Copilot uses AI. Check for mistakes.

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.

4 participants