V8Locker(final V8 runtime) { this.runtime = runtime; acquire(); }
/** * Runs an {@link V8Runnable} on the V8 thread. * * <b>Note: </b> This method executes synchronously, not asynchronously; * it will not return until the passed {@link V8Runnable} is done * executing. The method is also synchronized, so it will block until it * gets a chance to run. * * @param runnable {@link V8Runnable} to run. */ public synchronized void run(final V8Runnable runnable) { try { v8.getLocker().acquire(); runnable.run(v8); } finally { if ((v8 != null) && (v8.getLocker() != null) && v8.getLocker().hasLock()) { v8.getLocker().release(); } } }
V8Locker(final V8 runtime) { this.runtime = runtime; acquire(); }
@Test public void testBinarySemaphore() throws InterruptedException { v8.getLocker().acquire(); // Lock has been acquired twice v8.getLocker().release(); // Lock should be released, second acquire shouldn't count Thread t = new Thread(new Runnable() { @Override public void run() { v8.getLocker().acquire(); v8.getLocker().release(); } }); t.start(); t.join(); v8.getLocker().acquire(); }
@Override public void run() { v8.getLocker().acquire(); v8.getLocker().release(); } });
@Override public Object invoke(final V8Object receiver, final V8Array parameters) { v8.getLocker().release(); v8.getLocker().acquire(); return null; } }, "foo");
/** * Runs an {@link V8Runnable} on the V8 thread. * * <b>Note: </b> This method executes synchronously, not asynchronously; * it will not return until the passed {@link V8Runnable} is done * executing. The method is also synchronized, so it will block until it * gets a chance to run. * * @param runnable {@link V8Runnable} to run. */ public synchronized void run(final V8Runnable runnable) { try { v8.getLocker().acquire(); runnable.run(v8); } finally { if ((v8 != null) && (v8.getLocker() != null) && v8.getLocker().hasLock()) { v8.getLocker().release(); } } }
@Override public void run() { v8.getLocker().acquire(); v8.add("foo", "baz"); v8.getLocker().release(); } });
@Test public void testAcquireLocker() { V8Locker v8Locker = new V8Locker(v8); v8Locker.release(); v8Locker.acquire(); v8Locker.checkThread(); }
@Test public void testMultiThreadAccess() throws InterruptedException { v8.add("foo", "bar"); v8.getLocker().release(); Thread t = new Thread(new Runnable() { @Override public void run() { v8.getLocker().acquire(); v8.add("foo", "baz"); v8.getLocker().release(); } }); t.start(); t.join(); v8.getLocker().acquire(); assertEquals("baz", v8.getString("foo")); }
V8Locker() { acquire(); }
V8Locker() { acquire(); }
@Test public void testLosesCurrentIsolate() { final V8 v8 = V8.createV8Runtime(); v8.registerJavaMethod(new JavaCallback() { @Override public Object invoke(final V8Object receiver, final V8Array parameters) { v8TempRuntime = V8.createV8Runtime(); v8TempRuntime.getLocker().release(); throw new RuntimeException(); } }, "foo"); try { v8.executeFunction("foo", null); } catch (RuntimeException e) { // doNothing } v8.release(false); v8TempRuntime.getLocker().acquire(); v8TempRuntime.close(); }
static Optional<String> executeV8Function(V8 v8, String userAgent) { V8Array v8FunctionParams = null; try { v8.getLocker().acquire(); v8FunctionParams = new V8Array(v8).push(userAgent); return Optional.ofNullable(v8.executeStringFunction(WRAPPER_FUNCTION, v8FunctionParams)); } finally { // Release V8 engine function parameters array Optional.ofNullable(v8FunctionParams) .ifPresent(V8Array::release); // Release V8 engine lock Optional.of(v8.getLocker()) .filter(V8Locker::hasLock) .ifPresent(V8Locker::release); } } }