1*2be43276SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*2be43276SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*2be43276SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*2be43276SAndrew Rist * distributed with this work for additional information 6*2be43276SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*2be43276SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*2be43276SAndrew Rist * "License"); you may not use this file except in compliance 9*2be43276SAndrew Rist * with the License. You may obtain a copy of the License at 10*2be43276SAndrew Rist * 11*2be43276SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*2be43276SAndrew Rist * 13*2be43276SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*2be43276SAndrew Rist * software distributed under the License is distributed on an 15*2be43276SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*2be43276SAndrew Rist * KIND, either express or implied. See the License for the 17*2be43276SAndrew Rist * specific language governing permissions and limitations 18*2be43276SAndrew Rist * under the License. 19*2be43276SAndrew Rist * 20*2be43276SAndrew Rist *************************************************************/ 21*2be43276SAndrew Rist 22*2be43276SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir package com.sun.star.lib.util; 25cdf0e10cSrcweir 26cdf0e10cSrcweir import java.util.LinkedList; 27cdf0e10cSrcweir 28cdf0e10cSrcweir /** 29cdf0e10cSrcweir Helper class to asynchronously execute finalize methods. 30cdf0e10cSrcweir 31cdf0e10cSrcweir Current JVMs seem not to be robust against long-running finalize methods, in 32cdf0e10cSrcweir that such long-running finalize methods may lead to OutOfMemoryErrors. This 33cdf0e10cSrcweir class mitigates the problem by asynchronously shifting the bodies of 34cdf0e10cSrcweir potentially long-running finalize methods into an extra thread. Classes that 35cdf0e10cSrcweir make use of this in their finalize methods are the proxies used in the 36cdf0e10cSrcweir intra-process JNI UNO bridge and the inter-process Java URP UNO bridge (where 37cdf0e10cSrcweir in both cases finalizers lead to synchronous UNO release calls). 38cdf0e10cSrcweir 39cdf0e10cSrcweir If JVMs are getting more mature and should no longer have problems with 40cdf0e10cSrcweir long-running finalize mehtods, this class could be removed again. 41cdf0e10cSrcweir */ 42cdf0e10cSrcweir public final class AsynchronousFinalizer { 43cdf0e10cSrcweir /** 44cdf0e10cSrcweir Add a job to be executed asynchronously. 45cdf0e10cSrcweir 46cdf0e10cSrcweir The run method of the given job is called exactly once. If it terminates 47cdf0e10cSrcweir abnormally by throwing any Throwable, that is ignored. 48cdf0e10cSrcweir 49cdf0e10cSrcweir @param job represents the body of some finalize method; must not be null. 50cdf0e10cSrcweir */ add(Job job)51cdf0e10cSrcweir public static void add(Job job) { 52cdf0e10cSrcweir synchronized (queue) { 53cdf0e10cSrcweir boolean first = queue.isEmpty(); 54cdf0e10cSrcweir queue.add(job); 55cdf0e10cSrcweir if (first) { 56cdf0e10cSrcweir queue.notify(); 57cdf0e10cSrcweir } 58cdf0e10cSrcweir } 59cdf0e10cSrcweir } 60cdf0e10cSrcweir 61cdf0e10cSrcweir /** 62cdf0e10cSrcweir An interface to represent bodies of finalize methods. 63cdf0e10cSrcweir 64cdf0e10cSrcweir Similar to Runnable, except that the run method may throw any Throwable 65cdf0e10cSrcweir (which is effectively ignored by AsynchronousFinalizer.add, similar to 66cdf0e10cSrcweir any Throwables raised by finalize being ignored). 67cdf0e10cSrcweir */ 68cdf0e10cSrcweir public interface Job { run()69cdf0e10cSrcweir void run() throws Throwable; 70cdf0e10cSrcweir } 71cdf0e10cSrcweir 72cdf0e10cSrcweir private static final LinkedList queue = new LinkedList(); 73cdf0e10cSrcweir 74cdf0e10cSrcweir static { 75cdf0e10cSrcweir Thread t = new Thread() { 76cdf0e10cSrcweir public void run() { 77cdf0e10cSrcweir for (;;) { 78cdf0e10cSrcweir Job j; 79cdf0e10cSrcweir synchronized (queue) { 80cdf0e10cSrcweir while (queue.isEmpty()) { 81cdf0e10cSrcweir try { 82cdf0e10cSrcweir queue.wait(); 83cdf0e10cSrcweir } catch (InterruptedException e) {} 84cdf0e10cSrcweir } 85cdf0e10cSrcweir j = (Job) queue.remove(0); 86cdf0e10cSrcweir } 87cdf0e10cSrcweir try { 88cdf0e10cSrcweir j.run(); 89cdf0e10cSrcweir } catch (Throwable e) {} 90cdf0e10cSrcweir } 91cdf0e10cSrcweir } 92cdf0e10cSrcweir }; 93cdf0e10cSrcweir t.setDaemon(true); t.start()94cdf0e10cSrcweir t.start(); 95cdf0e10cSrcweir } 96cdf0e10cSrcweir AsynchronousFinalizer()97cdf0e10cSrcweir private AsynchronousFinalizer() {} 98cdf0e10cSrcweir } 99