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