| 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 | |
| 52 // the file lock. | |
| 53 await new Future.delayed(const Duration(seconds: 1)); | |
| 54 | |
| 55 int nextToWrite = 1; | 50 int nextToWrite = 1; |
| 56 int at = 0; | 51 int at = 0; |
| 57 List iWrote = new List.filled(length, 0); | 52 List iWrote = new List.filled(length, 0); |
| 58 bool nonBlockingFailed = false; | 53 bool nonBlockingFailed = false; |
| 59 while (nextToWrite <= length) { | 54 while (nextToWrite <= length) { |
| 60 int p = await raf.position(); | 55 int p = await raf.position(); |
| 61 await raf.writeByte(nextToWrite); | 56 await raf.writeByte(nextToWrite); |
| 62 await raf.flush(); | 57 await raf.flush(); |
| 63 // Record which bytes this process wrote so that we can check that the | 58 // 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. | 59 // other process was able to take the lock and write some bytes. |
| 65 iWrote[nextToWrite-1] = nextToWrite; | 60 iWrote[nextToWrite-1] = nextToWrite; |
| 66 nextToWrite++; | 61 nextToWrite++; |
| 67 await raf.unlock(0, length); | 62 // Let the other process get the lock at least once by spinning until the |
| 68 try { | 63 // non-blocking lock fails. |
| 69 await raf.lock(FileLock.EXCLUSIVE, 0, length); | 64 while (!nonBlockingFailed) { |
| 70 } catch(e) { | 65 await raf.unlock(0, length); |
| 71 // Check that at some point the non-blocking lock fails. | 66 try { |
| 72 nonBlockingFailed = true; | 67 await raf.lock(FileLock.EXCLUSIVE, 0, length); |
| 73 await raf.lock(FileLock.BLOCKING_EXCLUSIVE, 0, length); | 68 } catch(e) { |
| 69 // Check that at some point the non-blocking lock fails. |
| 70 nonBlockingFailed = true; |
| 71 await raf.lock(FileLock.BLOCKING_EXCLUSIVE, 0, length); |
| 72 } |
| 74 } | 73 } |
| 75 while (true) { | 74 while (true) { |
| 76 p = await raf.position(); | 75 p = await raf.position(); |
| 77 at = await raf.readByte(); | 76 at = await raf.readByte(); |
| 78 if (at == 0 || at == -1) break; | 77 if (at == 0 || at == -1) break; |
| 79 nextToWrite++; | 78 nextToWrite++; |
| 80 } | 79 } |
| 81 await raf.setPosition(p); | 80 await raf.setPosition(p); |
| 82 } | 81 } |
| 83 | 82 |
| 84 await raf.setPosition(0); | 83 await raf.setPosition(0); |
| 85 for (int i = 1; i <= length; i++) { | 84 for (int i = 1; i <= length; i++) { |
| 86 Expect.equals(i, await raf.readByte()); | 85 Expect.equals(i, await raf.readByte()); |
| 87 } | 86 } |
| 88 await raf.unlock(0, length); | 87 await raf.unlock(0, length); |
| 89 | 88 |
| 90 bool wroteAll = true; | 89 bool wroteAll = true; |
| 91 for (int i = 0; i < length; i++) { | 90 for (int i = 0; i < length; i++) { |
| 92 // If there's a 0 entry, this process didn't write all bytes. | 91 // If there's a 0 entry, this process didn't write all bytes. |
| 93 wroteAll = wroteAll && (iWrote[i] == 0); | 92 wroteAll = wroteAll && (iWrote[i] == 0); |
| 94 } | 93 } |
| 95 Expect.equals(false, wroteAll); | 94 Expect.equals(false, wroteAll); |
| 96 | 95 |
| 97 Expect.equals(true, nonBlockingFailed); | 96 Expect.equals(true, nonBlockingFailed); |
| 98 | 97 |
| 99 peer.exitCode.then((v) { | 98 await peer.exitCode.then((v) async { |
| 100 Expect.equals(0, v); | 99 Expect.equals(0, v); |
| 101 raf.closeSync(); | 100 await raf.close(); |
| 102 directory.deleteSync(recursive: true); | 101 await directory.delete(recursive: true); |
| 103 asyncEnd(); | |
| 104 }); | 102 }); |
| 105 } | 103 } |
| 106 | 104 |
| 107 main() { | 105 main() async { |
| 108 testLockWholeFile(); | 106 asyncStart(); |
| 107 await testLockWholeFile(); |
| 108 asyncEnd(); |
| 109 } | 109 } |
| OLD | NEW |