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    
019    package org.fusesource.hawtdispatch;
020    
021    import java.util.concurrent.Executor;
022    import 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     */
035    public 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         * Returns the usage metrics of this queue.  Only returns a value
231         * if the queue has profiling enabled.
232         *
233         * @return new metric counters accumulated since last called or null if the queue has not been used.
234         */
235        Metrics metrics();
236    
237    }