IdleResetSjavac.java revision 2682:bbd0164f668d
190075Sobrien/* 2117395Skan * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3169689Skan * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 418334Speter * 590075Sobrien * This code is free software; you can redistribute it and/or modify it 618334Speter * under the terms of the GNU General Public License version 2 only, as 790075Sobrien * published by the Free Software Foundation. Oracle designates this 890075Sobrien * particular file as subject to the "Classpath" exception as provided 990075Sobrien * by Oracle in the LICENSE file that accompanied this code. 1090075Sobrien * 1118334Speter * This code is distributed in the hope that it will be useful, but WITHOUT 1290075Sobrien * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1390075Sobrien * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1490075Sobrien * version 2 for more details (a copy is included in the LICENSE file that 1590075Sobrien * accompanied this code). 1618334Speter * 1718334Speter * You should have received a copy of the GNU General Public License version 1890075Sobrien * 2 along with this work; if not, write to the Free Software Foundation, 19169689Skan * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20169689Skan * 2118334Speter * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22169689Skan * or visit www.oracle.com if you need additional information or have any 23169689Skan * questions. 24169689Skan */ 25169689Skanpackage com.sun.tools.sjavac.server; 26169689Skan 2718334Speterimport java.io.File; 28169689Skanimport java.net.URI; 29169689Skanimport java.util.List; 3050397Sobrienimport java.util.Set; 31132718Skanimport java.util.Timer; 32132718Skanimport java.util.TimerTask; 3318334Speter 3418334Speter/** 3590075Sobrien * An sjavac implementation that keeps track of idleness and shuts down the 36169689Skan * given Terminable upon idleness timeout. 37169689Skan * 38169689Skan * An idleness timeout kicks in {@code idleTimeout} milliseconds after the last 39169689Skan * request is completed. 40169689Skan * 4118334Speter * <p><b>This is NOT part of any supported API. 4290075Sobrien * If you write code that depends on this, you do so at your own risk. 4318334Speter * This code and its internal interfaces are subject to change or 4490075Sobrien * deletion without notice.</b> 4518334Speter */ 4690075Sobrienpublic class IdleResetSjavac implements Sjavac { 4718334Speter 4890075Sobrien private final Sjavac delegate; 4990075Sobrien private final Terminable toShutdown; 5090075Sobrien private final Timer idlenessTimer = new Timer(); 5190075Sobrien private final long idleTimeout; 5290075Sobrien private int outstandingCalls = 0; 5390075Sobrien 5418334Speter // Class invariant: idlenessTimerTask != null <-> idlenessTimerTask is scheduled 5518334Speter private TimerTask idlenessTimerTask; 5618334Speter 5718334Speter public IdleResetSjavac(Sjavac delegate, 5890075Sobrien Terminable toShutdown, 5918334Speter long idleTimeout) { 6018334Speter this.delegate = delegate; 6118334Speter this.toShutdown = toShutdown; 6218334Speter this.idleTimeout = idleTimeout; 6318334Speter scheduleTimeout(); 6418334Speter } 6518334Speter 6618334Speter @Override 6718334Speter public SysInfo getSysInfo() { 6890075Sobrien startCall(); 6918334Speter try { 7018334Speter return delegate.getSysInfo(); 7118334Speter } finally { 7218334Speter endCall(); 7318334Speter } 7418334Speter } 7518334Speter 7618334Speter @Override 7718334Speter public CompilationResult compile(String protocolId, 7818334Speter String invocationId, 7918334Speter String[] args, 8018334Speter List<File> explicitSources, 8118334Speter Set<URI> sourcesToCompile, 8290075Sobrien Set<URI> visibleSources) { 8390075Sobrien startCall(); 8418334Speter try { 8518334Speter return delegate.compile(protocolId, 8618334Speter invocationId, 8718334Speter args, 8818334Speter explicitSources, 8918334Speter sourcesToCompile, 9018334Speter visibleSources); 9150397Sobrien } finally { 9250397Sobrien endCall(); 93117395Skan } 9490075Sobrien } 9518334Speter 9618334Speter private synchronized void startCall() { 9718334Speter // Was there no outstanding calls before this call? 9818334Speter if (++outstandingCalls == 1) { 9918334Speter // Then the timer task must have been scheduled 10018334Speter if (idlenessTimerTask == null) 10118334Speter throw new IllegalStateException("Idle timeout already cancelled"); 10218334Speter // Cancel timeout task 10318334Speter idlenessTimerTask.cancel(); 104169689Skan idlenessTimerTask = null; 10590075Sobrien } 10618334Speter } 10718334Speter 10818334Speter private synchronized void endCall() { 10918334Speter if (--outstandingCalls == 0) { 110132718Skan // No more outstanding calls. Schedule timeout. 111132718Skan scheduleTimeout(); 112169689Skan } 113132718Skan } 114132718Skan 115132718Skan private void scheduleTimeout() { 116132718Skan if (idlenessTimerTask != null) 117132718Skan throw new IllegalStateException("Idle timeout already scheduled"); 118132718Skan idlenessTimerTask = new TimerTask() { 119132718Skan public void run() { 120132718Skan toShutdown.shutdown("Server has been idle for " + (idleTimeout / 1000) + " seconds."); 121132718Skan } 122169689Skan }; 123169689Skan idlenessTimer.schedule(idlenessTimerTask, idleTimeout); 124169689Skan } 125169689Skan 12618334Speter @Override 12718334Speter public void shutdown() { 12890075Sobrien idlenessTimer.cancel(); 12990075Sobrien delegate.shutdown(); 130169689Skan } 131169689Skan 132169689Skan @Override 133169689Skan public String serverSettings() { 13490075Sobrien return delegate.serverSettings(); 13518334Speter } 136169689Skan} 13790075Sobrien