Skip to content

Commit

Permalink
Revise thread-safety logic
Browse files Browse the repository at this point in the history
  • Loading branch information
tpietzsch committed May 7, 2024
1 parent 2798d33 commit f53359f
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 41 deletions.
12 changes: 10 additions & 2 deletions src/main/java/net/imglib2/blocks/FallbackPrimitiveBlocks.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import net.imglib2.loops.LoopBuilder;
import net.imglib2.type.NativeType;
import net.imglib2.type.NativeTypeFactory;
import net.imglib2.util.Cast;
import net.imglib2.util.Util;
import net.imglib2.view.Views;

Expand All @@ -66,8 +67,8 @@ public FallbackPrimitiveBlocks( final RandomAccessible< T > source, final T type
if ( type.getEntitiesPerPixel().getRatio() != 1 )
throw new IllegalArgumentException( "Types with entitiesPerPixel != 1 are not supported" );

nativeTypeFactory = ( NativeTypeFactory< T, A > ) type.getNativeTypeFactory();
primitiveTypeProperties = ( PrimitiveTypeProperties< ?, A > ) PrimitiveTypeProperties.get( nativeTypeFactory.getPrimitiveType() );
nativeTypeFactory = Cast.unchecked( type.getNativeTypeFactory() );
primitiveTypeProperties = Cast.unchecked( PrimitiveTypeProperties.get( nativeTypeFactory.getPrimitiveType() ) );
}

@Override
Expand All @@ -85,6 +86,13 @@ public void copy( final long[] srcPos, final Object dest, final int[] size )
LoopBuilder.setImages( Views.interval( source, interval ), img ).forEachPixel( ( a, b ) -> b.set( a ) );
}

@Override
public PrimitiveBlocks< T > independentCopy()
{
// NB FallbackPrimitiveBlocks is stateless
return this;
}

