12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package com.sun.tools.sjavac.comp;
26
27 import java.io.File;
28 import java.net.URI;
29 import java.util.List;
30 import java.util.Objects;
31 import java.util.Set;
32 import java.util.concurrent.Callable;
33 import java.util.concurrent.ExecutorService;
34 import java.util.concurrent.Executors;
35 import java.util.concurrent.ThreadFactory;
36 import java.util.concurrent.TimeUnit;
37 import java.util.concurrent.atomic.AtomicInteger;
38
39 import com.sun.tools.sjavac.Log;
40 import com.sun.tools.sjavac.server.CompilationResult;
41 import com.sun.tools.sjavac.server.Sjavac;
42 import com.sun.tools.sjavac.server.SysInfo;
43
44 /**
45 * An sjavac implementation that limits the number of concurrent calls by
46 * wrapping invocations in Callables and delegating them to a FixedThreadPool.
47 *
48 * <p><b>This is NOT part of any supported API.
49 * If you write code that depends on this, you do so at your own risk.
50 * This code and its internal interfaces are subject to change or
51 * deletion without notice.</b>
52 */
53 public class PooledSjavac implements Sjavac {
54
55 final Sjavac delegate;
56 final ExecutorService pool;
57
58 public PooledSjavac(Sjavac delegate, int poolsize) {
59 Objects.requireNonNull(delegate);
60 this.delegate = delegate;
61 pool = Executors.newFixedThreadPool(poolsize, new ThreadFactory() {
62 AtomicInteger count = new AtomicInteger();
63 @Override
64 public Thread newThread(Runnable runnable) {
65 String cls = PooledSjavac.class.getSimpleName();
66 int num = count.incrementAndGet();
67 Thread t = new Thread(runnable, cls + "-" + num);
68 t.setDaemon(true);
69 return t;
70 }
71 });
72 }
73
74 @Override
75 public SysInfo getSysInfo() {
76 try {
77 return pool.submit(new Callable<SysInfo>() {
78 @Override
79 public SysInfo call() throws Exception {
80 return delegate.getSysInfo();
81 }
82 }).get();
83 } catch (Exception e) {
84 e.printStackTrace();
85 throw new RuntimeException("Error during getSysInfo", e);
86 }
87 }
88
89 @Override
90 public CompilationResult compile(final String protocolId,
91 final String invocationId,
92 final String[] args,
93 final List<File> explicitSources,
94 final Set<URI> sourcesToCompile,
95 final Set<URI> visibleSources) {
96 try {
97 return pool.submit(new Callable<CompilationResult>() {
98 @Override
99 public CompilationResult call() throws Exception {
100 return delegate.compile(protocolId,
101 invocationId,
102 args,
103 explicitSources,
104 sourcesToCompile,
105 visibleSources);
106 }
107 }).get();
108 } catch (Exception e) {
109 e.printStackTrace();
110 throw new RuntimeException("Error during compile", e);
111 }
112 }
113
114 @Override
115 public void shutdown() {
116 pool.shutdown(); // Disable new tasks from being submitted
117 try {
118 // Wait a while for existing tasks to terminate
119 if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
120 pool.shutdownNow(); // Cancel currently executing tasks
121 // Wait a while for tasks to respond to being cancelled
122 if (!pool.awaitTermination(60, TimeUnit.SECONDS))
123 Log.error("ThreadPool did not terminate");
124 }
125 // Grace period for thread termination
126 Thread.sleep(1000);
127 } catch (InterruptedException ie) {
128 // (Re-)Cancel if current thread also interrupted
129 pool.shutdownNow();
130 // Preserve interrupt status
131 Thread.currentThread().interrupt();
132 }
133
134 delegate.shutdown();
135 }
136
137 @Override
138 public String serverSettings() {
139 return delegate.serverSettings();
140 }
141 }
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package com.sun.tools.sjavac.comp;
26
27 import java.io.File;
28 import java.net.URI;
29 import java.util.List;
30 import java.util.Objects;
31 import java.util.Set;
32 import java.util.concurrent.ExecutorService;
33 import java.util.concurrent.Executors;
34 import java.util.concurrent.TimeUnit;
35
36 import com.sun.tools.sjavac.Log;
37 import com.sun.tools.sjavac.server.CompilationResult;
38 import com.sun.tools.sjavac.server.Sjavac;
39 import com.sun.tools.sjavac.server.SysInfo;
40
41 /**
42 * An sjavac implementation that limits the number of concurrent calls by
43 * wrapping invocations in Callables and delegating them to a FixedThreadPool.
44 *
45 * <p><b>This is NOT part of any supported API.
46 * If you write code that depends on this, you do so at your own risk.
47 * This code and its internal interfaces are subject to change or
48 * deletion without notice.</b>
49 */
50 public class PooledSjavac implements Sjavac {
51
52 final Sjavac delegate;
53 final ExecutorService pool;
54
55 public PooledSjavac(Sjavac delegate, int poolsize) {
56 Objects.requireNonNull(delegate);
57 this.delegate = delegate;
58 pool = Executors.newFixedThreadPool(poolsize);
59 }
60
61 @Override
62 public SysInfo getSysInfo() {
63 try {
64 return pool.submit(() -> delegate.getSysInfo()).get();
65 } catch (Exception e) {
66 e.printStackTrace();
67 throw new RuntimeException("Error during getSysInfo", e);
68 }
69 }
70
71 @Override
72 public CompilationResult compile(final String protocolId,
73 final String invocationId,
74 final String[] args,
75 final List<File> explicitSources,
76 final Set<URI> sourcesToCompile,
77 final Set<URI> visibleSources) {
78 try {
79 return pool.submit(() -> {
80 return delegate.compile(protocolId,
81 invocationId,
82 args,
83 explicitSources,
84 sourcesToCompile,
85 visibleSources);
86 }).get();
87 } catch (Exception e) {
88 e.printStackTrace();
89 throw new RuntimeException("Error during compile", e);
90 }
91 }
92
93 @Override
94 public void shutdown() {
95 Log.debug("Shutting down PooledSjavac");
96 pool.shutdown(); // Disable new tasks from being submitted
97 try {
98 // Wait a while for existing tasks to terminate
99 if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
100 pool.shutdownNow(); // Cancel currently executing tasks
101 // Wait a while for tasks to respond to being cancelled
102 if (!pool.awaitTermination(60, TimeUnit.SECONDS))
103 Log.error("ThreadPool did not terminate");
104 }
105 } catch (InterruptedException ie) {
106 // (Re-)Cancel if current thread also interrupted
107 pool.shutdownNow();
108 // Preserve interrupt status
109 Thread.currentThread().interrupt();
110 }
111
112 delegate.shutdown();
113 }
114
115 @Override
116 public String serverSettings() {
117 return delegate.serverSettings();
118 }
119 }
|