OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 // This test works by spawning a new process running | 5 // This test works by spawning a new process running |
6 // file_blocking_lock_script.dart, trading the file lock back and forth, | 6 // file_blocking_lock_script.dart, trading the file lock back and forth, |
7 // writing bytes 1 ... 25 in order to the file. There are checks to ensure | 7 // writing bytes 1 ... 25 in order to the file. There are checks to ensure |
8 // that the bytes are written in order, that one process doesn't write all the | 8 // that the bytes are written in order, that one process doesn't write all the |
9 // bytes and that a non-blocking lock fails such that a blocking lock must | 9 // bytes and that a non-blocking lock fails such that a blocking lock must |
10 // be taken, which succeeds. | 10 // be taken, which succeeds. |
(...skipping 21 matching lines...) Expand all Loading... | |
32 .listen((data) { print(data); }); | 32 .listen((data) { print(data); }); |
33 process.stderr | 33 process.stderr |
34 .transform(UTF8.decoder) | 34 .transform(UTF8.decoder) |
35 .listen((data) { print(data); }); | 35 .listen((data) { print(data); }); |
36 return process; | 36 return process; |
37 }); | 37 }); |
38 } | 38 } |
39 | 39 |
40 testLockWholeFile() async { | 40 testLockWholeFile() async { |
41 const int length = 25; | 41 const int length = 25; |
42 asyncStart(); | |
43 Directory directory = await Directory.systemTemp.createTemp('dart_file_lock'); | 42 Directory directory = await Directory.systemTemp.createTemp('dart_file_lock'); |
44 File file = new File(join(directory.path, "file")); | 43 File file = new File(join(directory.path, "file")); |
45 await file.writeAsBytes(new List.filled(length, 0)); | 44 await file.writeAsBytes(new List.filled(length, 0)); |
46 var raf = await file.open(mode: APPEND); | 45 var raf = await file.open(mode: APPEND); |
47 await raf.setPosition(0); | 46 await raf.setPosition(0); |
48 await raf.lock(FileLock.BLOCKING_EXCLUSIVE, 0, length); | 47 await raf.lock(FileLock.BLOCKING_EXCLUSIVE, 0, length); |
49 Process peer = await runPeer(file.path, length, FileLock.BLOCKING_EXCLUSIVE); | 48 Process peer = await runPeer(file.path, length, FileLock.BLOCKING_EXCLUSIVE); |
50 | 49 |
51 // Wait a bit for the other process to get started. We'll synchronize on | 50 // Wait a bit for the other process to get started. We'll synchronize on |
52 // the file lock. | 51 // the file lock. |
53 await new Future.delayed(const Duration(seconds: 1)); | 52 await new Future.delayed(const Duration(seconds: 1)); |
Florian Schneider
2016/06/14 16:46:51
Is this wait still necessary now with your change?
zra
2016/06/14 17:04:22
No. Removed.
| |
54 | 53 |
55 int nextToWrite = 1; | 54 int nextToWrite = 1; |
56 int at = 0; | 55 int at = 0; |
57 List iWrote = new List.filled(length, 0); | 56 List iWrote = new List.filled(length, 0); |
58 bool nonBlockingFailed = false; | 57 bool nonBlockingFailed = false; |
59 while (nextToWrite <= length) { | 58 while (nextToWrite <= length) { |
60 int p = await raf.position(); | 59 int p = await raf.position(); |
61 await raf.writeByte(nextToWrite); | 60 await raf.writeByte(nextToWrite); |
62 await raf.flush(); | 61 await raf.flush(); |
63 // Record which bytes this process wrote so that we can check that the | 62 // Record which bytes this process wrote so that we can check that the |
64 // other process was able to take the lock and write some bytes. | 63 // other process was able to take the lock and write some bytes. |
65 iWrote[nextToWrite-1] = nextToWrite; | 64 iWrote[nextToWrite-1] = nextToWrite; |
66 nextToWrite++; | 65 nextToWrite++; |
67 await raf.unlock(0, length); | 66 // Let the other process get the lock at least once by spinning until the |
68 try { | 67 // non-blocking lock fails. |
69 await raf.lock(FileLock.EXCLUSIVE, 0, length); | 68 while (!nonBlockingFailed) { |
70 } catch(e) { | 69 await raf.unlock(0, length); |
71 // Check that at some point the non-blocking lock fails. | 70 try { |
72 nonBlockingFailed = true; | 71 await raf.lock(FileLock.EXCLUSIVE, 0, length); |
73 await raf.lock(FileLock.BLOCKING_EXCLUSIVE, 0, length); | 72 } catch(e) { |
73 // Check that at some point the non-blocking lock fails. | |
74 nonBlockingFailed = true; | |
75 await raf.lock(FileLock.BLOCKING_EXCLUSIVE, 0, length); | |
76 } | |
74 } | 77 } |
75 while (true) { | 78 while (true) { |
76 p = await raf.position(); | 79 p = await raf.position(); |
77 at = await raf.readByte(); | 80 at = await raf.readByte(); |
78 if (at == 0 || at == -1) break; | 81 if (at == 0 || at == -1) break; |
79 nextToWrite++; | 82 nextToWrite++; |
80 } | 83 } |
81 await raf.setPosition(p); | 84 await raf.setPosition(p); |
82 } | 85 } |
83 | 86 |
84 await raf.setPosition(0); | 87 await raf.setPosition(0); |
85 for (int i = 1; i <= length; i++) { | 88 for (int i = 1; i <= length; i++) { |
86 Expect.equals(i, await raf.readByte()); | 89 Expect.equals(i, await raf.readByte()); |
87 } | 90 } |
88 await raf.unlock(0, length); | 91 await raf.unlock(0, length); |
89 | 92 |
90 bool wroteAll = true; | 93 bool wroteAll = true; |
91 for (int i = 0; i < length; i++) { | 94 for (int i = 0; i < length; i++) { |
92 // If there's a 0 entry, this process didn't write all bytes. | 95 // If there's a 0 entry, this process didn't write all bytes. |
93 wroteAll = wroteAll && (iWrote[i] == 0); | 96 wroteAll = wroteAll && (iWrote[i] == 0); |
94 } | 97 } |
95 Expect.equals(false, wroteAll); | 98 Expect.equals(false, wroteAll); |
96 | 99 |
97 Expect.equals(true, nonBlockingFailed); | 100 Expect.equals(true, nonBlockingFailed); |
98 | 101 |
99 peer.exitCode.then((v) { | 102 await peer.exitCode.then((v) async { |
100 Expect.equals(0, v); | 103 Expect.equals(0, v); |
101 raf.closeSync(); | 104 await raf.close(); |
102 directory.deleteSync(recursive: true); | 105 await directory.delete(recursive: true); |
103 asyncEnd(); | |
104 }); | 106 }); |
105 } | 107 } |
106 | 108 |
107 main() { | 109 main() async { |
108 testLockWholeFile(); | 110 asyncStart(); |
111 await testLockWholeFile(); | |
112 asyncEnd(); | |
109 } | 113 } |
OLD | NEW |