@Override
public PrimitiveBlocks< T > threadSafe()
{
Expand Down
14 changes: 8 additions & 6 deletions src/main/java/net/imglib2/blocks/PrimitiveBlocks.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@
*/
package net.imglib2.blocks;

import static net.imglib2.blocks.PrimitiveBlocks.OnFallback.FAIL;
import static net.imglib2.blocks.PrimitiveBlocks.OnFallback.WARN;

import net.imglib2.RandomAccessible;
import net.imglib2.type.NativeType;
import net.imglib2.util.Util;

import static net.imglib2.blocks.PrimitiveBlocks.OnFallback.FAIL;
import static net.imglib2.blocks.PrimitiveBlocks.OnFallback.WARN;


/**
* Copy blocks of data out of a {@code NativeType<T>} source into primitive
Expand Down Expand Up @@ -77,7 +77,7 @@
* If a source {@code RandomAccessible} cannot be understood, {@link
* PrimitiveBlocks#of(RandomAccessible) PrimitiveBlocks.of} will return a
* fall-back implementation (based on {@code LoopBuilder}).
*
* <p>
* With the optional {@link OnFallback OnFallback} argument to {@link
* PrimitiveBlocks#of(RandomAccessible, OnFallback) PrimitiveBlocks.of} it can
* be configured, whether
Expand Down Expand Up @@ -144,6 +144,8 @@ default void copy( int[] srcPos, Object dest, int[] size )
*/
PrimitiveBlocks< T > threadSafe();

PrimitiveBlocks< T > independentCopy();

enum OnFallback
{
ACCEPT,
Expand Down Expand Up @@ -197,11 +199,11 @@ static < T extends NativeType< T > > PrimitiveBlocks< T > of(
* @return a {@code PrimitiveBlocks} accessor for {@code ra}.
* @param <T> pixel type
*/
static < T extends NativeType< T >, R extends NativeType< R > > PrimitiveBlocks< T > of(
static < T extends NativeType< T > > PrimitiveBlocks< T > of(
RandomAccessible< T > ra,
OnFallback onFallback )
{
final ViewPropertiesOrError< T, R > props = ViewAnalyzer.getViewProperties( ra );
final ViewPropertiesOrError< T, ? > props = ViewAnalyzer.getViewProperties( ra );
if ( props.isFullySupported() )
{
return new ViewPrimitiveBlocks<>( props.getViewProperties() );
Expand Down
28 changes: 1 addition & 27 deletions src/main/java/net/imglib2/blocks/PrimitiveBlocksUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,41 +34,15 @@
package net.imglib2.blocks;

import java.util.Arrays;
import java.util.function.Supplier;

import net.imglib2.img.array.ArrayImg;
import net.imglib2.img.array.ArrayImgFactory;
import net.imglib2.img.basictypeaccess.array.ArrayDataAccess;
import net.imglib2.transform.integer.MixedTransform;
import net.imglib2.type.NativeType;
import net.imglib2.util.CloseableThreadLocal;

class PrimitiveBlocksUtils
{
static < T extends NativeType< T > > PrimitiveBlocks< T > threadSafe( final Supplier< PrimitiveBlocks< T > > supplier )
{
final CloseableThreadLocal< PrimitiveBlocks< T > > tl = CloseableThreadLocal.withInitial( supplier );
return new PrimitiveBlocks< T >()
{
@Override
public T getType()
{
return tl.get().getType();
}

@Override
public void copy( final long[] srcPos, final Object dest, final int[] size )
{
tl.get().copy( srcPos, dest, size );
}

@Override
public PrimitiveBlocks< T > threadSafe()
{
return this;
}
};
}

static < T extends NativeType< T > > Object extractOobValue( final T type, final Extension extension )
{
if ( extension.type() == Extension.Type.CONSTANT )
Expand Down
45 changes: 39 additions & 6 deletions src/main/java/net/imglib2/blocks/ViewPrimitiveBlocks.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Expand All @@ -33,14 +33,17 @@
*/
package net.imglib2.blocks;

import static net.imglib2.blocks.PrimitiveBlocksUtils.extractOobValue;

import java.util.function.Supplier;

import net.imglib2.transform.integer.MixedTransform;
import net.imglib2.type.NativeType;
import net.imglib2.type.PrimitiveType;
import net.imglib2.util.Cast;
import net.imglib2.util.CloseableThreadLocal;
import net.imglib2.util.Intervals;

import static net.imglib2.blocks.PrimitiveBlocksUtils.extractOobValue;

class ViewPrimitiveBlocks< T extends NativeType< T >, R extends NativeType< R > > implements PrimitiveBlocks< T >
{
private final ViewProperties< T, R > props;
Expand All @@ -58,6 +61,8 @@ class ViewPrimitiveBlocks< T extends NativeType< T >, R extends NativeType< R >

private final Convert convert;

private Supplier< PrimitiveBlocks< T > > threadSafeSupplier;

public ViewPrimitiveBlocks( final ViewProperties< T, R > props )
{
this.props = props;
Expand Down Expand Up @@ -156,10 +161,38 @@ else if ( doConvert )
@Override
public PrimitiveBlocks< T > threadSafe()
{
return PrimitiveBlocksUtils.threadSafe( this::newInstance );
if ( threadSafeSupplier == null )
threadSafeSupplier = CloseableThreadLocal.withInitial( this::independentCopy )::get;
return new PrimitiveBlocks< T >()
{
@Override
public T getType()
{
return props.getViewType();
}

@Override
public void copy( final long[] srcPos, final Object dest, final int[] size )
{
threadSafeSupplier.get().copy( srcPos, dest, size );
}

@Override
public PrimitiveBlocks< T > independentCopy()
{
return ViewPrimitiveBlocks.this.independentCopy().threadSafe();
}

@Override
public PrimitiveBlocks< T > threadSafe()
{
return this;
}
};
}

ViewPrimitiveBlocks< T, R > newInstance()
@Override
public PrimitiveBlocks< T > independentCopy()
{
return new ViewPrimitiveBlocks<>( this );
}
Expand Down

0 comments on commit f53359f

Please sign in to comment.