langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PooledSjavac.java
author chegar
Mon, 18 Aug 2014 10:59:44 +0100
changeset 26107 a4a156a33c94
parent 26098 langtools/src/share/classes/com/sun/tools/sjavac/comp/PooledSjavac.java@32588700060b
child 31115 8d8e98052d5d
permissions -rw-r--r--
Merge
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
26098
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
     1
/*
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
     2
 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
     4
 *
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    10
 *
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    15
 * accompanied this code).
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    16
 *
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    20
 *
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    23
 * questions.
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    24
 */
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    25
package com.sun.tools.sjavac.comp;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    26
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    27
import java.io.File;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    28
import java.net.URI;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    29
import java.util.List;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    30
import java.util.Objects;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    31
import java.util.Set;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    32
import java.util.concurrent.Callable;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    33
import java.util.concurrent.ExecutorService;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    34
import java.util.concurrent.Executors;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    35
import java.util.concurrent.ThreadFactory;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    36
import java.util.concurrent.TimeUnit;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    37
import java.util.concurrent.atomic.AtomicInteger;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    38
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    39
import com.sun.tools.sjavac.Log;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    40
import com.sun.tools.sjavac.server.CompilationResult;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    41
import com.sun.tools.sjavac.server.Sjavac;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    42
import com.sun.tools.sjavac.server.SysInfo;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    43
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    44
/**
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    45
 * An sjavac implementation that limits the number of concurrent calls by
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    46
 * wrapping invocations in Callables and delegating them to a FixedThreadPool.
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    47
 *
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    48
 *  <p><b>This is NOT part of any supported API.
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    49
 *  If you write code that depends on this, you do so at your own risk.
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    50
 *  This code and its internal interfaces are subject to change or
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    51
 *  deletion without notice.</b>
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    52
 */
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    53
public class PooledSjavac implements Sjavac {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    54
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    55
    final Sjavac delegate;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    56
    final ExecutorService pool;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    57
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    58
    public PooledSjavac(Sjavac delegate, int poolsize) {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    59
        Objects.requireNonNull(delegate);
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    60
        this.delegate = delegate;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    61
        pool = Executors.newFixedThreadPool(poolsize, new ThreadFactory() {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    62
            AtomicInteger count = new AtomicInteger();
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    63
            @Override
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    64
            public Thread newThread(Runnable runnable) {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    65
                String cls = PooledSjavac.class.getSimpleName();
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    66
                int num = count.incrementAndGet();
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    67
                Thread t = new Thread(runnable, cls + "-" + num);
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    68
                t.setDaemon(true);
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    69
                return t;
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    70
            }
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    71
        });
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    72
    }
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    73
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    74
    @Override
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    75
    public SysInfo getSysInfo() {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    76
        try {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    77
            return pool.submit(new Callable<SysInfo>() {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    78
                @Override
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    79
                public SysInfo call() throws Exception {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    80
                    return delegate.getSysInfo();
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    81
                }
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    82
            }).get();
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    83
        } catch (Exception e) {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    84
            e.printStackTrace();
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    85
            throw new RuntimeException("Error during getSysInfo", e);
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    86
        }
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    87
    }
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    88
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    89
    @Override
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    90
    public CompilationResult compile(final String protocolId,
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    91
                                     final String invocationId,
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    92
                                     final String[] args,
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    93
                                     final List<File> explicitSources,
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    94
                                     final Set<URI> sourcesToCompile,
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    95
                                     final Set<URI> visibleSources) {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    96
        try {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    97
            return pool.submit(new Callable<CompilationResult>() {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    98
                @Override
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
    99
                public CompilationResult call() throws Exception {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   100
                    return delegate.compile(protocolId,
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   101
                                            invocationId,
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   102
                                            args,
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   103
                                            explicitSources,
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   104
                                            sourcesToCompile,
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   105
                                            visibleSources);
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   106
                }
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   107
            }).get();
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   108
        } catch (Exception e) {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   109
            e.printStackTrace();
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   110
            throw new RuntimeException("Error during compile", e);
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   111
        }
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   112
    }
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   113
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   114
    @Override
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   115
    public void shutdown() {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   116
        pool.shutdown(); // Disable new tasks from being submitted
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   117
        try {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   118
            // Wait a while for existing tasks to terminate
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   119
            if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   120
                pool.shutdownNow(); // Cancel currently executing tasks
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   121
                // Wait a while for tasks to respond to being cancelled
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   122
                if (!pool.awaitTermination(60, TimeUnit.SECONDS))
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   123
                    Log.error("ThreadPool did not terminate");
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   124
            }
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   125
            // Grace period for thread termination
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   126
            Thread.sleep(1000);
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   127
        } catch (InterruptedException ie) {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   128
          // (Re-)Cancel if current thread also interrupted
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   129
          pool.shutdownNow();
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   130
          // Preserve interrupt status
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   131
          Thread.currentThread().interrupt();
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   132
        }
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   133
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   134
        delegate.shutdown();
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   135
    }
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   136
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   137
    @Override
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   138
    public String serverSettings() {
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   139
        return delegate.serverSettings();
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   140
    }
32588700060b 8048457: Sjavac should not use portfiles, sockets, etc if background=false
alundblad
parents:
diff changeset
   141
}