@Override public void run() { try { delegate.run(); } catch (Throwable ex) { Schedulers.handleError(ex); } finally { cached.dispose(); } } }
@Override @Nullable public Void call() { thread = Thread.currentThread(); try { try { task.run(); } catch (Throwable ex) { Schedulers.handleError(ex); } } finally { thread = null; } return null; }
@Override @Nullable public Void call() { thread = Thread.currentThread(); try { try { task.run(); } catch (Throwable ex) { Schedulers.handleError(ex); } } finally { thread = null; } return null; }
@Override @Nullable public Void call() { thread = Thread.currentThread(); try { try { task.run(); } catch (Throwable ex) { Schedulers.handleError(ex); } } finally { thread = null; Future f; for (;;) { f = future; if (f == CANCELLED || FUTURE.compareAndSet(this, f, FINISHED)) { break; } } } return null; }
@Override @Nullable public Void call() { thread = Thread.currentThread(); try { try { task.run(); setRest(executor.submit(this)); } catch (Throwable ex) { Schedulers.handleError(ex); } } finally { thread = null; } return null; }
@Override public void run() { if (!get()) { try { task.run(); } catch (Throwable ex) { Schedulers.handleError(ex); } finally { lazySet(true); } } }
@Override public Disposable schedule(Runnable task) { if(terminated){ throw Exceptions.failWithRejected(); } Objects.requireNonNull(task, "task"); ExecutorPlainRunnable r = new ExecutorPlainRunnable(task); //RejectedExecutionException are propagated up, but since Executor doesn't from //failing tasks we'll also wrap the execute call in a try catch: try { executor.execute(r); } catch (Throwable ex) { if (executor instanceof ExecutorService && ((ExecutorService) executor).isShutdown()) { terminated = true; } Schedulers.handleError(ex); throw Exceptions.failWithRejected(ex); } return r; }
@Override public void run() { if (!get()) { try { task.run(); } catch (Throwable ex) { Schedulers.handleError(ex); } finally { if (callRemoveOnFinish) { dispose(); } else { lazySet(true); } } } }
@Override @Nullable public Void call() { THREAD.lazySet(this, Thread.currentThread()); try { try { task.run(); } catch (Throwable ex) { Schedulers.handleError(ex); } } finally { THREAD.lazySet(this, null); Composite o = parent; //note: the o != null check must happen after the compareAndSet for it to always mark task as DONE if (o != DISPOSED && PARENT.compareAndSet(this, o, DONE) && o != null) { o.remove(this); } Future f; for (;;) { f = future; if (f == SYNC_CANCELLED || f == ASYNC_CANCELLED || FUTURE.compareAndSet(this, f, FINISHED)) { break; } } } return null; }
@Override public Disposable schedule(Runnable task) { Objects.requireNonNull(task, "task"); ExecutorTrackedRunnable r = new ExecutorTrackedRunnable(task, this, true); if (!tasks.add(r)) { throw Exceptions.failWithRejected(); } try { executor.execute(r); } catch (Throwable ex) { tasks.remove(r); Schedulers.handleError(ex); throw Exceptions.failWithRejected(ex); } return r; }
@Override public Disposable schedule(Runnable task) { Objects.requireNonNull(task, "task"); if (terminated) { throw Exceptions.failWithRejected(); } ExecutorTrackedRunnable r = new ExecutorTrackedRunnable(task, this, false); synchronized (this) { if (terminated) { throw Exceptions.failWithRejected(); } queue.offer(r); } if (WIP.getAndIncrement(this) == 0) { try { executor.execute(this); } catch (Throwable ex) { r.dispose(); Schedulers.handleError(ex); throw Exceptions.failWithRejected(ex); } } return r; }
@Test public void testUncaughtHookCalledWhenCommonException() { AtomicBoolean handled = new AtomicBoolean(false); Schedulers.onHandleError((t, e) -> handled.set(true)); try { Schedulers.handleError(new IllegalArgumentException()); } finally { Schedulers.resetOnHandleError(); } Assert.assertTrue("IllegalArgumentException not handled", handled.get()); }
@Test public void testUncaughtHookCalledWhenOnErrorNotImplemented() { AtomicBoolean handled = new AtomicBoolean(false); Schedulers.onHandleError((t, e) -> handled.set(true)); try { Schedulers.handleError(Exceptions.errorCallbackNotImplemented(new IllegalArgumentException())); } finally { Schedulers.resetOnHandleError(); } Assert.assertTrue("errorCallbackNotImplemented not handled", handled.get()); }
@Test public void testUncaughtHooksCalledWhenThreadDeath() { AtomicReference<Throwable> onHandleErrorInvoked = new AtomicReference<>(); AtomicReference<Throwable> globalUncaughtInvoked = new AtomicReference<>(); Schedulers.onHandleError((t, e) -> onHandleErrorInvoked.set(e)); Thread.setDefaultUncaughtExceptionHandler((t, e) -> globalUncaughtInvoked.set(e)); ThreadDeath fatal = new ThreadDeath(); //written that way so that we can always reset the hook Throwable thrown = catchThrowable(() -> Schedulers.handleError(fatal)); Schedulers.resetOnHandleError(); assertThat(thrown) .as("fatal exceptions not thrown") .isNull(); assertThat(onHandleErrorInvoked).as("onHandleError invoked") .hasValue(fatal); assertThat(globalUncaughtInvoked).as("global uncaught handler invoked") .hasValue(fatal); }
@Override public void run() { try { delegate.run(); } catch (Throwable ex) { Schedulers.handleError(ex); } finally { cached.dispose(); } } }
@Override @Nullable public Void call() { thread = Thread.currentThread(); try { try { task.run(); } catch (Throwable ex) { Schedulers.handleError(ex); } } finally { thread = null; } return null; }
@Override @Nullable public Void call() { thread = Thread.currentThread(); try { try { task.run(); } catch (Throwable ex) { Schedulers.handleError(ex); } } finally { thread = null; } return null; }
@Override public void run() { if (!get()) { try { task.run(); } catch (Throwable ex) { Schedulers.handleError(ex); } finally { lazySet(true); } } }
@Override public void run() { if (!get()) { try { task.run(); } catch (Throwable ex) { Schedulers.handleError(ex); } finally { if (callRemoveOnFinish) { dispose(); } else { lazySet(true); } } } }
@Override public Disposable schedule(Runnable task) { Objects.requireNonNull(task, "task"); ExecutorTrackedRunnable r = new ExecutorTrackedRunnable(task, this, true); if (!tasks.add(r)) { throw Exceptions.failWithRejected(); } try { executor.execute(r); } catch (Throwable ex) { tasks.remove(r); Schedulers.handleError(ex); throw Exceptions.failWithRejected(ex); } return r; }