IllegalStateException when attempting to transfer MemorySegment thread ownership
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Mon Jul 20 09:08:55 UTC 2020
On 20/07/2020 08:59, Ty Young wrote:
> When attempting to transfer thread ownership of a MappedMemorySegment,
> an IllegalStateException is thrown:
>
>
> java.lang.IllegalStateException: Attempted access outside owning thread
>
>
> with the following code:
>
>
> MappedMemorySegment segment;
>
> System.out.println("Owner: " + this.address.segment().ownerThread());
> System.out.println("Current: " + Thread.currentThread());
>
> if(this.address.segment().ownerThread().equals(Thread.currentThread()))
> segment = (MappedMemorySegment)this.getAddress().segment();
>
> else
> segment =
> (MappedMemorySegment)this.getAddress().segment().withOwnerThread(Thread.currentThread());
>
>
> This error happens when closing my JavaFX application via its close
> handler on the above else branch. The application calls a static
> method which eventually creates the MappedMemorySegment on the main
> thread but the close handler works on the JavaFX thread as shown from
> the print output:
>
>
> Owner: Thread[main,5,main]
> Current: Thread[JavaFX Application Thread,5,main]
>
>
> I tried using unsafe MemorySegment.ofNativeRestricted to make the
> segment thread independent, but it doesn't work out due to
> MemorySegment.ofNativeRestricted always returning a pure
> MemorySegmentImpl implementation instead of the
> **Mapped**MemorySegmentImpl. I'm guessing this is a bug?
>
Too clarify thing - do you agree that the exception you get (while
annoying) is normal behavior (e.g. attempting to transfer ownership from
different thread). "withOwnerThread" is meant to be used in cases where
thread A wants to deliberately give ownership of its own segment to
thread B (e.g. in a reader/writer kind of use case). It's still one
thread at a time (serial confinement).
I understand you are trying to use ofNativeRestricted as a workaround to
remove ownership restriction on a mapped segment, but that method
creates an ordinary native segment, so you won't be able to call force
and/or unmap via close(). ofNativeRestricted is really a replacement for
the JNI's NewDirectByteBuffer function [1], so it cannot be used to
create a mapped segment out of an arbitrary address.
This is why we are looking for ways/opt ins to relax confinement
restrictions, so that unconfinement segments might be made available w/o
workarounds. We're not there yet.
Maurizio
[1] -
https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewDirectByteBuffer
More information about the panama-dev
mailing list