1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.util.concurrent;
17
18 import java.util.concurrent.Callable;
19 import java.util.concurrent.RunnableFuture;
20
21 class PromiseTask<V> extends DefaultPromise<V> implements RunnableFuture<V> {
22
23 private static final class RunnableAdapter<T> implements Callable<T> {
24 final Runnable task;
25 final T result;
26
27 RunnableAdapter(Runnable task, T result) {
28 this.task = task;
29 this.result = result;
30 }
31
32 @Override
33 public T call() {
34 task.run();
35 return result;
36 }
37
38 @Override
39 public String toString() {
40 return "Callable(task: " + task + ", result: " + result + ')';
41 }
42 }
43
44 private static final Runnable COMPLETED = new SentinelRunnable("COMPLETED");
45 private static final Runnable CANCELLED = new SentinelRunnable("CANCELLED");
46 private static final Runnable FAILED = new SentinelRunnable("FAILED");
47
48 private static class SentinelRunnable implements Runnable {
49 private final String name;
50
51 SentinelRunnable(String name) {
52 this.name = name;
53 }
54
55 @Override
56 public void run() { }
57
58 @Override
59 public String toString() {
60 return name;
61 }
62 }
63
64
65 private Object task;
66
67 PromiseTask(EventExecutor executor, Runnable runnable, V result) {
68 super(executor);
69 task = result == null ? runnable : new RunnableAdapter<V>(runnable, result);
70 }
71
72 PromiseTask(EventExecutor executor, Runnable runnable) {
73 super(executor);
74 task = runnable;
75 }
76
77 PromiseTask(EventExecutor executor, Callable<V> callable) {
78 super(executor);
79 task = callable;
80 }
81
82 @Override
83 public final int hashCode() {
84 return System.identityHashCode(this);
85 }
86
87 @Override
88 public final boolean equals(Object obj) {
89 return this == obj;
90 }
91
92 @SuppressWarnings("unchecked")
93 V runTask() throws Throwable {
94 final Object task = this.task;
95 if (task instanceof Callable) {
96 return ((Callable<V>) task).call();
97 }
98 ((Runnable) task).run();
99 return null;
100 }
101
102 @Override
103 public void run() {
104 try {
105 if (setUncancellableInternal()) {
106 V result = runTask();
107 setSuccessInternal(result);
108 }
109 } catch (Throwable e) {
110 setFailureInternal(e);
111 }
112 }
113
114 private boolean clearTaskAfterCompletion(boolean done, Runnable result) {
115 if (done) {
116
117
118
119
120 task = result;
121 }
122 return done;
123 }
124
125 @Override
126 public final Promise<V> setFailure(Throwable cause) {
127 throw new IllegalStateException();
128 }
129
130 protected final Promise<V> setFailureInternal(Throwable cause) {
131 super.setFailure(cause);
132 clearTaskAfterCompletion(true, FAILED);
133 return this;
134 }
135
136 @Override
137 public final boolean tryFailure(Throwable cause) {
138 return false;
139 }
140
141 protected final boolean tryFailureInternal(Throwable cause) {
142 return clearTaskAfterCompletion(super.tryFailure(cause), FAILED);
143 }
144
145 @Override
146 public final Promise<V> setSuccess(V result) {
147 throw new IllegalStateException();
148 }
149
150 protected final Promise<V> setSuccessInternal(V result) {
151 super.setSuccess(result);
152 clearTaskAfterCompletion(true, COMPLETED);
153 return this;
154 }
155
156 @Override
157 public final boolean trySuccess(V result) {
158 return false;
159 }
160
161 protected final boolean trySuccessInternal(V result) {
162 return clearTaskAfterCompletion(super.trySuccess(result), COMPLETED);
163 }
164
165 @Override
166 public final boolean setUncancellable() {
167 throw new IllegalStateException();
168 }
169
170 protected final boolean setUncancellableInternal() {
171 return super.setUncancellable();
172 }
173
174 @Override
175 public boolean cancel(boolean mayInterruptIfRunning) {
176 return clearTaskAfterCompletion(super.cancel(mayInterruptIfRunning), CANCELLED);
177 }
178
179 @Override
180 protected StringBuilder toStringBuilder() {
181 StringBuilder buf = super.toStringBuilder();
182 buf.setCharAt(buf.length() - 1, ',');
183
184 return buf.append(" task: ")
185 .append(task)
186 .append(')');
187 }
188 }