Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(349)

Unified Diff: sdk/lib/io/file_impl.dart

Issue 24721003: Only allow one async operation on RandomAccessFile at a time. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Also disallow sync calls while an async operation is scheduled. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/standalone/io/file_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..4df878a9844a6c05bcca5ab1bc08dff04c9ce4ad 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;
@@ -554,7 +550,7 @@ class _RandomAccessFile implements RandomAccessFile {
external static int _close(int id);
void closeSync() {
- _checkNotClosed();
+ _checkAvailable();
var id = _close(_id);
if (id == -1) {
throw new FileException("Cannot close file", path);
@@ -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);
}
@@ -575,7 +570,7 @@ class _RandomAccessFile implements RandomAccessFile {
external static _readByte(int id);
int readByteSync() {
- _checkNotClosed();
+ _checkAvailable();
var result = _readByte(_id);
if (result is OSError) {
throw new FileException("readByte failed", path, result);
@@ -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);
}
@@ -599,7 +593,7 @@ class _RandomAccessFile implements RandomAccessFile {
external static _read(int id, int bytes);
List<int> readSync(int bytes) {
- _checkNotClosed();
+ _checkAvailable();
if (bytes is !int) {
throw new ArgumentError(bytes);
}
@@ -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);
}
@@ -642,7 +635,7 @@ class _RandomAccessFile implements RandomAccessFile {
external static _readInto(int id, List<int> buffer, int start, int end);
int readIntoSync(List<int> buffer, [int start, int end]) {
- _checkNotClosed();
+ _checkAvailable();
if (buffer is !List ||
(start != null && start is !int) ||
(end != null && end is !int)) {
@@ -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);
}
@@ -675,7 +667,7 @@ class _RandomAccessFile implements RandomAccessFile {
external static _writeByte(int id, int value);
int writeByteSync(int value) {
- _checkNotClosed();
+ _checkAvailable();
if (value is !int) {
throw new ArgumentError(value);
}
@@ -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);
}
@@ -718,7 +708,7 @@ class _RandomAccessFile implements RandomAccessFile {
external static _writeFrom(int id, List<int> buffer, int start, int end);
void writeFromSync(List<int> buffer, [int start, int end]) {
- _checkNotClosed();
+ _checkAvailable();
if (buffer is !List ||
(start != null && start is !int) ||
(end != null && end is !int)) {
@@ -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);
}
@@ -769,7 +758,7 @@ class _RandomAccessFile implements RandomAccessFile {
external static _position(int id);
int positionSync() {
- _checkNotClosed();
+ _checkAvailable();
var result = _position(_id);
if (result is OSError) {
throw new FileException("position failed", path, result);
@@ -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);
@@ -791,7 +779,7 @@ class _RandomAccessFile implements RandomAccessFile {
external static _setPosition(int id, int position);
void setPositionSync(int position) {
- _checkNotClosed();
+ _checkAvailable();
var result = _setPosition(_id, position);
if (result is OSError) {
throw new FileException("setPosition failed", path, result);
@@ -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);
}
@@ -811,7 +798,7 @@ class _RandomAccessFile implements RandomAccessFile {
external static _truncate(int id, int length);
void truncateSync(int length) {
- _checkNotClosed();
+ _checkAvailable();
var result = _truncate(_id, length);
if (result is OSError) {
throw new FileException("truncate failed", path, result);
@@ -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);
}
@@ -831,7 +817,7 @@ class _RandomAccessFile implements RandomAccessFile {
external static _length(int id);
int lengthSync() {
- _checkNotClosed();
+ _checkAvailable();
var result = _length(_id);
if (result is OSError) {
throw new FileException("length failed", path, result);
@@ -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",
@@ -854,7 +839,7 @@ class _RandomAccessFile implements RandomAccessFile {
external static _flush(int id);
void flushSync() {
- _checkNotClosed();
+ _checkAvailable();
var result = _flush(_id);
if (result is OSError) {
throw new FileException("flush failed", path, result);
@@ -863,13 +848,32 @@ 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 = "An async operation is currently pending";
+ 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 _checkAvailable() {
+ if (_asyncDispatched) {
+ throw new FileException("An async operation is currently pending", path);
+ }
+ if (closed) {
+ throw new FileException("File closed", path);
+ }
}
}
« no previous file with comments | « no previous file | tests/standalone/io/file_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698