diff --git a/docs/release-notes.md b/docs/release-notes.md
index 2e1e050e..2ff4ec0a 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -10,6 +10,7 @@
## Upcoming release
* For players:
* Fixed rare error when a mod adds/removes event handlers asynchronously.
+ * Removed the experimental `RewriteInParallel` option added in SMAPI 3.6 (it was already disabled by default). Unfortunately this caused intermittent unpredictable errors when enabled.
* For modders:
* You can now read/write `SDate` values to JSON (e.g. for `config.json`, network mod messages, etc).
diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
index f8c901e0..dbb5f696 100644
--- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
+++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
@@ -76,10 +76,9 @@ namespace StardewModdingAPI.Framework.ModLoading
/// The mod for which the assembly is being loaded.
/// The assembly file path.
/// Assume the mod is compatible, even if incompatible code is detected.
- /// Whether to enable experimental parallel rewriting.
/// Returns the rewrite metadata for the preprocessed assembly.
/// An incompatible CIL instruction was found while rewriting the assembly.
- public Assembly Load(IModMetadata mod, string assemblyPath, bool assumeCompatible, bool rewriteInParallel)
+ public Assembly Load(IModMetadata mod, string assemblyPath, bool assumeCompatible)
{
// get referenced local assemblies
AssemblyParseResult[] assemblies;
@@ -109,7 +108,7 @@ namespace StardewModdingAPI.Framework.ModLoading
continue;
// rewrite assembly
- bool changed = this.RewriteAssembly(mod, assembly.Definition, loggedMessages, logPrefix: " ", rewriteInParallel);
+ bool changed = this.RewriteAssembly(mod, assembly.Definition, loggedMessages, logPrefix: " ");
// detect broken assembly reference
foreach (AssemblyNameReference reference in assembly.Definition.MainModule.AssemblyReferences)
@@ -263,10 +262,9 @@ namespace StardewModdingAPI.Framework.ModLoading
/// The assembly to rewrite.
/// The messages that have already been logged for this mod.
/// A string to prefix to log messages.
- /// Whether to enable experimental parallel rewriting.
/// Returns whether the assembly was modified.
/// An incompatible CIL instruction was found while rewriting the assembly.
- private bool RewriteAssembly(IModMetadata mod, AssemblyDefinition assembly, HashSet loggedMessages, string logPrefix, bool rewriteInParallel)
+ private bool RewriteAssembly(IModMetadata mod, AssemblyDefinition assembly, HashSet loggedMessages, string logPrefix)
{
ModuleDefinition module = assembly.MainModule;
string filename = $"{assembly.Name.Name}.dll";
@@ -315,7 +313,7 @@ namespace StardewModdingAPI.Framework.ModLoading
return rewritten;
}
);
- bool anyRewritten = rewriter.RewriteModule(rewriteInParallel);
+ bool anyRewritten = rewriter.RewriteModule();
// handle rewrite flags
foreach (IInstructionHandler handler in handlers)
diff --git a/src/SMAPI/Framework/ModLoading/Framework/RecursiveRewriter.cs b/src/SMAPI/Framework/ModLoading/Framework/RecursiveRewriter.cs
index 34c78c7d..fb651465 100644
--- a/src/SMAPI/Framework/ModLoading/Framework/RecursiveRewriter.cs
+++ b/src/SMAPI/Framework/ModLoading/Framework/RecursiveRewriter.cs
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
@@ -57,59 +55,24 @@ namespace StardewModdingAPI.Framework.ModLoading.Framework
}
/// Rewrite the loaded module code.
- /// Whether to enable experimental parallel rewriting.
/// Returns whether the module was modified.
- public bool RewriteModule(bool rewriteInParallel)
+ public bool RewriteModule()
{
IEnumerable types = this.Module.GetTypes().Where(type => type.BaseType != null); // skip special types like
- // experimental parallel rewriting
- // This may cause intermittent startup errors and is disabled by default: https://github.com/Pathoschild/SMAPI/issues/721
- if (rewriteInParallel)
+ bool changed = false;
+
+ try
{
- int typesChanged = 0;
- Exception exception = null;
-
- Parallel.ForEach(types, type =>
- {
- if (exception != null)
- return;
-
- bool changed = false;
- try
- {
- changed = this.RewriteTypeDefinition(type);
- }
- catch (Exception ex)
- {
- exception ??= ex;
- }
-
- if (changed)
- Interlocked.Increment(ref typesChanged);
- });
-
- return exception == null
- ? typesChanged > 0
- : throw new Exception($"Rewriting {this.Module.Name} failed.", exception);
+ foreach (var type in types)
+ changed |= this.RewriteTypeDefinition(type);
+ }
+ catch (Exception ex)
+ {
+ throw new Exception($"Rewriting {this.Module.Name} failed.", ex);
}
- // non-parallel rewriting
- {
- bool changed = false;
-
- try
- {
- foreach (var type in types)
- changed |= this.RewriteTypeDefinition(type);
- }
- catch (Exception ex)
- {
- throw new Exception($"Rewriting {this.Module.Name} failed.", ex);
- }
-
- return changed;
- }
+ return changed;
}
diff --git a/src/SMAPI/Framework/Models/SConfig.cs b/src/SMAPI/Framework/Models/SConfig.cs
index 1c682f96..3a3f6960 100644
--- a/src/SMAPI/Framework/Models/SConfig.cs
+++ b/src/SMAPI/Framework/Models/SConfig.cs
@@ -16,7 +16,6 @@ namespace StardewModdingAPI.Framework.Models
{
[nameof(CheckForUpdates)] = true,
[nameof(ParanoidWarnings)] = Constants.IsDebugBuild,
- [nameof(RewriteInParallel)] = Constants.IsDebugBuild,
[nameof(UseBetaChannel)] = Constants.ApiVersion.IsPrerelease(),
[nameof(GitHubProjectName)] = "Pathoschild/SMAPI",
[nameof(WebApiBaseUrl)] = "https://smapi.io/api/",
@@ -41,9 +40,6 @@ namespace StardewModdingAPI.Framework.Models
/// Whether to check for newer versions of SMAPI and mods on startup.
public bool CheckForUpdates { get; set; }
- /// Whether to enable experimental parallel rewriting.
- public bool RewriteInParallel { get; set; } = (bool)SConfig.DefaultValues[nameof(SConfig.RewriteInParallel)];
-
/// Whether to add a section to the 'mod issues' list for mods which which directly use potentially sensitive .NET APIs like file or shell access.
public bool ParanoidWarnings { get; set; } = (bool)SConfig.DefaultValues[nameof(SConfig.ParanoidWarnings)];
diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs
index 72ef9095..fd8d7034 100644
--- a/src/SMAPI/Framework/SCore.cs
+++ b/src/SMAPI/Framework/SCore.cs
@@ -337,8 +337,6 @@ namespace StardewModdingAPI.Framework
// add headers
if (this.Settings.DeveloperMode)
this.Monitor.Log($"You have SMAPI for developers, so the console will be much more verbose. You can disable developer mode by installing the non-developer version of SMAPI, or by editing {Constants.ApiConfigPath}.", LogLevel.Info);
- if (this.Settings.RewriteInParallel)
- this.Monitor.Log($"You enabled experimental parallel rewriting. This may result in faster startup times, but intermittent startup errors. You can disable it by reinstalling SMAPI or editing {Constants.ApiConfigPath}.", LogLevel.Info);
if (!this.Settings.CheckForUpdates)
this.Monitor.Log($"You configured SMAPI to not check for updates. Running an old version of SMAPI is not recommended. You can enable update checks by reinstalling SMAPI or editing {Constants.ApiConfigPath}.", LogLevel.Warn);
if (!this.Monitor.WriteToConsole)
@@ -983,7 +981,7 @@ namespace StardewModdingAPI.Framework
Assembly modAssembly;
try
{
- modAssembly = assemblyLoader.Load(mod, assemblyPath, assumeCompatible: mod.DataRecord?.Status == ModStatus.AssumeCompatible, rewriteInParallel: this.Settings.RewriteInParallel);
+ modAssembly = assemblyLoader.Load(mod, assemblyPath, assumeCompatible: mod.DataRecord?.Status == ModStatus.AssumeCompatible);
this.ModRegistry.TrackAssemblies(mod, modAssembly);
}
catch (IncompatibleInstructionException) // details already in trace logs
diff --git a/src/SMAPI/SMAPI.config.json b/src/SMAPI/SMAPI.config.json
index 0a6d8372..6ba64fe7 100644
--- a/src/SMAPI/SMAPI.config.json
+++ b/src/SMAPI/SMAPI.config.json
@@ -33,15 +33,6 @@ copy all the settings, or you may cause bugs due to overridden changes in future
*/
"DeveloperMode": true,
- /**
- * Whether to enable experimental parallel rewriting when SMAPI is loading mods. This can
- * reduce startup time when you have many mods installed, but is experimental and may cause
- * intermittent startup errors.
- *
- * When this is commented out, it'll be true for local debug builds and false otherwise.
- */
- //"RewriteInParallel": false,
-
/**
* Whether to add a section to the 'mod issues' list for mods which directly use potentially
* sensitive .NET APIs like file or shell access. Note that many mods do this legitimately as