-
Notifications
You must be signed in to change notification settings - Fork 841
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Field eventsToDeliver is a LinkedList, i.e., not thread-safe. Accesses to field eventsToDeliver are protected by synchronization on itself, but not in 1 location. #1971
Conversation
…s to field eventsToDeliver are protected by synchronization on itself, but not in 1 location.
Codecov Report
@@ Coverage Diff @@
## master #1971 +/- ##
============================================
+ Coverage 76.63% 76.64% +0.01%
Complexity 225 225
============================================
Files 1112 1112
Lines 33646 33586 -60
Branches 2606 2598 -8
============================================
- Hits 25783 25742 -41
+ Misses 6584 6563 -21
- Partials 1279 1281 +2
Flags with carried forward coverage won't be shown. Click here to find out more. Continue to review full report at Codecov.
|
Kudos, SonarCloud Quality Gate passed! 0 Bugs 100.0% Coverage The version of Java (1.8.0_252) you have used to run this analysis is deprecated and we will stop accepting it from October 2020. Please update to at least Java 11. |
Reviewing this. It looks like it shouldn't happen today, but that doesn't mean it shouldn't happen in the future. Should we also guard line 271 (a eventsToDeliver.add) with a synchronized block? Can we also amend the release note to specify it's a "future race condition risk", since it's not a race condition today? |
Comments above are minor, so I'll probably just merge it as-is since it seems like the customer might not have time to get back on this issue. |
We might need to update the changelog entry to add the |
Kudos, SonarCloud Quality Gate passed! 0 Bugs |
…1d62f0f6a Pull request: release <- staging/39b5da9e-12d6-48f4-9c40-be41d62f0f6a
I also reported this at:
#1972
Description
Field
eventsToDeliver
is aLinkedList
(line 128), i.e., not thread-safe.Accesses to
eventsToDeliver
are protected by synchronization on itself (synchronized (eventsToDeliver)
), e.g., at lines: 373-376, 424-426, 493-494, 493-498, and 493-506.Note that line 506 (a
remove()
) and line 374 (decoder
callshandleMessage()
as perdecoder
's definition at line 110, andhandleMessage()
callsadd()
at line 271) modify theeventsToDeliver
(and are protected by synchronization at line 493 and line 373 respectively).However, line 397 (an
add()
, i.e., modifieseventsToDeliver
) is not protected.I see line 397 adds a
ON_COMPLETE_EVENT
, which, when processed in theeventsToDeliver
, will signal termination (inisCompletedOrDeliverEvent()
at line 494).However, I think the
add()
at line 397 can occur in parallel with theremove()
at line 506. This is because theremove()
at line 506 occurs for other messages in theeventsToDeliver
that were already enqueued before theON_COMPLETE_EVENT
.I.e., when
ON_COMPLETE_EVENT
is being added by line 397 other messages may still be getting processed from theeventsToDeliver
queue.Note how
isCompletedOrDeliverEvent()
is getting called (by itself, recursively) at lines 505-509 untileventsToDeliver
becomes empty (line 498) orON_COMPLETE_EVENT
is encountered (line 494).Note also how the recursive calls at lines 505-509 are asynchronous (which is likely part of the reason for which we have the synchronization).
Even if somehow we know that there is a guarantee that all calls to line 506 were finished before line 397 is called (seems unlikely, with all those asynchronous calls above---also, if we could enforce such a guarantee, we may have better ways to communicate completion than to enqueue
ON_COMPLETE_EVENT
in the sharedeventsToDeliver
queue), it still seems like a fragile guarantee to make, because external callers may not be aware of it (e.g., it is not documented) or about other timing assumptions.This Fix Code
This fix is very simple: just surround the
add()
at line 397 with asynchronized (eventsToDeliver)
, just like the other lines discussed above (373-376, 424-426, 493-494, 493-498, and 493-506).Testing
mvn clean install
Types of changes
Checklist
mvn install
succeedsLicense