import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier';
import type { PromiseOrValue } from '../PromiseUtil';
import { EqualReadWriteLocker } from './EqualReadWriteLocker';
import type { ResourceLocker } from './ResourceLocker';
/**
 * A {@link ReadWriteLocker} that allows for multiple simultaneous read operations.
 * Write operations will be blocked as long as read operations are not finished.
 * New read operations are allowed while this is going on, which will cause write operations to wait longer.
 *
 * Based on https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock#Using_two_mutexes .
 * As soon as 1 read lock request is made, the main lock is locked.
 * Internally a counter keeps track of the amount of active read locks.
 * Only when this number reaches 0 will the main lock be released again.
 * The internal count lock is only locked to increase/decrease this counter and is released afterwards.
 * This allows for multiple read operations, although only 1 at the time can update the counter,
 * which means there can still be a small waiting period if there are multiple simultaneous read operations.
 *
 * Classes extending this need to implement `getCountLockIdentifier` and `modifyCount`.
 */
export declare abstract class BaseReadWriteLocker extends EqualReadWriteLocker {
    protected readonly countLocker: ResourceLocker;
    /**
     * @param resourceLocker - Used for creating read and write locks.
     * @param countLocker - Used for creating locks when updating the counter.
     */
    protected constructor(resourceLocker: ResourceLocker, countLocker: ResourceLocker);
    withReadLock<T>(identifier: ResourceIdentifier, whileLocked: () => PromiseOrValue<T>): Promise<T>;
    /**
     * Safely updates the count before starting a read operation.
     */
    private acquireReadLock;
    /**
     * Safely decreases the count after the read operation is finished.
     */
    private releaseReadLock;
    /**
     * Safely runs an action on the count.
     */
    private withInternalCountLock;
    /**
     * Generate the identifier that will be used to acquire the count lock for the given identifier.
     * There will be cases where this lock needs to be acquired
     * while an active lock on the main resource is still being maintained.
     * This means that if the input `resourceLocker` and `countLocker` use the same locking system
     * this generated identifier needs to be different.
     */
    protected abstract getCountLockIdentifier(identifier: ResourceIdentifier): ResourceIdentifier;
    /**
     * Update the counter that keeps track of having open read locks there currently are.
     * @param identifier - Identifier on which to update the number of read locks.
     * @param mod - `+1` or `-1`.
     */
    protected abstract modifyCount(identifier: ResourceIdentifier, mod: number): PromiseOrValue<number>;
}
