@solid/community-server
Version:
Community Solid Server: an open and modular implementation of the Solid specifications
56 lines (55 loc) • 2.91 kB
TypeScript
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>;
}