1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.util;
20
21 import java.util.concurrent.Executor;
22
23 public abstract class ExecutorCallback<C> implements Callback<C>
24 {
25 private final ForkInvoker<C> _invoker;
26 private final Executor _executor;
27
28 public ExecutorCallback(Executor executor)
29 {
30 this(executor, 4);
31 }
32
33 public ExecutorCallback(Executor executor, int maxRecursion)
34 {
35 _executor = executor;
36 _invoker = new ExecutorCallbackInvoker(maxRecursion);
37 }
38
39 @Override
40 public final void completed(final C context)
41 {
42
43 if (alwaysDispatchCompletion())
44 {
45 _invoker.fork(context);
46 }
47 else
48 {
49 _invoker.invoke(context);
50 }
51 }
52
53 protected abstract void onCompleted(C context);
54
55 @Override
56 public final void failed(final C context, final Throwable x)
57 {
58
59 Runnable runnable = new Runnable()
60 {
61 @Override
62 public void run()
63 {
64 onFailed(context, x);
65 }
66
67 @Override
68 public String toString()
69 {
70 return String.format("ExecutorCallback@%x{%s,%s}", hashCode(), context, x);
71 }
72 };
73
74 if (_executor == null)
75 new Thread(runnable).start();
76 else
77 _executor.execute(runnable);
78 }
79
80 protected void onFailed(C context, Throwable x)
81 {
82 }
83
84 protected boolean alwaysDispatchCompletion()
85 {
86 return _executor != null;
87 }
88
89 @Override
90 public String toString()
91 {
92 return String.format("%s@%x", getClass(), hashCode());
93 }
94
95 private class ExecutorCallbackInvoker extends ForkInvoker<C> implements Runnable
96 {
97 private ExecutorCallbackInvoker(int maxInvocations)
98 {
99 super(maxInvocations);
100 }
101
102 @Override
103 public void fork(final C context)
104 {
105 _executor.execute(context == null ? this : new Runnable()
106 {
107 @Override
108 public void run()
109 {
110 call(context);
111 }
112
113 @Override
114 public String toString()
115 {
116 return String.format("ExecutorCallback@%x{%s}", hashCode(), context);
117 }
118 });
119 }
120
121 @Override
122 public void call(C context)
123 {
124 onCompleted(context);
125 }
126
127 @Override
128 public void run()
129 {
130 call(null);
131 }
132 }
133 }