Skip to content
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

Fix: Add synchronized blocks to prevent ConcurrentModificationException #1876

Merged
merged 8 commits into from
Nov 3, 2023

Conversation

jennantilla
Copy link
Contributor

@jennantilla jennantilla commented Oct 19, 2023

Description

One Line Summary

Add synchronized blocks to prevent ConcurrentModificationException

Details

Motivation

Reports of ConcurrentModificationException occurring in various areas of the SDK:

ModelStore.kt

Model.kt

EventProducer.kt
EventProducer.fire - #1858

Scope

The methods reported in the various stack traces were wrapped in synchronized blocks to make them thread-safe.

Additional blocks may need to be added to other areas of the SDK if additional crashes are reported in the future.

Testing

Manual testing

The exact conditions needed to trigger these exceptions are unclear--the only way I was able to reproduce a similar crash was from some custom code. Adding synchronized blocks to this code prevented the crash from occurring on Pixel 7 emulator running Android 33. If reproduction steps can be verified, eventual unit tests may be added in the future to help check for these exceptions.

Affected code checklist

  • Notifications
    • Display
    • Open
    • Push Processing
    • Confirm Deliveries
  • Outcomes
  • Sessions
  • In-App Messaging
  • REST API requests
  • Public API changes

Checklist

Overview

  • I have filled out all REQUIRED sections above
  • PR does one thing
    • If it is hard to explain how any codes changes are related to each other then it most likely needs to be more than one PR
  • Any Public API changes are explained in the PR details and conform to existing APIs

Testing

  • I have included test coverage for these changes, or explained why they are not needed
  • All automated tests pass, or I explained why that is not possible
  • I have personally tested this on my device, or explained why that is not possible

Final pass

  • Code is as readable as possible.
    • Simplify with less code, followed by splitting up code into well named functions and variables, followed by adding comments to the code.
  • I have reviewed this PR myself, ensuring it meets each checklist item
    • WIP (Work In Progress) is ok, but explain what is still in progress and what you would like feedback on. Start the PR title with "WIP" to indicate this.

This change is Reviewable

@arthurgeron-work
Copy link

Thank you for digging into this issue

@jennantilla jennantilla changed the title Fix: Add synchronization blocks to prevent ConcurrentModificationException Fix: Add synchronized blocks to prevent ConcurrentModificationException Oct 23, 2023
Copy link
Contributor

@emawby emawby left a comment

Choose a reason for hiding this comment

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

Lets try using the @synchronized class/function annotations to make this read more cleanly.

@nan-li
Copy link
Contributor

nan-li commented Oct 31, 2023

Lets try using the @synchronized class/function annotations to make this read more cleanly.

@synchronized methods protect methods only and allow one thread to execute a particular method at a time, but different methods can execute at the same time. So it would not be for our purposes. I think we still have to use synchronized blocks... unless the class has only 1 method that we require synchronization in..

@emawby emawby self-requested a review October 31, 2023 20:07
ensure additional thread safety in SingletonModelStore
@jennantilla
Copy link
Contributor Author

@brismithers some additions here based on your analysis in Asana, if you wouldn't mind taking a quick look to ensure I got it all!

@brismithers
Copy link
Contributor

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/common/modeling/Model.kt line 125 at r2 (raw file):

     */
    fun initializeFromModel(id: String?, model: Model) {
        synchronized(initializationLock) {

I believe the data.clear() is needed, if the incoming model doesn't have a particular property set the current model will not have that property removed. I wonder if it might be safer to build up a local MutableMap then at the end replace data with the new instance?

@brismithers
Copy link
Contributor

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/common/modeling/Model.kt line 127 at r3 (raw file):

        model: Model,
    ) {
        val newData = Collections.synchronizedMap(mutableMapOf<String, Any?>())

nit: this doesn't need to by synchronized since it is only used by this method as a local variable.

Copy link
Contributor Author

@jennantilla jennantilla left a comment

Choose a reason for hiding this comment

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

Reviewable status: 0 of 4 files reviewed, 1 unresolved discussion (waiting on @brismithers, @emawby, @jkasten2, @nan-li, and @shepherd-l)


OneSignalSDK/onesignal/core/src/main/java/com/onesignal/common/modeling/Model.kt line 125 at r2 (raw file):

Previously, brismithers (Brian Smith) wrote…

I believe the data.clear() is needed, if the incoming model doesn't have a particular property set the current model will not have that property removed. I wonder if it might be safer to build up a local MutableMap then at the end replace data with the new instance?

Done.

@jennantilla jennantilla merged commit d8abaee into user-model/main Nov 3, 2023
1 of 3 checks passed
@jennantilla jennantilla deleted the fix/concurrent_modification_exception branch November 3, 2023 21:49
@jennantilla jennantilla mentioned this pull request Nov 3, 2023
jinliu9508 pushed a commit that referenced this pull request Jan 31, 2024
…xception

Fix: Add synchronized blocks to prevent ConcurrentModificationException
jinliu9508 pushed a commit that referenced this pull request Jan 31, 2024
…xception

Fix: Add synchronized blocks to prevent ConcurrentModificationException
jinliu9508 pushed a commit that referenced this pull request Feb 6, 2024
…xception

Fix: Add synchronized blocks to prevent ConcurrentModificationException
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.

None yet

5 participants