4632N/A/*
4632N/A * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
4632N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4632N/A *
4632N/A * This code is free software; you can redistribute it and/or modify it
4632N/A * under the terms of the GNU General Public License version 2 only, as
4632N/A * published by the Free Software Foundation. Oracle designates this
4632N/A * particular file as subject to the "Classpath" exception as provided
4632N/A * by Oracle in the LICENSE file that accompanied this code.
4632N/A *
4632N/A * This code is distributed in the hope that it will be useful, but WITHOUT
4632N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4632N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4632N/A * version 2 for more details (a copy is included in the LICENSE file that
4632N/A * accompanied this code).
4632N/A *
4632N/A * You should have received a copy of the GNU General Public License version
4632N/A * 2 along with this work; if not, write to the Free Software Foundation,
4632N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4632N/A *
4632N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4632N/A * or visit www.oracle.com if you need additional information or have any
4632N/A * questions.
4632N/A */
4632N/A
4632N/Apackage com.apple.concurrent;
4632N/A
4632N/Aimport java.util.concurrent.*;
4632N/A
4632N/A/**
4632N/A * Factory for {@link Executor}s and {@link ExecutorService}s backed by
4632N/A * libdispatch.
4632N/A *
4632N/A * Access is controlled through the Dispatch.getInstance() method, because
4632N/A * performed tasks occur on threads owned by libdispatch. These threads are
4632N/A * not owned by any particular AppContext or have any specific context
4632N/A * classloader installed.
4632N/A *
4632N/A * @since Java for Mac OS X 10.6 Update 2
4632N/A */
4632N/Apublic final class Dispatch {
4632N/A /**
4632N/A * The priorities of the three default asynchronous queues.
4632N/A */
4632N/A public enum Priority {
4632N/A LOW(-2), NORMAL(0), HIGH(2); // values from <dispatch/queue.h>
4632N/A
4632N/A final int nativePriority;
4632N/A Priority(final int nativePriority) { this.nativePriority = nativePriority; }
4632N/A };
4632N/A
4632N/A final static Dispatch instance = new Dispatch();
4632N/A
4632N/A /**
4632N/A * Factory method returns an instnace of Dispatch if supported by the
4632N/A * underlying operating system, and if the caller's security manager
4632N/A * permits "canInvokeInSystemThreadGroup".
4632N/A *
4632N/A * @return a factory instance of Dispatch, or null if not available
4632N/A */
4632N/A public static Dispatch getInstance() {
4632N/A checkSecurity();
4632N/A if (!LibDispatchNative.nativeIsDispatchSupported()) return null;
4632N/A
4632N/A return instance;
4632N/A }
4632N/A
4632N/A private static void checkSecurity() {
4632N/A final SecurityManager security = System.getSecurityManager();
4632N/A if (security != null) security.checkPermission(new RuntimePermission("canInvokeInSystemThreadGroup"));
4632N/A }
4632N/A
4632N/A private Dispatch() { }
4632N/A
4632N/A /**
4632N/A * Creates an {@link Executor} that performs tasks asynchronously. The {@link Executor}
4632N/A * cannot be shutdown, and enqueued {@link Runnable}s cannot be canceled. Passing null
4632N/A * returns the {@link Priority.NORMAL} {@link Executor}.
4632N/A *
4632N/A * @param priority - the priority of the returned {@link Executor}
4632N/A * @return an asynchronous {@link Executor}
4632N/A */
4632N/A public Executor getAsyncExecutor(Priority priority) {
4632N/A if (priority == null) priority = Priority.NORMAL;
4632N/A final long nativeQueue = LibDispatchNative.nativeCreateConcurrentQueue(priority.nativePriority);
4632N/A if (nativeQueue == 0L) return null;
4632N/A return new LibDispatchConcurrentQueue(nativeQueue);
4632N/A }
4632N/A
4632N/A int queueIndex = 0;
4632N/A /**
4632N/A * Creates an {@link ExecutorService} that performs tasks synchronously in FIFO order.
4632N/A * Useful to protect a resource against concurrent modification, in lieu of a lock.
4632N/A * Passing null returns an {@link ExecutorService} with a uniquely labeled queue.
4632N/A *
4632N/A * @param label - a label to name the queue, shown in several debugging tools
4632N/A * @return a synchronous {@link ExecutorService}
4632N/A */
4632N/A public ExecutorService createSerialExecutor(String label) {
4632N/A if (label == null) label = "";
4632N/A if (label.length() > 256) label = label.substring(0, 256);
4632N/A String queueName = "com.apple.java.concurrent.";
4632N/A if ("".equals(label)) {
4632N/A synchronized (this) {
4632N/A queueName += queueIndex++;
4632N/A }
4632N/A } else {
4632N/A queueName += label;
4632N/A }
4632N/A
4632N/A final long nativeQueue = LibDispatchNative.nativeCreateSerialQueue(queueName);
4632N/A if (nativeQueue == 0) return null;
4632N/A return new LibDispatchSerialQueue(nativeQueue);
4632N/A }
4632N/A
4632N/A Executor nonBlockingMainQueue = null;
4632N/A /**
4632N/A * Returns an {@link Executor} that performs the provided Runnables on the main queue of the process.
4632N/A * Runnables submitted to this {@link Executor} will not run until the AWT is started or another native toolkit is running a CFRunLoop or NSRunLoop on the main thread.
4632N/A *
4632N/A * Submitting a Runnable to this {@link Executor} does not wait for the Runnable to complete.
4632N/A * @return an asynchronous {@link Executor} that is backed by the main queue
4632N/A */
4632N/A public synchronized Executor getNonBlockingMainQueueExecutor() {
4632N/A if (nonBlockingMainQueue != null) return nonBlockingMainQueue;
4632N/A return nonBlockingMainQueue = new LibDispatchMainQueue.ASync();
4632N/A }
4632N/A
4632N/A Executor blockingMainQueue = null;
4632N/A /**
4632N/A * Returns an {@link Executor} that performs the provided Runnables on the main queue of the process.
4632N/A * Runnables submitted to this {@link Executor} will not run until the AWT is started or another native toolkit is running a CFRunLoop or NSRunLoop on the main thread.
4632N/A *
4632N/A * Submitting a Runnable to this {@link Executor} will block until the Runnable has completed.
4632N/A * @return an {@link Executor} that is backed by the main queue
4632N/A */
4632N/A public synchronized Executor getBlockingMainQueueExecutor() {
4632N/A if (blockingMainQueue != null) return blockingMainQueue;
4632N/A return blockingMainQueue = new LibDispatchMainQueue.Sync();
4632N/A }
4632N/A}