Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { isMissing, isNumber } from "@esfx/internal-guards";
import { maxInt32 as MAX_INT32 } from "@esfx/internal-integers";
import { Tag } from "@esfx/internal-tag";
import { WaitQueue } from "@esfx/async-waitqueue";
import { Cancelable } from "@esfx/cancelable";
/**
* Limits the number of asynchronous operations that can access a resource
* or pool of resources.
*/
@Tag()
export class AsyncSemaphore {
private _maxCount: number;
private _currentCount: number;
private _waiters = new WaitQueue();
/**
* Initializes a new instance of the Semaphore class.
*
* @param initialCount The initial number of entries.
* @param maxCount The maximum number of entries.
*/
constructor(initialCount: number, maxCount?: number) {
if (isMissing(maxCount)) maxCount = MAX_INT32;
if (!isNumber(initialCount)) throw new TypeError("Number expected: initialCount.");
if (!isNumber(maxCount)) throw new TypeError("Number expected: maxCount.");
if ((initialCount |= 0) < 0) throw new RangeError("Argument out of range: initialCount.");
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { isMissing, isBoolean } from "@esfx/internal-guards";
import { Tag } from "@esfx/internal-tag";
import { Cancelable } from "@esfx/cancelable";
import { WaitQueue } from "@esfx/async-waitqueue";
/**
* Asynchronously notifies one or more waiting Promises that an event has occurred.
*/
@Tag()
export class AsyncManualResetEvent {
private _signaled: boolean;
private _waiters = new WaitQueue();
/**
* Initializes a new instance of the ManualResetEvent class.
*
* @param initialState A value indicating whether to set the initial state to signaled.
*/
constructor(initialState?: boolean) {
if (isMissing(initialState)) initialState = false;
if (!isBoolean(initialState)) throw new TypeError("Boolean expected: initialState.");
this._signaled = !!initialState;
}
/**
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { isMissing, isNumber, isFunction } from "@esfx/internal-guards";
import { Tag } from "@esfx/internal-tag";
import { Cancelable } from "@esfx/cancelable";
import { WaitQueue } from "@esfx/async-waitqueue";
/**
* Enables multiple tasks to cooperatively work on an algorithm through
* multiple phases.
*/
@Tag()
export class AsyncBarrier {
private _isExecutingPostPhaseAction = false;
private _postPhaseAction: ((barrier: AsyncBarrier) => void | PromiseLike) | undefined;
private _phaseNumber: number = 0;
private _participantCount: number;
private _remainingParticipants: number;
private _waiters = new WaitQueue();
/**
* Initializes a new instance of the Barrier class.
*
* @param participantCount The initial number of participants for the barrier.
* @param postPhaseAction An action to execute between each phase.
*/
constructor(participantCount: number, postPhaseAction?: (barrier: AsyncBarrier) => void | PromiseLike) {
if (!isNumber(participantCount)) throw new TypeError("Number expected: participantCount.");
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { Tag } from "@esfx/internal-tag";
/**
* Encapsulates a Promise and exposes its resolve and reject callbacks.
*/
@Tag()
export class Deferred {
private _promise: Promise;
private _resolve!: (value?: PromiseLike | T) => void;
private _reject!: (reason: any) => void;
private _callback?: (err: Error | null | undefined, value: T) => void;
/**
* Initializes a new instance of the Deferred class.
*/
constructor() {
this._promise = new Promise((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
});
}
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { Tag, defineTag } from "@esfx/internal-tag";
import { AsyncLockable, LockHandle } from "@esfx/async-lockable";
import { WaitQueue } from "@esfx/async-waitqueue";
import { Cancelable } from "@esfx/cancelable";
import { Disposable } from "@esfx/disposable";
/**
* An async coordination primitive used to coordinate access to a protected resource.
*/
@Tag()
export class AsyncMutex implements AsyncLockable {
private _waiters = new WaitQueue();
private _handle: LockHandle | undefined;
/**
* Indicates whether the lock has been taken.
*/
get isLocked() {
return this._handle !== undefined;
}
/**
* Asynchronously waits for the lock to become available and then takes the lock.
* @param cancelable A `Cancelable` used to cancel the pending request.
*/
async lock(cancelable?: Cancelable): Promise> {
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { isBoolean } from "@esfx/internal-guards";
import { Tag } from "@esfx/internal-tag";
import { Cancelable } from "@esfx/cancelable";
import { WaitQueue } from "@esfx/async-waitqueue";
/**
* Represents a synchronization event that, when signaled, resets automatically after releasing a
* single waiting asynchronous operation.
*/
@Tag()
export class AsyncAutoResetEvent {
private _signaled: boolean;
private _waiters = new WaitQueue();
/**
* Initializes a new instance of the AutoResetEvent class.
* @param initialState A value indicating whether to set the initial state to signaled.
*/
constructor(initialState = false) {
if (!isBoolean(initialState)) throw new TypeError("Boolean expected: initialState.");
this._signaled = initialState;
}
/**
* Sets the state of the event to signaled, resolving at most one waiting Promise.
* The event is then automatically reset.
const writerPrototype: object = {};
defineTag(writerPrototype, "AsyncReaderWriterLockWriter");
Object.setPrototypeOf(writerPrototype, lockHandlePrototype);
const upgradeableReaderPrototype: object = {};
defineTag(upgradeableReaderPrototype, "AsyncReaderWriterLockUpgradeableReader");
Object.setPrototypeOf(upgradeableReaderPrototype, readerPrototype);
const upgradedWriterPrototype: object = {};
defineTag(upgradedWriterPrototype, "AsyncReaderWriterLockUpgradedWriter");
Object.setPrototypeOf(upgradedWriterPrototype, writerPrototype);
/**
* Coordinates readers and writers for a resource.
*/
@Tag()
export class AsyncReaderWriterLock {
private _readerQueue = new WaitQueue();
private _writerQueue = new WaitQueue();
private _readers = new Set();
private _writer: LockHandle | undefined;
private _upgradeable: LockHandle | undefined;
/**
* Creates a `AsyncReaderWriterLockReader` that can be used to take and release "read" locks on a resource.
*/
createReader() {
const owner = this;
const handle: AsyncReaderWriterLockReader = Object.setPrototypeOf({
get owner() {
return owner;
},
readonly token: CancelToken;
/**
* Cancels the source, evaluating any subscribed callbacks. If any callback raises an exception,
* the exception is propagated to a host specific unhanedle exception mechanism.
*/
cancel(): void;
/**
* Closes the source, preventing the possibility of future cancellation.
*/
close(): void;
}
/**
* Propagates notifications that operations should be canceled.
*/
@Tag()
export class CancelToken implements Cancelable, CancelSignal {
static readonly none = closedSource.token;
static readonly canceled = canceledSource.token;
private _state!: CancelState;
private constructor() {
throw new TypeError("Object not creatable.");
}
/**
* Gets a value indicating whether the token is signaled.
*/
get signaled() {
return this._state.getState() === "signaled";
}
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { isMissing, isNumber } from "@esfx/internal-guards";
import { Tag } from "@esfx/internal-tag";
import { Cancelable } from "@esfx/cancelable";
import { AsyncManualResetEvent } from "@esfx/async-manualresetevent";
/**
* An event that is set when all participants have signaled.
*/
@Tag()
export class AsyncCountdownEvent {
private _initialCount: number;
private _remainingCount: number;
private _event: AsyncManualResetEvent;
/**
* Initializes a new instance of the CountdownEvent class.
*
* @param initialCount The initial participant count.
*/
constructor(initialCount: number) {
if (!isNumber(initialCount)) throw new TypeError("Number expected: initialCount.");
if ((initialCount |= 0) < 0) throw new RangeError("Argument out of range: initialCount.");
this._initialCount = initialCount;
this._remainingCount = initialCount;