|
16 | 16 | using Xamarin.Android.Tools;
|
17 | 17 | using Microsoft.Android.Build.Tasks;
|
18 | 18 | using Java.Interop.Tools.JavaCallableWrappers.Adapters;
|
| 19 | +using System.Threading.Tasks; |
| 20 | +using System.Collections.Concurrent; |
19 | 21 |
|
20 | 22 | namespace Xamarin.Android.Tasks
|
21 | 23 | {
|
@@ -183,26 +185,38 @@ void Run (bool useMarshalMethods)
|
183 | 185 | }
|
184 | 186 |
|
185 | 187 | // Now that "never" never happened, we can proceed knowing that at least the assembly sets are the same for each architecture
|
186 |
| - var nativeCodeGenStates = new Dictionary<AndroidTargetArch, NativeCodeGenState> (); |
187 |
| - bool generateJavaCode = true; |
| 188 | + var nativeCodeGenStates = new ConcurrentDictionary<AndroidTargetArch, NativeCodeGenState> (); |
188 | 189 | NativeCodeGenState? templateCodeGenState = null;
|
189 | 190 |
|
190 |
| - foreach (var kvp in allAssembliesPerArch) { |
| 191 | + var firstArch = allAssembliesPerArch.First ().Key; |
| 192 | + var generateSucceeded = true; |
| 193 | + |
| 194 | + // Generate Java sources in parallel |
| 195 | + Parallel.ForEach (allAssembliesPerArch, (kvp) => { |
191 | 196 | AndroidTargetArch arch = kvp.Key;
|
192 | 197 | Dictionary<string, ITaskItem> archAssemblies = kvp.Value;
|
| 198 | + |
| 199 | + // We only need to generate Java code for one ABI, as the Java code is ABI-agnostic |
| 200 | + // Pick the "first" one as the one to generate Java code for |
| 201 | + var generateJavaCode = arch == firstArch; |
| 202 | + |
193 | 203 | (bool success, NativeCodeGenState? state) = GenerateJavaSourcesAndMaybeClassifyMarshalMethods (arch, archAssemblies, MaybeGetArchAssemblies (userAssembliesPerArch, arch), useMarshalMethods, generateJavaCode);
|
194 | 204 |
|
195 | 205 | if (!success) {
|
196 |
| - return; |
| 206 | + generateSucceeded = false; |
197 | 207 | }
|
198 | 208 |
|
| 209 | + // If this is the first architecture, we need to store the state for later use |
199 | 210 | if (generateJavaCode) {
|
200 | 211 | templateCodeGenState = state;
|
201 |
| - generateJavaCode = false; |
202 | 212 | }
|
203 | 213 |
|
204 |
| - nativeCodeGenStates.Add (arch, state); |
205 |
| - } |
| 214 | + nativeCodeGenStates.TryAdd (arch, state); |
| 215 | + }); |
| 216 | + |
| 217 | + // If we hit an error generating the Java code, we should bail out now |
| 218 | + if (!generateSucceeded) |
| 219 | + return; |
206 | 220 |
|
207 | 221 | if (templateCodeGenState == null) {
|
208 | 222 | throw new InvalidOperationException ($"Internal error: no native code generator state defined");
|
|
0 commit comments