Skip to content

Commit b1667a2

Browse files
committed
[jcw-gen] DON'T generate Java Callable Wrappers in parallel
Partially reverst commit f0fa3c3. The problem with f0fa3c3 is that Mono.Cecil follows the normal .NET guidelines with respect to thread safety: static members are thread-safe, but *instance members are not thread safe*. Meaning accessing e.g. `TypeDefinition.Methods` isn't thread-safe. Attempting to generate Java Callable Wrappers in parallel can result in "bizarre" Javav code wherein not all Java members which should be overridden are actually overidden, presumably because the TypeDefinition of the type, some base type, or some implemented interface, is being used concurrently from multiple threads. Revert the Task use from commit f0fa3c3 and generate Java Callable Wrappers sequentially, so that they're valid.
1 parent 9c3e743 commit b1667a2

File tree

2 files changed

+5
-67
lines changed

2 files changed

+5
-67
lines changed

src/Java.Interop.Tools.JavaCallableWrappers/Test/Java.Interop.Tools.JavaCallableWrappers/JavaCallableWrapperGeneratorTests.cs

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -30,69 +30,6 @@ public void ConstructorExceptions ()
3030
Assert.AreEqual (4200, e.Code);
3131
}
3232

33-
[Test]
34-
public void GenerateInParallel ()
35-
{
36-
var assemblyDef = AssemblyDefinition.ReadAssembly (typeof (DefaultName).Assembly.Location);
37-
var types = new []{
38-
typeof (AbstractClassInvoker),
39-
typeof (AbstractClass),
40-
typeof (ActivityName),
41-
typeof (ApplicationName),
42-
typeof (DefaultName),
43-
typeof (DefaultName.A),
44-
typeof (DefaultName.A.B),
45-
typeof (DefaultName.C.D),
46-
// Skip because this will produce nested types
47-
// typeof (ExampleOuterClass),
48-
// typeof (ExampleOuterClass.ExampleInnerClass),
49-
typeof (InstrumentationName),
50-
// Skip because this will produce nested types
51-
// typeof (NonStaticOuterClass),
52-
// typeof (NonStaticOuterClass.NonStaticInnerClass),
53-
typeof (ProviderName),
54-
typeof (ReceiverName),
55-
typeof (RegisterName),
56-
typeof (RegisterName.DefaultNestedName),
57-
typeof (RegisterName.OverrideNestedName),
58-
typeof (ServiceName),
59-
};
60-
var typeDefs = types.Select (t => SupportDeclarations.GetTypeDefinition (t, assemblyDef))
61-
.ToList ();
62-
63-
var tasks = typeDefs.Select (type => Task.Run (() => {
64-
var g = new JavaCallableWrapperGenerator (type, log: Console.WriteLine);
65-
var o = new StringWriter ();
66-
g.Generate (o);
67-
var r = new StringReader (o.ToString ());
68-
var l = r.ReadLine ();
69-
if (!l.StartsWith ("package ", StringComparison.Ordinal))
70-
throw new InvalidOperationException ($"Invalid JCW for {type.FullName}!");
71-
var p = l.Substring ("package ".Length);
72-
p = p.Substring (0, p.Length - 1);
73-
l = r.ReadLine ();
74-
if (l.Length != 0)
75-
throw new InvalidOperationException ($"Invalid JCW for {type.FullName}! (Missing newline)");
76-
l = r.ReadLine ();
77-
if (l.Length != 0)
78-
throw new InvalidOperationException ($"Invalid JCW for {type.FullName}! (Missing 2nd newline)");
79-
l = r.ReadLine ();
80-
string c = null;
81-
if (l.StartsWith ("public class ", StringComparison.Ordinal))
82-
c = l.Substring ("public class ".Length);
83-
else if (l.StartsWith ("public abstract class ", StringComparison.Ordinal))
84-
c = l.Substring ("public abstract class ".Length);
85-
else
86-
throw new InvalidOperationException ($"Invalid JCW for {type.FullName}! (Missing class)");
87-
return p + "/" + c;
88-
})).ToArray ();
89-
Task.WaitAll (tasks);
90-
for (int i = 0; i < types.Length; ++i) {
91-
Assert.AreEqual (JniType.ToJniName (typeDefs [i]), tasks [i].Result);
92-
Assert.AreEqual (JniType.ToJniName (types [i]), tasks [i].Result);
93-
}
94-
}
95-
9633
[Test]
9734
public void GenerateApplication (
9835
[Values (null, "android.app.Application", "android.support.multidex.MultiDexApplication")] string applicationJavaClass

tools/jcw-gen/App.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,11 @@ public static int Main (string [] args)
6060
resolver.SearchDirectories.Add (Path.GetDirectoryName (assembly));
6161
resolver.Load (assembly);
6262
}
63-
var tasks = JavaTypeScanner.GetJavaTypes (assemblies, resolver, log: Console.WriteLine)
64-
.Where (td => !JavaTypeScanner.ShouldSkipJavaCallableWrapperGeneration (td))
65-
.Select (td => Task.Run (() => GenerateJavaCallableWrapper (td, outputPath)));
66-
Task.WaitAll (tasks.ToArray ());
63+
var types = JavaTypeScanner.GetJavaTypes (assemblies, resolver, log: Console.WriteLine)
64+
.Where (td => !JavaTypeScanner.ShouldSkipJavaCallableWrapperGeneration (td));
65+
foreach (var type in types) {
66+
GenerateJavaCallableWrapper (type, outputPath);
67+
}
6768
return 0;
6869
}
6970
catch (Exception e) {

0 commit comments

Comments
 (0)