File tree Expand file tree Collapse file tree 2 files changed +47
-2
lines changed
@aws-cdk/tmp-toolkit-helpers/src/api Expand file tree Collapse file tree 2 files changed +47
-2
lines changed Original file line number Diff line number Diff line change @@ -39,9 +39,14 @@ export class RWLock {
39
39
40
40
await writeFileAtomic ( this . writerFile , this . pidString ) ;
41
41
42
+ let released = false ;
42
43
return {
43
44
release : async ( ) => {
44
- await deleteFile ( this . writerFile ) ;
45
+ // Releasing needs a flag, otherwise we might delete a file that some other lock has created in the mean time.
46
+ if ( ! released ) {
47
+ await deleteFile ( this . writerFile ) ;
48
+ released = true ;
49
+ }
45
50
} ,
46
51
convertToReaderLock : async ( ) => {
47
52
// Acquire the read lock before releasing the write lock. Slightly less
@@ -80,9 +85,15 @@ export class RWLock {
80
85
private async doAcquireRead ( ) : Promise < IReadLock > {
81
86
const readerFile = this . readerFile ( ) ;
82
87
await writeFileAtomic ( readerFile , this . pidString ) ;
88
+
89
+ let released = false ;
83
90
return {
84
91
release : async ( ) => {
85
- await deleteFile ( readerFile ) ;
92
+ // Releasing needs a flag, otherwise we might delete a file that some other lock has created in the mean time.
93
+ if ( ! released ) {
94
+ await deleteFile ( readerFile ) ;
95
+ released = true ;
96
+ }
86
97
} ,
87
98
} ;
88
99
}
@@ -152,6 +163,9 @@ export class RWLock {
152
163
* An acquired lock
153
164
*/
154
165
export interface IReadLock {
166
+ /**
167
+ * Release the lock. Can be called more than once.
168
+ */
155
169
release ( ) : Promise < void > ;
156
170
}
157
171
Original file line number Diff line number Diff line change 1
1
/* eslint-disable import/order */
2
+ import { promises as fs } from 'node:fs' ;
2
3
import * as os from 'os' ;
3
4
import * as path from 'path' ;
4
5
import { RWLock } from '../../lib/api/rwlock' ;
@@ -51,3 +52,33 @@ test('can convert writer to reader lock', async () => {
51
52
await r . release ( ) ;
52
53
}
53
54
} ) ;
55
+
56
+ test ( 'can release writer lock more than once, second invocation does nothing' , async ( ) => {
57
+ const unlink = jest . spyOn ( fs , 'unlink' ) ;
58
+
59
+ // GIVEN
60
+ const lock = new RWLock ( testDir ( ) ) ;
61
+ const r = await lock . acquireWrite ( ) ;
62
+
63
+ // WHEN
64
+ await r . release ( ) ;
65
+ expect ( unlink ) . toHaveBeenCalledTimes ( 1 ) ;
66
+
67
+ await r . release ( ) ;
68
+ expect ( unlink ) . toHaveBeenCalledTimes ( 1 ) ;
69
+ } ) ;
70
+
71
+ test ( 'can release reader lock more than once, second invocation does nothing' , async ( ) => {
72
+ const unlink = jest . spyOn ( fs , 'unlink' ) ;
73
+
74
+ // GIVEN
75
+ const lock = new RWLock ( testDir ( ) ) ;
76
+ const r = await lock . acquireRead ( ) ;
77
+
78
+ // WHEN
79
+ await r . release ( ) ;
80
+ expect ( unlink ) . toHaveBeenCalledTimes ( 1 ) ;
81
+
82
+ await r . release ( ) ;
83
+ expect ( unlink ) . toHaveBeenCalledTimes ( 1 ) ;
84
+ } ) ;
You can’t perform that action at this time.
0 commit comments