PooledSjavac.java revision 3022:5ba1a29a0eb0
1143535Spjd/*
2131476Spjd * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
3131476Spjd * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4131476Spjd *
5131476Spjd * This code is free software; you can redistribute it and/or modify it
6131476Spjd * under the terms of the GNU General Public License version 2 only, as
7131476Spjd * published by the Free Software Foundation.  Oracle designates this
8131476Spjd * particular file as subject to the "Classpath" exception as provided
9131476Spjd * by Oracle in the LICENSE file that accompanied this code.
10131476Spjd *
11131476Spjd * This code is distributed in the hope that it will be useful, but WITHOUT
12131476Spjd * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13131476Spjd * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14131476Spjd * version 2 for more details (a copy is included in the LICENSE file that
15131476Spjd * accompanied this code).
16131476Spjd *
17131476Spjd * You should have received a copy of the GNU General Public License version
18131476Spjd * 2 along with this work; if not, write to the Free Software Foundation,
19131476Spjd * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20131476Spjd *
21131476Spjd * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22131476Spjd * or visit www.oracle.com if you need additional information or have any
23131476Spjd * questions.
24131476Spjd */
25131476Spjdpackage com.sun.tools.sjavac.comp;
26131476Spjd
27249768Sjoelimport java.io.Writer;
28131476Spjdimport java.util.Objects;
29131476Spjdimport java.util.concurrent.ExecutorService;
30131476Spjdimport java.util.concurrent.Executors;
31131476Spjdimport java.util.concurrent.TimeUnit;
32131476Spjd
33131476Spjdimport com.sun.tools.sjavac.Log;
34131476Spjdimport com.sun.tools.sjavac.server.Sjavac;
35131476Spjd
36131476Spjd/**
37131476Spjd * An sjavac implementation that limits the number of concurrent calls by
38131476Spjd * wrapping invocations in Callables and delegating them to a FixedThreadPool.
39131476Spjd *
40131649Spjd *  <p><b>This is NOT part of any supported API.
41131649Spjd *  If you write code that depends on this, you do so at your own risk.
42140298Spjd *  This code and its internal interfaces are subject to change or
43131649Spjd *  deletion without notice.</b>
44131476Spjd */
45131476Spjdpublic class PooledSjavac implements Sjavac {
46131476Spjd
47131476Spjd    final Sjavac delegate;
48131476Spjd    final ExecutorService pool;
49131649Spjd
50131476Spjd    public PooledSjavac(Sjavac delegate, int poolsize) {
51140298Spjd        Objects.requireNonNull(delegate);
52131476Spjd        this.delegate = delegate;
53131476Spjd        pool = Executors.newFixedThreadPool(poolsize);
54131476Spjd    }
55140298Spjd
56131476Spjd    @Override
57132344Spjd    public int compile(String[] args, Writer out, Writer err) {
58140298Spjd        try {
59132344Spjd            return pool.submit(() -> {
60131476Spjd                return delegate.compile(args, out, err);
61131476Spjd            }).get();
62143535Spjd        } catch (Exception e) {
63143535Spjd            e.printStackTrace();
64131476Spjd            throw new RuntimeException("Error during compile", e);
65131476Spjd        }
66131476Spjd    }
67131476Spjd
68131476Spjd    @Override
69131476Spjd    public void shutdown() {
70137221Sceri        Log.debug("Shutting down PooledSjavac");
71131763Sru        pool.shutdown(); // Disable new tasks from being submitted
72131476Spjd        try {
73131476Spjd            // Wait a while for existing tasks to terminate
74131476Spjd            if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
75131476Spjd                pool.shutdownNow(); // Cancel currently executing tasks
76131476Spjd                // Wait a while for tasks to respond to being cancelled
77131476Spjd                if (!pool.awaitTermination(60, TimeUnit.SECONDS))
78131476Spjd                    Log.error("ThreadPool did not terminate");
79131476Spjd            }
80131476Spjd        } catch (InterruptedException ie) {
81131520Spjd          // (Re-)Cancel if current thread also interrupted
82131520Spjd          pool.shutdownNow();
83131476Spjd          // Preserve interrupt status
84249768Sjoel          Thread.currentThread().interrupt();
85131476Spjd        }
86131476Spjd
87131763Sru        delegate.shutdown();
88131476Spjd    }
89131476Spjd
90131476Spjd}
91131476Spjd