Chromium Code Reviews| Index: sdk/lib/io/file_impl.dart |
| diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart |
| index 1dce796efc46c74f6049a15b331138c286971bf2..04f56c7417bb519376c4c28ef821322eee149399 100644 |
| --- a/sdk/lib/io/file_impl.dart |
| +++ b/sdk/lib/io/file_impl.dart |
| @@ -531,17 +531,13 @@ class _File extends FileSystemEntity implements File { |
| class _RandomAccessFile implements RandomAccessFile { |
| final String path; |
| int _id; |
| + bool _asyncDispatched = false; |
| SendPort _fileService; |
| _RandomAccessFile(int this._id, String this.path); |
| Future<RandomAccessFile> close() { |
| - if (closed) return _closedException(); |
| - // Set the id_ to 0 (NULL) to ensure the no more async requests |
| - // can be issued for this file. |
| - int id = _id; |
| - _id = 0; |
| - return _IOService.dispatch(_FILE_CLOSE, [id]).then((result) { |
| + return _dispatch(_FILE_CLOSE, [_id], markClosed: true).then((result) { |
| if (result != -1) { |
| _id = result; |
| return this; |
| @@ -563,8 +559,7 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| Future<int> readByte() { |
| - if (closed) return _closedException(); |
| - return _IOService.dispatch(_FILE_READ_BYTE, [_id]).then((response) { |
| + return _dispatch(_FILE_READ_BYTE, [_id]).then((response) { |
| if (_isErrorResponse(response)) { |
| throw _exceptionFromResponse(response, "readByte failed", path); |
| } |
| @@ -587,8 +582,7 @@ class _RandomAccessFile implements RandomAccessFile { |
| if (bytes is !int) { |
| throw new ArgumentError(bytes); |
| } |
| - if (closed) return _closedException(); |
| - return _IOService.dispatch(_FILE_READ, [_id, bytes]).then((response) { |
| + return _dispatch(_FILE_READ, [_id, bytes]).then((response) { |
| if (_isErrorResponse(response)) { |
| throw _exceptionFromResponse(response, "read failed", path); |
| } |
| @@ -616,11 +610,10 @@ class _RandomAccessFile implements RandomAccessFile { |
| (end != null && end is !int)) { |
| throw new ArgumentError(); |
| } |
| - if (closed) return _closedException(); |
| if (start == null) start = 0; |
| if (end == null) end = buffer.length; |
| int length = end - start; |
| - return _IOService.dispatch(_FILE_READ_INTO, [_id, length]).then((response) { |
| + return _dispatch(_FILE_READ_INTO, [_id, length]).then((response) { |
| if (_isErrorResponse(response)) { |
| throw _exceptionFromResponse(response, "readInto failed", path); |
| } |
| @@ -663,8 +656,7 @@ class _RandomAccessFile implements RandomAccessFile { |
| if (value is !int) { |
| throw new ArgumentError(value); |
| } |
| - if (closed) return _closedException(); |
| - return _IOService.dispatch(_FILE_WRITE_BYTE, [_id, value]).then((response) { |
| + return _dispatch(_FILE_WRITE_BYTE, [_id, value]).then((response) { |
| if (_isErrorResponse(response)) { |
| throw _exceptionFromResponse(response, "writeByte failed", path); |
| } |
| @@ -693,8 +685,6 @@ class _RandomAccessFile implements RandomAccessFile { |
| throw new ArgumentError("Invalid arguments to writeFrom"); |
| } |
| - if (closed) return _closedException(); |
| - |
| _BufferAndStart result; |
| try { |
| result = _ensureFastAndSerializableByteData(buffer, start, end); |
| @@ -707,7 +697,7 @@ class _RandomAccessFile implements RandomAccessFile { |
| request[1] = result.buffer; |
| request[2] = result.start; |
| request[3] = end - (start - result.start); |
| - return _IOService.dispatch(_FILE_WRITE_FROM, request).then((response) { |
| + return _dispatch(_FILE_WRITE_FROM, request).then((response) { |
| if (_isErrorResponse(response)) { |
| throw _exceptionFromResponse(response, "writeFrom failed", path); |
| } |
| @@ -757,8 +747,7 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| Future<int> position() { |
| - if (closed) return _closedException(); |
| - return _IOService.dispatch(_FILE_POSITION, [_id]).then((response) { |
| + return _dispatch(_FILE_POSITION, [_id]).then((response) { |
| if (_isErrorResponse(response)) { |
| throw _exceptionFromResponse(response, "position failed", path); |
| } |
| @@ -778,8 +767,7 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| Future<RandomAccessFile> setPosition(int position) { |
| - if (closed) return _closedException(); |
| - return _IOService.dispatch(_FILE_SET_POSITION, [_id, position]) |
| + return _dispatch(_FILE_SET_POSITION, [_id, position]) |
| .then((response) { |
| if (_isErrorResponse(response)) { |
| throw _exceptionFromResponse(response, "setPosition failed", path); |
| @@ -799,8 +787,7 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| Future<RandomAccessFile> truncate(int length) { |
| - if (closed) return _closedException(); |
| - return _IOService.dispatch(_FILE_TRUNCATE, [_id, length]).then((response) { |
| + return _dispatch(_FILE_TRUNCATE, [_id, length]).then((response) { |
| if (_isErrorResponse(response)) { |
| throw _exceptionFromResponse(response, "truncate failed", path); |
| } |
| @@ -819,8 +806,7 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| Future<int> length() { |
| - if (closed) return _closedException(); |
| - return _IOService.dispatch(_FILE_LENGTH, [_id]).then((response) { |
| + return _dispatch(_FILE_LENGTH, [_id]).then((response) { |
| if (_isErrorResponse(response)) { |
| throw _exceptionFromResponse(response, "length failed", path); |
| } |
| @@ -840,8 +826,7 @@ class _RandomAccessFile implements RandomAccessFile { |
| } |
| Future<RandomAccessFile> flush() { |
| - if (closed) return _closedException(); |
| - return _IOService.dispatch(_FILE_FLUSH, [_id]).then((response) { |
| + return _dispatch(_FILE_FLUSH, [_id]).then((response) { |
| if (_isErrorResponse(response)) { |
| throw _exceptionFromResponse(response, |
| "flush failed", |
| @@ -863,13 +848,29 @@ class _RandomAccessFile implements RandomAccessFile { |
| bool get closed => _id == 0; |
| - void _checkNotClosed() { |
| + Future _dispatch(int request, List data, { bool markClosed: false }) { |
| if (closed) { |
| - throw new FileException("File closed", path); |
| + return new Future.error(new FileException("File closed", path)); |
| + } |
| + if (_asyncDispatched) { |
| + var msg = "A file operation is already issued for this RandomAccessFile"; |
|
Søren Gjesse
2013/09/26 18:31:19
How about a message something like this: "An async
Anders Johnsen
2013/10/01 10:50:40
Done.
|
| + return new Future.error(new FileException(msg, path)); |
| + } |
| + if (markClosed) { |
| + // Set the id_ to 0 (NULL) to ensure the no more async requests |
| + // can be issued for this file. |
| + _id = 0; |
| } |
| + _asyncDispatched = true; |
| + return _IOService.dispatch(request, data) |
| + .whenComplete(() { |
| + _asyncDispatched = false; |
| + }); |
| } |
| - Future _closedException() { |
| - return new Future.error(new FileException("File closed", path)); |
| + void _checkNotClosed() { |
| + if (closed) { |
| + throw new FileException("File closed", path); |
| + } |
| } |
| } |