1 /*
2  * Copyright 2013 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  *   http://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 io.netty.util.internal.UnstableApi;
19 import io.netty.util.internal.logging.InternalLogger;
20 import io.netty.util.internal.logging.InternalLoggerFactory;
21
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.concurrent.AbstractExecutorService;
27 import java.util.concurrent.Callable;
28 import java.util.concurrent.RunnableFuture;
29 import java.util.concurrent.TimeUnit;
30
31 /**
32  * Abstract base class for {@link EventExecutor} implementations.
33  */

34 public abstract class AbstractEventExecutor extends AbstractExecutorService implements EventExecutor {
35     private static final InternalLogger logger = InternalLoggerFactory.getInstance(AbstractEventExecutor.class);
36
37     static final long DEFAULT_SHUTDOWN_QUIET_PERIOD = 2;
38     static final long DEFAULT_SHUTDOWN_TIMEOUT = 15;
39
40     private final EventExecutorGroup parent;
41     private final Collection<EventExecutor> selfCollection = Collections.<EventExecutor>singleton(this);
42
43     protected AbstractEventExecutor() {
44         this(null);
45     }
46
47     protected AbstractEventExecutor(EventExecutorGroup parent) {
48         this.parent = parent;
49     }
50
51     @Override
52     public EventExecutorGroup parent() {
53         return parent;
54     }
55
56     @Override
57     public EventExecutor next() {
58         return this;
59     }
60
61     @Override
62     public boolean inEventLoop() {
63         return inEventLoop(Thread.currentThread());
64     }
65
66     @Override
67     public Iterator<EventExecutor> iterator() {
68         return selfCollection.iterator();
69     }
70
71     @Override
72     public Future<?> shutdownGracefully() {
73         return shutdownGracefully(DEFAULT_SHUTDOWN_QUIET_PERIOD, DEFAULT_SHUTDOWN_TIMEOUT, TimeUnit.SECONDS);
74     }
75
76     /**
77      * @deprecated {@link #shutdownGracefully(longlong, TimeUnit)} or {@link #shutdownGracefully()} instead.
78      */

79     @Override
80     @Deprecated
81     public abstract void shutdown();
82
83     /**
84      * @deprecated {@link #shutdownGracefully(longlong, TimeUnit)} or {@link #shutdownGracefully()} instead.
85      */

86     @Override
87     @Deprecated
88     public List<Runnable> shutdownNow() {
89         shutdown();
90         return Collections.emptyList();
91     }
92
93     @Override
94     public <V> Promise<V> newPromise() {
95         return new DefaultPromise<V>(this);
96     }
97
98     @Override
99     public <V> ProgressivePromise<V> newProgressivePromise() {
100         return new DefaultProgressivePromise<V>(this);
101     }
102
103     @Override
104     public <V> Future<V> newSucceededFuture(V result) {
105         return new SucceededFuture<V>(this, result);
106     }
107
108     @Override
109     public <V> Future<V> newFailedFuture(Throwable cause) {
110         return new FailedFuture<V>(this, cause);
111     }
112
113     @Override
114     public Future<?> submit(Runnable task) {
115         return (Future<?>) super.submit(task);
116     }
117
118     @Override
119     public <T> Future<T> submit(Runnable task, T result) {
120         return (Future<T>) super.submit(task, result);
121     }
122
123     @Override
124     public <T> Future<T> submit(Callable<T> task) {
125         return (Future<T>) super.submit(task);
126     }
127
128     @Override
129     protected final <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
130         return new PromiseTask<T>(this, runnable, value);
131     }
132
133     @Override
134     protected final <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
135         return new PromiseTask<T>(this, callable);
136     }
137
138     @Override
139     public ScheduledFuture<?> schedule(Runnable command, long delay,
140                                        TimeUnit unit) {
141         throw new UnsupportedOperationException();
142     }
143
144     @Override
145     public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
146         throw new UnsupportedOperationException();
147     }
148
149     @Override
150     public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
151         throw new UnsupportedOperationException();
152     }
153
154     @Override
155     public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
156         throw new UnsupportedOperationException();
157     }
158
159     /**
160      * Try to execute the given {@link Runnable} and just log if it throws a {@link Throwable}.
161      */

162     protected static void safeExecute(Runnable task) {
163         try {
164             task.run();
165         } catch (Throwable t) {
166             logger.warn("A task raised an exception. Task: {}", task, t);
167         }
168     }
169
170     /**
171      * Like {@link #execute(Runnable)} but does not guarantee the task will be run until either
172      * a non-lazy task is executed or the executor is shut down.
173      *
174      * This is equivalent to submitting a {@link EventExecutor.LazyRunnable} to
175      * {@link #execute(Runnable)} but for an arbitrary {@link Runnable}.
176      *
177      * The default implementation just delegates to {@link #execute(Runnable)}.
178      */

179     @UnstableApi
180     public void lazyExecute(Runnable task) {
181         execute(task);
182     }
183
184     /**
185      * Marker interface for {@link Runnable} to indicate that it should be queued for execution
186      * but does not need to run immediately.
187      */

188     @UnstableApi
189     public interface LazyRunnable extends Runnable { }
190 }
191