class StoreCopyCheckPointMutex {

    public Resource storeCopy( ThrowingAction<IOException> beforeFirstConcurrentStoreCopy ) throws IOException
    {
        Lock readLock = lock.readLock();
        boolean firstConcurrentRead = incrementCount() == 0;
        boolean success = false;
        try
        {
            if ( firstConcurrentRead )
            {
                try
                {
                    beforeFirstConcurrentStoreCopy.apply();
                }
                catch ( IOException e )
                {
                    storeCopyActionError = e;
                    throw e;
                }
                catch ( Throwable e )
                {
                    storeCopyActionError = e;
                    throw new IOException( e );
                }
                storeCopyActionCompleted = true;
            }
            else
            {
                // Wait for the "before" first store copy to complete
                waitForFirstStoreCopyActionToComplete();
            }
            success = true;
        }
        finally
        {
            if ( success )
            {
                readLock.lock();
            }
            else
            {
                decrementCount();
            }
        }

        return () ->
        {
            // Decrement concurrent store-copy count
            decrementCount();
            readLock.unlock();
        };
    }

    public  StoreCopyCheckPointMutex();
    public  StoreCopyCheckPointMutex( ReadWriteLock lock );

}