IllegalStateException when attempting to transfer MemorySegment thread ownership

Ty Young youngty1997 at gmail.com
Mon Jul 20 09:54:23 UTC 2020


On 7/20/20 4:08 AM, Maurizio Cimadamore wrote:
>
> 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).


Yes, and that's what I'm trying to do. The MappedMemorySegment itself is 
only being closed(and, therefore, transferred) when a user attempts to 
exit the application. Every other access is from the Main thread*.


*minus literally every single derived MemorySegment.


>
> 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.


It is what it is. I just wasn't 100% if this was a bug or something 
still being worked on.


>
> Maurizio
>
> [1] - 
> https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewDirectByteBuffer
>


More information about the panama-dev mailing list