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