From 267c6f2ac71f92999e969232431ba04678e7437e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 07:54:39 +0200 Subject: Adding upstream version 4:24.2.0. Signed-off-by: Daniel Baumann --- .../sun/star/lib/util/AsynchronousFinalizer.java | 117 +++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 ridljar/com/sun/star/lib/util/AsynchronousFinalizer.java (limited to 'ridljar/com/sun/star/lib/util/AsynchronousFinalizer.java') diff --git a/ridljar/com/sun/star/lib/util/AsynchronousFinalizer.java b/ridljar/com/sun/star/lib/util/AsynchronousFinalizer.java new file mode 100644 index 0000000000..588b8fe388 --- /dev/null +++ b/ridljar/com/sun/star/lib/util/AsynchronousFinalizer.java @@ -0,0 +1,117 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +package com.sun.star.lib.util; + +import java.util.LinkedList; + +/** + * Helper class to asynchronously execute finalize methods. + * + *

Current JVMs seem not to be robust against long-running finalize methods, + * in that such long-running finalize methods may lead to OutOfMemoryErrors. + * This class mitigates the problem by asynchronously shifting the bodies of + * potentially long-running finalize methods into an extra thread. Classes that + * make use of this in their finalize methods are the proxies used in the + * intra-process JNI UNO bridge and the inter-process Java URP UNO bridge (where + * in both cases finalizers lead to synchronous UNO release calls).

+ * + *

Irrespective whether JVMs are getting more mature and should no longer + * have problems with long-running finalize methods, at least the JNI UNO bridge + * needs some way to stop finalization of proxies (to C++ objects) well before + * process exit, as provided by drain().

+ */ +public final class AsynchronousFinalizer { + public AsynchronousFinalizer() { + thread = new Thread("AsynchronousFinalizer") { + @Override + public void run() { + for (;;) { + Job j; + synchronized (queue) { + for (;;) { + if (done) { + return; + } + if (!queue.isEmpty()) { + break; + } + try { + queue.wait(); + } catch (InterruptedException e) { + return; + } + } + j = queue.remove(0); + } + try { + j.run(); + } catch (Throwable e) {} + } + } + }; + thread.start(); + } + + /** + * Add a job to be executed asynchronously. + * + *

The run method of the given job is called exactly once. If it terminates + * abnormally by throwing any Throwable, that is ignored.

+ * + * @param job represents the body of some finalize method; must not be null. + */ + public void add(Job job) { + synchronized (queue) { + boolean first = queue.isEmpty(); + queue.add(job); + if (first) { + queue.notify(); + } + } + } + + public void drain() throws InterruptedException { + synchronized (queue) { + done = true; + queue.notify(); + } + // tdf#123481 Only join if we are not in our own thread, else we have a deadlock + if (Thread.currentThread() != thread) + thread.join(); + } + + /** + * An interface to represent bodies of finalize methods. + * + * Similar to Runnable, except that the run method may throw any + * Throwable (which is effectively ignored by + * AsynchronousFinalizer.add, similar to any Throwables + * raised by finalize being ignored). + */ + public interface Job { + void run() throws Throwable; + } + + private final LinkedList queue = new LinkedList(); + private final Thread thread; + private boolean done = false; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3