8319928: Exceptions thrown by cleanup actions should be handled correctly

Reviewed-by: jvernee
This commit is contained in:
Maurizio Cimadamore 2023-11-20 15:02:11 +00:00
parent a6098e438d
commit 7f231109c2
3 changed files with 86 additions and 2 deletions

View file

@ -29,6 +29,7 @@ import jdk.internal.foreign.MemorySessionImpl;
import jdk.internal.ref.CleanerFactory;
import java.lang.foreign.MemorySegment.Scope;
import java.util.function.Consumer;
/**
* An arena controls the lifecycle of native memory segments, providing both flexible
@ -317,8 +318,11 @@ public interface Arena extends SegmentAllocator, AutoCloseable {
* @throws WrongThreadException if this arena is confined, and this method is called
* from a thread other than the arena's owner thread
* @throws UnsupportedOperationException if this arena cannot be closed explicitly
* @throws RuntimeException if an exception is thrown while executing a custom cleanup action
* associated with this arena (e.g. as a result of calling
* {@link MemorySegment#reinterpret(long, Arena, Consumer)} or
* {@link MemorySegment#reinterpret(Arena, Consumer)}).
*/
@Override
void close();
}

View file

@ -254,11 +254,24 @@ public abstract sealed class MemorySessionImpl
}
static void cleanup(ResourceCleanup first) {
RuntimeException pendingException = null;
ResourceCleanup current = first;
while (current != null) {
current.cleanup();
try {
current.cleanup();
} catch (RuntimeException ex) {
if (pendingException == null) {
pendingException = ex;
} else if (ex != pendingException) {
// note: self-suppression is not supported
pendingException.addSuppressed(ex);
}
}
current = current.next;
}
if (pendingException != null) {
throw pendingException;
}
}
public abstract static class ResourceCleanup {