From a3b19c2a12ba8d304ee64513e660969c68d3839f Mon Sep 17 00:00:00 2001 From: Konstantin Tuev Date: Fri, 5 Mar 2021 12:28:47 +0200 Subject: [PATCH 1/4] Fix concurrent modification of the shared preferences on Android --- .../plugins/sharedpreferences/MethodCallHandlerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java index 4f55d882005f..4486421e3959 100644 --- a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java +++ b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java @@ -23,7 +23,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; -import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -53,7 +53,7 @@ class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { MethodCallHandlerImpl(Context context) { preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); executor = - new ThreadPoolExecutor(0, 1, 30L, TimeUnit.SECONDS, new SynchronousQueue()); + new ThreadPoolExecutor(0, 1, 30L, TimeUnit.SECONDS, new LinkedBlockingQueue()); handler = new Handler(Looper.getMainLooper()); } From fd3d46ca7fb7fd6c636aa966d2cdc7a306a160e5 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 10 Mar 2021 10:28:17 -0500 Subject: [PATCH 2/4] Add a test of many synchronous writes --- .../integration_test/shared_preferences_test.dart | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart index 1caf695d9365..d36286a559b3 100644 --- a/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart @@ -91,5 +91,18 @@ void main() { expect(preferences.getDouble('double'), null); expect(preferences.getStringList('List'), null); }); + + testWidgets('simultaneous writes', (WidgetTester _) async { + final List> writes = >[]; + final int writeCount = 100; + for (int i = 1; i <= writeCount; i++) { + writes.add(preferences.setInt('int', i)); + } + List result = await Future.wait(writes, eagerError: true); + // All writes should succeed. + expect(result.where((element) => !element), isEmpty); + // The last write should win. + expect(preferences.getInt('int'), writeCount); + }); }); } From 14c692ed0a6bc8ac04f1828bf868b5294455819c Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 10 Mar 2021 10:29:15 -0500 Subject: [PATCH 3/4] Version and changelog update --- packages/shared_preferences/shared_preferences/CHANGELOG.md | 4 ++++ .../example/linux/flutter/generated_plugin_registrant.cc | 4 +++- .../example/windows/flutter/generated_plugin_registrant.cc | 4 +++- packages/shared_preferences/shared_preferences/pubspec.yaml | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index 1516163b8807..b0899d57a3c5 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.4 + +* Fix a regression with simultaneous writes on Android. + ## 2.0.3 * Android: don't create additional Handler when method channel is called. diff --git a/packages/shared_preferences/shared_preferences/example/linux/flutter/generated_plugin_registrant.cc b/packages/shared_preferences/shared_preferences/example/linux/flutter/generated_plugin_registrant.cc index 890de29bbab1..d38195aa0412 100644 --- a/packages/shared_preferences/shared_preferences/example/linux/flutter/generated_plugin_registrant.cc +++ b/packages/shared_preferences/shared_preferences/example/linux/flutter/generated_plugin_registrant.cc @@ -4,4 +4,6 @@ #include "generated_plugin_registrant.h" -void fl_register_plugins(FlPluginRegistry* registry) {} + +void fl_register_plugins(FlPluginRegistry* registry) { +} diff --git a/packages/shared_preferences/shared_preferences/example/windows/flutter/generated_plugin_registrant.cc b/packages/shared_preferences/shared_preferences/example/windows/flutter/generated_plugin_registrant.cc index a6177ab0b72b..4bfa0f3a3a75 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/flutter/generated_plugin_registrant.cc +++ b/packages/shared_preferences/shared_preferences/example/windows/flutter/generated_plugin_registrant.cc @@ -4,4 +4,6 @@ #include "generated_plugin_registrant.h" -void RegisterPlugins(flutter::PluginRegistry* registry) {} + +void RegisterPlugins(flutter::PluginRegistry* registry) { +} diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index 899266a4d6f0..b53bbfd93a38 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -2,7 +2,7 @@ name: shared_preferences description: Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences -version: 2.0.3 +version: 2.0.4 flutter: plugin: From 5256b0c96da8fe6b8433a9891426500769a58e8e Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 10 Mar 2021 10:30:06 -0500 Subject: [PATCH 4/4] Revert generated files --- .../example/linux/flutter/generated_plugin_registrant.cc | 4 +--- .../example/windows/flutter/generated_plugin_registrant.cc | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/shared_preferences/shared_preferences/example/linux/flutter/generated_plugin_registrant.cc b/packages/shared_preferences/shared_preferences/example/linux/flutter/generated_plugin_registrant.cc index d38195aa0412..890de29bbab1 100644 --- a/packages/shared_preferences/shared_preferences/example/linux/flutter/generated_plugin_registrant.cc +++ b/packages/shared_preferences/shared_preferences/example/linux/flutter/generated_plugin_registrant.cc @@ -4,6 +4,4 @@ #include "generated_plugin_registrant.h" - -void fl_register_plugins(FlPluginRegistry* registry) { -} +void fl_register_plugins(FlPluginRegistry* registry) {} diff --git a/packages/shared_preferences/shared_preferences/example/windows/flutter/generated_plugin_registrant.cc b/packages/shared_preferences/shared_preferences/example/windows/flutter/generated_plugin_registrant.cc index 4bfa0f3a3a75..a6177ab0b72b 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/flutter/generated_plugin_registrant.cc +++ b/packages/shared_preferences/shared_preferences/example/windows/flutter/generated_plugin_registrant.cc @@ -4,6 +4,4 @@ #include "generated_plugin_registrant.h" - -void RegisterPlugins(flutter::PluginRegistry* registry) { -} +void RegisterPlugins(flutter::PluginRegistry* registry) {}