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

Side by Side Diff: runtime/bin/file_impl.dart

Issue 10533110: Make sure that _FileInputStream._fillBuffer is not entered again before it finishes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 8 years, 6 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 class _FileInputStream extends _BaseDataInputStream implements InputStream { 5 class _FileInputStream extends _BaseDataInputStream implements InputStream {
6 _FileInputStream(String name) 6 _FileInputStream(String name)
7 : _data = [], 7 : _data = const [],
8 _position = 0, 8 _position = 0,
9 _filePosition = 0 { 9 _filePosition = 0 {
10 var file = new File(name); 10 var file = new File(name);
11 var future = file.open(FileMode.READ); 11 var future = file.open(FileMode.READ);
12 future.handleException((e) { 12 future.handleException((e) {
13 _reportError(e); 13 _reportError(e);
14 return true; 14 return true;
15 }); 15 });
16 future.then(_setupOpenedFile); 16 future.then(_setupOpenedFile);
17 } 17 }
18 18
19 _FileInputStream.fromStdio(int fd) 19 _FileInputStream.fromStdio(int fd)
20 : _data = [], 20 : _data = const [],
21 _position = 0, 21 _position = 0,
22 _filePosition = 0 { 22 _filePosition = 0 {
23 assert(fd == 0); 23 assert(fd == 0);
24 _setupOpenedFile(_File._openStdioSync(fd)); 24 _setupOpenedFile(_File._openStdioSync(fd));
25 } 25 }
26 26
27 void _setupOpenedFile(RandomAccessFile openedFile) { 27 void _setupOpenedFile(RandomAccessFile openedFile) {
28 _openedFile = openedFile; 28 _openedFile = openedFile;
29 if (_streamMarkedClosed) { 29 if (_streamMarkedClosed) {
30 // This input stream has already been closed. 30 // This input stream has already been closed.
(...skipping 27 matching lines...) Expand all
58 } 58 }
59 59
60 void _fillBuffer() { 60 void _fillBuffer() {
61 Expect.equals(_position, _data.length); 61 Expect.equals(_position, _data.length);
62 if (_openedFile == null) return; // Called before the file is opened. 62 if (_openedFile == null) return; // Called before the file is opened.
63 int size = Math.min(_bufferLength, _fileLength - _filePosition); 63 int size = Math.min(_bufferLength, _fileLength - _filePosition);
64 if (size == 0) { 64 if (size == 0) {
65 _closeFile(); 65 _closeFile();
66 return; 66 return;
67 } 67 }
68 // If there is currently a _fillBuffer call waiting on readList,
69 // let it fill the buffer instead of us.
70 if (_activeFillBufferCall) return;
71 _activeFillBufferCall = true;
68 if (_data.length != size) { 72 if (_data.length != size) {
69 _data = new Uint8List(size); 73 _data = new Uint8List(size);
74 // Maintain the invariant signalling that the buffer is empty.
75 _position = _data.length;
70 } 76 }
71 var future = _openedFile.readList(_data, 0, _data.length); 77 var future = _openedFile.readList(_data, 0, _data.length);
72 future.then((read) { 78 future.then((read) {
73 _filePosition += read; 79 _filePosition += read;
74 if (read != _data.length) { 80 if (read != _data.length) {
75 _data = _data.getRange(0, read); 81 _data = _data.getRange(0, read);
76 } 82 }
77 _position = 0; 83 _position = 0;
84 _activeFillBufferCall = false;
78 85
79 if (_fileLength == _filePosition) { 86 if (_fileLength == _filePosition) {
80 _closeFile(); 87 _closeFile();
81 } 88 }
82 _checkScheduleCallbacks(); 89 _checkScheduleCallbacks();
83 }); 90 });
91 future.handleException((e) {
92 _activeFillBufferCall = false;
93 _reportError(e);
94 return true;
95 });
84 } 96 }
85 97
86 int available() { 98 int available() {
87 return closed ? 0 : _data.length - _position; 99 return closed ? 0 : _data.length - _position;
88 } 100 }
89 101
90 void pipe(OutputStream output, [bool close = true]) { 102 void pipe(OutputStream output, [bool close = true]) {
91 _pipe(this, output, close: close); 103 _pipe(this, output, close: close);
92 } 104 }
93 105
94 void _finishRead() { 106 void _finishRead() {
95 if (_position == _data.length && !_streamMarkedClosed) { 107 if (_position == _data.length && !_streamMarkedClosed) {
96 _fillBuffer(); 108 _fillBuffer();
97 } else { 109 } else {
98 _checkScheduleCallbacks(); 110 _checkScheduleCallbacks();
99 } 111 }
100 } 112 }
101 113
102 List<int> _read(int bytesToRead) { 114 List<int> _read(int bytesToRead) {
103 List<int> result; 115 List<int> result;
104 if (_position == 0 && bytesToRead == _data.length) { 116 if (_position == 0 && bytesToRead == _data.length) {
105 result = _data; 117 result = _data;
106 _data = []; 118 _data = const [];
107 } else { 119 } else {
108 result = new Uint8List(bytesToRead); 120 result = new Uint8List(bytesToRead);
109 result.setRange(0, bytesToRead, _data, _position); 121 result.setRange(0, bytesToRead, _data, _position);
110 _position += bytesToRead; 122 _position += bytesToRead;
111 } 123 }
112 _finishRead(); 124 _finishRead();
113 return result; 125 return result;
114 } 126 }
115 127
116 int _readInto(List<int> buffer, int offset, int len) { 128 int _readInto(List<int> buffer, int offset, int len) {
117 buffer.setRange(offset, len, _data, _position); 129 buffer.setRange(offset, len, _data, _position);
118 _position += len; 130 _position += len;
119 _finishRead(); 131 _finishRead();
120 return len; 132 return len;
121 } 133 }
122 134
123 void _close() { 135 void _close() {
124 _data = []; 136 _data = const [];
125 _position = 0; 137 _position = 0;
126 _filePosition = 0; 138 _filePosition = 0;
127 _fileLength = 0; 139 _fileLength = 0;
128 _closeFile(); 140 _closeFile();
129 } 141 }
130 142
131 static final int _bufferLength = 64 * 1024; 143 static final int _bufferLength = 64 * 1024;
132 144
133 RandomAccessFile _openedFile; 145 RandomAccessFile _openedFile;
134 List<int> _data; 146 List<int> _data;
135 int _position; 147 int _position;
136 int _filePosition; 148 int _filePosition;
137 int _fileLength; 149 int _fileLength;
150 bool _activeFillBufferCall = false;
138 } 151 }
139 152
140 153
141 class _PendingOperation { 154 class _PendingOperation {
142 const _PendingOperation(this._id); 155 const _PendingOperation(this._id);
143 static final _PendingOperation CLOSE = const _PendingOperation(0); 156 static final _PendingOperation CLOSE = const _PendingOperation(0);
144 static final _PendingOperation FLUSH = const _PendingOperation(1); 157 static final _PendingOperation FLUSH = const _PendingOperation(1);
145 final int _id; 158 final int _id;
146 } 159 }
147 160
(...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 new FileIOException("File closed '$_name'")); 1154 new FileIOException("File closed '$_name'"));
1142 }); 1155 });
1143 return completer.future; 1156 return completer.future;
1144 } 1157 }
1145 1158
1146 final String _name; 1159 final String _name;
1147 int _id; 1160 int _id;
1148 1161
1149 SendPort _fileService; 1162 SendPort _fileService;
1150 } 1163 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698