File tree Expand file tree Collapse file tree 6 files changed +104
-12
lines changed Expand file tree Collapse file tree 6 files changed +104
-12
lines changed Original file line number Diff line number Diff line change @@ -2,7 +2,7 @@ import type { MutexInterface } from 'async-mutex';
22import type { ResourceAcquire } from '@matrixai/resources' ;
33import { Mutex , withTimeout } from 'async-mutex' ;
44import { withF , withG } from '@matrixai/resources' ;
5- import { yieldMicro } from './utils' ;
5+ import { sleep , yieldMicro } from './utils' ;
66import { ErrorAsyncLocksTimeout } from './errors' ;
77
88class Lock {
@@ -43,8 +43,21 @@ class Lock {
4343 return this . _lock . isLocked ( ) ;
4444 }
4545
46- public async waitForUnlock ( ) : Promise < void > {
47- return this . _lock . waitForUnlock ( ) ;
46+ public async waitForUnlock ( timeout ?: number ) : Promise < void > {
47+ if ( timeout != null ) {
48+ let timedOut = false ;
49+ await Promise . race ( [
50+ this . _lock . waitForUnlock ( ) ,
51+ sleep ( timeout ) . then ( ( ) => {
52+ timedOut = true ;
53+ } ) ,
54+ ] ) ;
55+ if ( timedOut ) {
56+ throw new ErrorAsyncLocksTimeout ( ) ;
57+ }
58+ } else {
59+ await this . _lock . waitForUnlock ( ) ;
60+ }
4861 }
4962
5063 public async withF < T > (
Original file line number Diff line number Diff line change @@ -2,7 +2,7 @@ import type { MutexInterface } from 'async-mutex';
22import type { ResourceAcquire } from '@matrixai/resources' ;
33import { Mutex , withTimeout } from 'async-mutex' ;
44import { withF , withG } from '@matrixai/resources' ;
5- import { yieldMicro } from './utils' ;
5+ import { sleep , yieldMicro } from './utils' ;
66import { ErrorAsyncLocksTimeout } from './errors' ;
77
88/**
@@ -83,8 +83,21 @@ class RWLockReader {
8383 return this . lock . isLocked ( ) ;
8484 }
8585
86- public async waitForUnlock ( ) : Promise < void > {
87- return this . lock . waitForUnlock ( ) ;
86+ public async waitForUnlock ( timeout ?: number ) : Promise < void > {
87+ if ( timeout != null ) {
88+ let timedOut = false ;
89+ await Promise . race ( [
90+ this . lock . waitForUnlock ( ) ,
91+ sleep ( timeout ) . then ( ( ) => {
92+ timedOut = true ;
93+ } ) ,
94+ ] ) ;
95+ if ( timedOut ) {
96+ throw new ErrorAsyncLocksTimeout ( ) ;
97+ }
98+ } else {
99+ await this . lock . waitForUnlock ( ) ;
100+ }
88101 }
89102
90103 public async withReadF < T > (
Original file line number Diff line number Diff line change @@ -135,12 +135,27 @@ class RWLockWriter {
135135 return this . readersLock . isLocked ( ) || this . writersLock . isLocked ( ) ;
136136 }
137137
138- public async waitForUnlock ( ) : Promise < void > {
139- await Promise . all ( [
140- this . readersLock . waitForUnlock ( ) ,
141- this . writersLock . waitForUnlock ( ) ,
142- ] ) ;
143- return ;
138+ public async waitForUnlock ( timeout ?: number ) : Promise < void > {
139+ if ( timeout != null ) {
140+ let timedOut = false ;
141+ await Promise . race ( [
142+ Promise . all ( [
143+ this . readersLock . waitForUnlock ( ) ,
144+ this . writersLock . waitForUnlock ( ) ,
145+ ] ) ,
146+ sleep ( timeout ) . then ( ( ) => {
147+ timedOut = true ;
148+ } ) ,
149+ ] ) ;
150+ if ( timedOut ) {
151+ throw new ErrorAsyncLocksTimeout ( ) ;
152+ }
153+ } else {
154+ await Promise . all ( [
155+ this . readersLock . waitForUnlock ( ) ,
156+ this . writersLock . waitForUnlock ( ) ,
157+ ] ) ;
158+ }
144159 }
145160
146161 public async withReadF < T > (
Original file line number Diff line number Diff line change @@ -195,4 +195,21 @@ describe(Lock.name, () => {
195195 expect ( lock . isLocked ( ) ) . toBe ( false ) ;
196196 expect ( lock . count ) . toBe ( 0 ) ;
197197 } ) ;
198+ test ( 'timeout waiting for unlock' , async ( ) => {
199+ const lock = new Lock ( ) ;
200+ await lock . waitForUnlock ( 100 ) ;
201+ await withF ( [ lock . lock ( ) ] , async ( [ lock ] ) => {
202+ await expect ( lock . waitForUnlock ( 100 ) ) . rejects . toThrow (
203+ errors . ErrorAsyncLocksTimeout ,
204+ ) ;
205+ } ) ;
206+ await lock . waitForUnlock ( 100 ) ;
207+ const g = withG ( [ lock . lock ( ) ] , async function * ( [ lock ] ) {
208+ await expect ( lock . waitForUnlock ( 100 ) ) . rejects . toThrow (
209+ errors . ErrorAsyncLocksTimeout ,
210+ ) ;
211+ } ) ;
212+ await g . next ( ) ;
213+ await lock . waitForUnlock ( 100 ) ;
214+ } ) ;
198215} ) ;
Original file line number Diff line number Diff line change @@ -445,4 +445,21 @@ describe(RWLockReader.name, () => {
445445 expect ( lock . readerCount ) . toBe ( 0 ) ;
446446 expect ( lock . writerCount ) . toBe ( 0 ) ;
447447 } ) ;
448+ test ( 'timeout waiting for unlock' , async ( ) => {
449+ const lock = new RWLockReader ( ) ;
450+ await lock . waitForUnlock ( 100 ) ;
451+ await withF ( [ lock . read ( ) ] , async ( [ lock ] ) => {
452+ await expect ( lock . waitForUnlock ( 100 ) ) . rejects . toThrow (
453+ errors . ErrorAsyncLocksTimeout ,
454+ ) ;
455+ } ) ;
456+ await lock . waitForUnlock ( 100 ) ;
457+ const g = withG ( [ lock . write ( ) ] , async function * ( [ lock ] ) {
458+ await expect ( lock . waitForUnlock ( 100 ) ) . rejects . toThrow (
459+ errors . ErrorAsyncLocksTimeout ,
460+ ) ;
461+ } ) ;
462+ await g . next ( ) ;
463+ await lock . waitForUnlock ( 100 ) ;
464+ } ) ;
448465} ) ;
Original file line number Diff line number Diff line change @@ -442,4 +442,21 @@ describe(RWLockWriter.name, () => {
442442 expect ( lock . readerCount ) . toBe ( 0 ) ;
443443 expect ( lock . writerCount ) . toBe ( 0 ) ;
444444 } ) ;
445+ test ( 'timeout waiting for unlock' , async ( ) => {
446+ const lock = new RWLockWriter ( ) ;
447+ await lock . waitForUnlock ( 100 ) ;
448+ await withF ( [ lock . read ( ) ] , async ( [ lock ] ) => {
449+ await expect ( lock . waitForUnlock ( 100 ) ) . rejects . toThrow (
450+ errors . ErrorAsyncLocksTimeout ,
451+ ) ;
452+ } ) ;
453+ await lock . waitForUnlock ( 100 ) ;
454+ const g = withG ( [ lock . write ( ) ] , async function * ( [ lock ] ) {
455+ await expect ( lock . waitForUnlock ( 100 ) ) . rejects . toThrow (
456+ errors . ErrorAsyncLocksTimeout ,
457+ ) ;
458+ } ) ;
459+ await g . next ( ) ;
460+ await lock . waitForUnlock ( 100 ) ;
461+ } ) ;
445462} ) ;
You can’t perform that action at this time.
0 commit comments