1 /*
2 * Copyright 2012 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License,
5 * version 2.0 (the "License"); you may not use this file except in compliance
6 * with the License. You may obtain a copy of the License at:
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
16 package io.netty.util.concurrent;
17
18 import java.util.concurrent.Callable;
19 import java.util.concurrent.TimeUnit;
20
21 /**
22 * The {@link EventExecutor} is a special {@link EventExecutorGroup} which comes
23 * with some handy methods to see if a {@link Thread} is executed in a event loop.
24 * Besides this, it also extends the {@link EventExecutorGroup} to allow for a generic
25 * way to access methods.
26 */
27 public interface EventExecutor extends EventExecutorGroup, ThreadAwareExecutor {
28
29 /**
30 * Return the {@link EventExecutorGroup} which is the parent of this {@link EventExecutor},
31 */
32 EventExecutorGroup parent();
33
34 @Override
35 default boolean isExecutorThread(Thread thread) {
36 return inEventLoop(thread);
37 }
38
39 /**
40 * Calls {@link #inEventLoop(Thread)} with {@link Thread#currentThread()} as argument
41 */
42 default boolean inEventLoop() {
43 return inEventLoop(Thread.currentThread());
44 }
45
46 /**
47 * Return {@code true} if the given {@link Thread} is executed in the event loop,
48 * {@code false} otherwise.
49 */
50 boolean inEventLoop(Thread thread);
51
52 /**
53 * Return a new {@link Promise}.
54 */
55 default <V> Promise<V> newPromise() {
56 return new DefaultPromise<>(this);
57 }
58
59 /**
60 * Create a new {@link ProgressivePromise}.
61 */
62 default <V> ProgressivePromise<V> newProgressivePromise() {
63 return new DefaultProgressivePromise<>(this);
64 }
65
66 /**
67 * Create a new {@link Future} which is marked as succeeded already. So {@link Future#isSuccess()}
68 * will return {@code true}. All {@link FutureListener} added to it will be notified directly. Also
69 * every call of blocking methods will just return without blocking.
70 */
71 default <V> Future<V> newSucceededFuture(V result) {
72 return new SucceededFuture<>(this, result);
73 }
74
75 /**
76 * Create a new {@link Future} which is marked as failed already. So {@link Future#isSuccess()}
77 * will return {@code false}. All {@link FutureListener} added to it will be notified directly. Also
78 * every call of blocking methods will just return without blocking.
79 */
80 default <V> Future<V> newFailedFuture(Throwable cause) {
81 return new FailedFuture<>(this, cause);
82 }
83
84 /**
85 * Returns {@code true} if the {@link EventExecutor} is considered suspended.
86 *
87 * @return {@code true} if suspended, {@code false} otherwise.
88 */
89 default boolean isSuspended() {
90 return false;
91 }
92
93 /**
94 * Try to suspend this {@link EventExecutor} and return {@code true} if suspension was successful.
95 * Suspending an {@link EventExecutor} will allow it to free up resources, like for example a {@link Thread} that
96 * is backing the {@link EventExecutor}. Once an {@link EventExecutor} was suspended it will be started again
97 * by submitting work to it via one of the following methods:
98 * <ul>
99 * <li>{@link #execute(Runnable)}</li>
100 * <li>{@link #schedule(Runnable, long, TimeUnit)}</li>
101 * <li>{@link #schedule(Callable, long, TimeUnit)}</li>
102 * <li>{@link #scheduleAtFixedRate(Runnable, long, long, TimeUnit)}</li>
103 * <li>{@link #scheduleWithFixedDelay(Runnable, long, long, TimeUnit)}</li>
104 * </ul>
105 *
106 * Even if this method returns {@code true} it might take some time for the {@link EventExecutor} to fully suspend
107 * itself.
108 *
109 * @return {@code true} if suspension was successful, otherwise {@code false}.
110 */
111 default boolean trySuspend() {
112 return false;
113 }
114 }