001/**
002 * Copyright (c) 2008-2009 Apple Inc. All rights reserved.
003 * Copyright (C) 2012 FuseSource, Inc.
004 * http://fusesource.com
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.fusesource.hawtdispatch;
020
021import java.util.concurrent.Executor;
022import java.util.concurrent.TimeUnit;
023
024/**
025 *
026 * <p>
027 * Dispatch queues are lightweight objects to which runnable objects
028 * may be submitted for asynchronous execution and therefore are
029 * {@link Executor} objects.
030 * </p>
031 *
032 *
033 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
034 */
035public interface DispatchQueue extends DispatchObject, Executor {
036
037    /**
038     * Defines the types of dispatch queues supported by the system.
039     */
040    enum QueueType {
041
042        /**
043         * A global queue represents a dispatch queue which executes
044         * runnable objects in a concurrently.
045         */
046        GLOBAL_QUEUE,
047
048        /**
049         * A serial dispatch queues executes runnable objects
050         * submitted to them serially in FIFO order. A
051         * queue will only invoke one runnable at a time,
052         * ut independent queues may each invoke their runnables
053         * concurrently with respect to each other.
054         */
055        SERIAL_QUEUE,
056
057        /**
058         * A thread queue is a dispatch queue associated with a specific
059         * thread.  It executes runnable objects submitted to them
060         * serially in FIFO order.   
061         */
062        THREAD_QUEUE
063    }
064
065    /**
066     * @return the type of dispatch queue that this object implements.
067     */
068    public QueueType getQueueType();
069
070    /**
071     * <p>
072     * Creates a new serial dispatch queue with this queue set as it's
073     * target queue. See {@link Dispatch#createQueue(String)} for
074     * more information about serial dispatch queues.
075     * </p>
076     *
077     * @param label the label to assign the dispatch queue, can be null
078     * @return the newly created dispatch queue
079     */
080    public DispatchQueue createQueue(String label);
081
082    /**
083     * <p>
084     * Submits a runnable for asynchronous execution on a dispatch queue.
085     * </p><p>
086     * {@link #execute(Runnable)} is the fundamental mechanism for submitting
087     * runnable objects to a dispatch queue.
088     * </p><p>
089     * Calls to {@link #execute(Runnable)} always return immediately after the runnable has
090     * been submitted, and never wait for the runnable to be executed.
091     * </p><p>
092     * The target queue determines whether the runnable will be invoked serially or
093     * concurrently with respect to other runnables submitted to that same queue.
094     * Serial queues are processed concurrently with with respect to each other.
095     * </p>
096     *
097     * @param runnable
098     * The runnable to submit to the dispatch queue.
099     */
100    void execute(Runnable runnable);
101
102    /**
103     * <p>
104     * Submits a task for asynchronous execution on a dispatch queue.
105     * </p><p>
106     * {@link #execute(Task)} is the fundamental mechanism for submitting
107     * runnable objects to a dispatch queue.
108     * </p><p>
109     * Calls to {@link #execute(Task)} always return immediately after the runnable has
110     * been submitted, and never wait for the runnable to be executed.
111     * </p><p>
112     * The target queue determines whether the runnable will be invoked serially or
113     * concurrently with respect to other runnables submitted to that same queue.
114     * Serial queues are processed concurrently with with respect to each other.
115     * </p>
116     *
117     * @param task
118     * The task to submit to the dispatch queue.
119     */
120    void execute(Task task);
121
122    /**
123     * <p>
124     * Schedule a runnable for execution on a given queue at a specified time.
125     * </p>
126     *
127     * @param delay
128     * the amount of time to delay before executing the runnable
129     * @param unit the unit of time that the delay value is specified in
130     * @param runnable
131     */
132    public void executeAfter(long delay, TimeUnit unit, Runnable runnable);
133
134    /**
135     * <p>
136     * Schedule a task for execution on a given queue at a specified time.
137     * </p>
138     *
139     * @param delay
140     * the amount of time to delay before executing the runnable
141     * @param unit the unit of time that the delay value is specified in
142     * @param task
143     */
144    public void executeAfter(long delay, TimeUnit unit, Task task);
145
146//
147//  This is an API method that libdispatch supports, but even they don't recommend it's
148//  use.  Due to the static nature of our thread pool implementation it's even more dangerous.
149//  so leaving it commented out for now so that folks don't use it.  Perhaps we can enable it
150//  in a future release.
151//
152//    /**
153//     * <p>
154//     * Submits a runnable for synchronous execution on a dispatch queue.
155//     * </p><p>
156//     * Submits a runnable to a dispatch queue like dispatch_async(), however
157//     * {@link #dispatchSync(Runnable)} will not return until the runnable
158//     * has finished.
159//     * </p><p>
160//     * Calls to {@link #dispatchSync(Runnable)} targeting the current queue will result
161//     * in dead-lock. Use of {@link #dispatchSync(Runnable)} is also subject to the same
162//     * multi-party dead-lock problems that may result from the use of a mutex.
163//     * Use of {@link #execute(Runnable)} is preferred.
164//     * </p>
165//     *
166//     * @param runnable
167//     * The runnable to be invoked on the target dispatch queue.
168//     */
169//    public void dispatchSync(Runnable runnable) throws InterruptedException;
170
171//  Ditto..
172//
173//    /**
174//     * <p>
175//     * Submits a runnable to a dispatch queue for multiple invocations.
176//     * </p><p>
177//     * This function
178//     * waits for the task runnable to complete before returning. If the target queue
179//     * is a concurrent queue returned by {@link Dispatch#getGlobalQueue()}, the runnable
180//     * may be invoked concurrently, and it must therefore be thread safe.
181//     * </p>
182//     *
183//     * @param iterations
184//     * The number of iterations to perform.
185//     * <br/>
186//     * @param runnable
187//     * The runnable to be invoked the specified number of iterations.
188//     */
189//    public void dispatchApply(int iterations, Runnable runnable) throws InterruptedException;
190
191    /**
192     * <p>
193     * Returns the label of the queue.
194     * </p>
195     *
196     * @return the label of the queue. The result may be null.
197     */
198    public String getLabel();
199
200    /**
201     * <p>
202     * Sets the label of the queue.
203     * </p>
204     *
205     * @param label the label of the queue.
206     */
207    public void setLabel(String label);
208
209    /**
210     * <p>
211     * Returns true if this dispatch queue is executing the caller.
212     * </p>
213     *
214     * @return if this dispatch queue is executing the caller.
215     */
216    public boolean isExecuting();
217
218    /**
219     * Asserts that the current dispatch queue is executing.
220     */
221    public void assertExecuting();
222
223    /**
224     * Enables or disables profiler metric tracking on the queue.
225     * @param on
226     */
227    void profile(boolean on);
228
229    /**
230     * @return true is profiling is enabled.
231     */
232    boolean profile();
233
234    /**
235     * Returns the usage metrics of this queue.  Only returns a value
236     * if the queue has profiling enabled.
237     *
238     * @return new metric counters accumulated since last called or null if the queue has not been used.
239     */
240    Metrics metrics();
241
242}