Merge pull request #448 from DataDog/ark/parallel-dd-loader
Register Datadog classloader as parallel capable
This commit is contained in:
commit
962af76bb5
|
@ -5,6 +5,10 @@ import java.net.URLClassLoader;
|
||||||
|
|
||||||
/** Classloader used to run the core datadog agent. */
|
/** Classloader used to run the core datadog agent. */
|
||||||
public class DatadogClassLoader extends URLClassLoader {
|
public class DatadogClassLoader extends URLClassLoader {
|
||||||
|
static {
|
||||||
|
ClassLoader.registerAsParallelCapable();
|
||||||
|
}
|
||||||
|
|
||||||
// Calling java.lang.instrument.Instrumentation#appendToBootstrapClassLoaderSearch
|
// Calling java.lang.instrument.Instrumentation#appendToBootstrapClassLoaderSearch
|
||||||
// adds a jar to the bootstrap class lookup, but not to the resource lookup.
|
// adds a jar to the bootstrap class lookup, but not to the resource lookup.
|
||||||
// As a workaround, we keep a reference to the bootstrap jar
|
// As a workaround, we keep a reference to the bootstrap jar
|
||||||
|
@ -45,6 +49,10 @@ public class DatadogClassLoader extends URLClassLoader {
|
||||||
* <p>This class is thread safe.
|
* <p>This class is thread safe.
|
||||||
*/
|
*/
|
||||||
public static final class BootstrapClassLoaderProxy extends URLClassLoader {
|
public static final class BootstrapClassLoaderProxy extends URLClassLoader {
|
||||||
|
static {
|
||||||
|
ClassLoader.registerAsParallelCapable();
|
||||||
|
}
|
||||||
|
|
||||||
public BootstrapClassLoaderProxy(URL[] urls, ClassLoader parent) {
|
public BootstrapClassLoaderProxy(URL[] urls, ClassLoader parent) {
|
||||||
super(urls, parent);
|
super(urls, parent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package datadog.trace.bootstrap
|
||||||
|
|
||||||
|
import spock.lang.Specification
|
||||||
|
import spock.lang.Timeout
|
||||||
|
|
||||||
|
import java.util.concurrent.Phaser
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
class DatadogClassLoaderTest extends Specification {
|
||||||
|
@Timeout(value = 60, unit = TimeUnit.SECONDS)
|
||||||
|
def "DD classloader does not lock classloading around instance" () {
|
||||||
|
setup:
|
||||||
|
def className1 = 'some/class/Name1'
|
||||||
|
def className2 = 'some/class/Name2'
|
||||||
|
final URL loc = getClass().getProtectionDomain().getCodeSource().getLocation()
|
||||||
|
final DatadogClassLoader ddLoader = new DatadogClassLoader(loc, loc, (ClassLoader) null)
|
||||||
|
final Phaser threadHoldLockPhase = new Phaser(2)
|
||||||
|
final Phaser acquireLockFromMainThreadPhase = new Phaser(2)
|
||||||
|
|
||||||
|
when:
|
||||||
|
final Thread thread1 = new Thread() {
|
||||||
|
@Override
|
||||||
|
void run() {
|
||||||
|
synchronized (ddLoader.getClassLoadingLock(className1)) {
|
||||||
|
threadHoldLockPhase.arrive()
|
||||||
|
acquireLockFromMainThreadPhase.arriveAndAwaitAdvance()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
thread1.start()
|
||||||
|
|
||||||
|
final Thread thread2 = new Thread() {
|
||||||
|
@Override
|
||||||
|
void run() {
|
||||||
|
threadHoldLockPhase.arriveAndAwaitAdvance()
|
||||||
|
synchronized (ddLoader.getClassLoadingLock(className2)) {
|
||||||
|
acquireLockFromMainThreadPhase.arrive()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
thread2.start()
|
||||||
|
thread1.join()
|
||||||
|
thread2.join()
|
||||||
|
boolean applicationDidNotDeadlock = true
|
||||||
|
|
||||||
|
then:
|
||||||
|
applicationDidNotDeadlock
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue