Path: blob/master/src/java.desktop/share/classes/sun/font/CreatedFontTracker.java
41154 views
/*1* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.font;2627import java.io.File;28import java.io.OutputStream;29import java.security.AccessController;30import java.security.PrivilegedAction;31import java.util.HashMap;32import java.util.Map;33import java.util.concurrent.Semaphore;34import java.util.concurrent.TimeUnit;3536import sun.awt.AppContext;37import sun.awt.util.ThreadGroupUtils;3839public class CreatedFontTracker {4041public static final int MAX_FILE_SIZE = 32 * 1024 * 1024;42public static final int MAX_TOTAL_BYTES = 10 * MAX_FILE_SIZE;4344static CreatedFontTracker tracker;45int numBytes;4647public static synchronized CreatedFontTracker getTracker() {48if (tracker == null) {49tracker = new CreatedFontTracker();50}51return tracker;52}5354private CreatedFontTracker() {55numBytes = 0;56}5758public synchronized int getNumBytes() {59return numBytes;60}6162public synchronized void addBytes(int sz) {63numBytes += sz;64}6566public synchronized void subBytes(int sz) {67numBytes -= sz;68}6970/**71* Returns an AppContext-specific counting semaphore.72*/73private static synchronized Semaphore getCS() {74final AppContext appContext = AppContext.getAppContext();75Semaphore cs = (Semaphore) appContext.get(CreatedFontTracker.class);76if (cs == null) {77// Make a semaphore with 5 permits that obeys the first-in first-out78// granting of permits.79cs = new Semaphore(5, true);80appContext.put(CreatedFontTracker.class, cs);81}82return cs;83}8485public boolean acquirePermit() throws InterruptedException {86// This does a timed-out wait.87return getCS().tryAcquire(120, TimeUnit.SECONDS);88}8990public void releasePermit() {91getCS().release();92}9394public void add(File file) {95TempFileDeletionHook.add(file);96}9798public void set(File file, OutputStream os) {99TempFileDeletionHook.set(file, os);100}101102public void remove(File file) {103TempFileDeletionHook.remove(file);104}105106/**107* Helper class for cleanup of temp files created while processing fonts.108* Note that this only applies to createFont() from an InputStream object.109*/110private static class TempFileDeletionHook {111private static HashMap<File, OutputStream> files = new HashMap<>();112113private static Thread t = null;114@SuppressWarnings("removal")115static void init() {116if (t == null) {117// Add a shutdown hook to remove the temp file.118AccessController.doPrivileged((PrivilegedAction<Void>) () -> {119/* The thread must be a member of a thread group120* which will not get GCed before VM exit.121* Make its parent the top-level thread group.122*/123ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();124t = new Thread(rootTG, TempFileDeletionHook::runHooks,125"TempFontFileDeleter", 0, false);126/* Set context class loader to null in order to avoid127* keeping a strong reference to an application classloader.128*/129t.setContextClassLoader(null);130Runtime.getRuntime().addShutdownHook(t);131return null;132});133}134}135136private TempFileDeletionHook() {}137138static synchronized void add(File file) {139init();140files.put(file, null);141}142143static synchronized void set(File file, OutputStream os) {144files.put(file, os);145}146147static synchronized void remove(File file) {148files.remove(file);149}150151static synchronized void runHooks() {152if (files.isEmpty()) {153return;154}155156for (Map.Entry<File, OutputStream> entry : files.entrySet()) {157// Close the associated output stream, and then delete the file.158try {159if (entry.getValue() != null) {160entry.getValue().close();161}162} catch (Exception e) {}163entry.getKey().delete();164}165}166}167}168169170