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

Side by Side Diff: runtime/bin/file.cc

Issue 1892623002: Fixes leak of native File objects. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address comments Created 4 years, 8 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
« no previous file with comments | « runtime/bin/file.h ('k') | runtime/bin/file_android.cc » ('j') | 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 #if !defined(DART_IO_DISABLED) 5 #if !defined(DART_IO_DISABLED)
6 6
7 #include "bin/file.h" 7 #include "bin/file.h"
8 8
9 #include "bin/builtin.h" 9 #include "bin/builtin.h"
10 #include "bin/dartutils.h" 10 #include "bin/dartutils.h"
11 #include "bin/embedded_dart_io.h" 11 #include "bin/embedded_dart_io.h"
12 #include "bin/io_buffer.h" 12 #include "bin/io_buffer.h"
13 #include "bin/utils.h" 13 #include "bin/utils.h"
14 14
15 #include "include/dart_api.h" 15 #include "include/dart_api.h"
16 #include "include/dart_tools_api.h" 16 #include "include/dart_tools_api.h"
17 17
18 namespace dart { 18 namespace dart {
19 namespace bin { 19 namespace bin {
20 20
21 static const int kFileNativeFieldIndex = 0;
21 static const int kMSPerSecond = 1000; 22 static const int kMSPerSecond = 1000;
22 23
23 // The file pointer has been passed into Dart as an intptr_t and it is safe 24 // The file pointer has been passed into Dart as an intptr_t and it is safe
24 // to pull it out of Dart as a 64-bit integer, cast it to an intptr_t and 25 // to pull it out of Dart as a 64-bit integer, cast it to an intptr_t and
25 // from there to a File pointer. 26 // from there to a File pointer.
26 static File* GetFilePointer(Dart_Handle handle) { 27 static File* GetFile(Dart_NativeArguments args) {
27 intptr_t value = DartUtils::GetIntptrValue(handle); 28 File* file;
28 return reinterpret_cast<File*>(value); 29 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
30 ASSERT(Dart_IsInstance(dart_this));
31 ThrowIfError(Dart_GetNativeInstanceField(
32 dart_this,
33 kFileNativeFieldIndex,
34 reinterpret_cast<intptr_t*>(&file)));
35 return file;
29 } 36 }
30 37
31 38
39 static void SetFile(Dart_Handle dart_this, intptr_t file_pointer) {
40 Dart_Handle result = Dart_SetNativeInstanceField(
41 dart_this,
42 kFileNativeFieldIndex,
43 file_pointer);
44 if (Dart_IsError(result)) {
45 Log::PrintErr("SetNativeInstanceField in SetFile() failed\n");
46 Dart_PropagateError(result);
47 }
48 }
49
50
51 void FUNCTION_NAME(File_GetPointer)(Dart_NativeArguments args) {
52 File* file = GetFile(args);
53 // If the file is already closed, GetFile() will return NULL.
54 if (file != NULL) {
55 // Increment file's reference count. File_GetPointer() should only be called
56 // when we are about to send the File* to the IO Service.
57 file->Retain();
58 }
59 intptr_t file_pointer = reinterpret_cast<intptr_t>(file);
60 Dart_SetReturnValue(args, Dart_NewInteger(file_pointer));
61 }
62
63
64 static void ReleaseFile(void* isolate_callback_data,
65 Dart_WeakPersistentHandle handle,
66 void* peer) {
67 File* file = reinterpret_cast<File*>(peer);
68 file->Release();
69 }
70
71
72 void FUNCTION_NAME(File_SetPointer)(Dart_NativeArguments args) {
73 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
74 intptr_t file_pointer =
75 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1));
76 File* file = reinterpret_cast<File*>(file_pointer);
77 Dart_WeakPersistentHandle handle = Dart_NewWeakPersistentHandle(
78 dart_this, reinterpret_cast<void*>(file), sizeof(*file), ReleaseFile);
79 file->SetWeakHandle(handle);
80 SetFile(dart_this, file_pointer);
81 }
82
83
32 void FUNCTION_NAME(File_Open)(Dart_NativeArguments args) { 84 void FUNCTION_NAME(File_Open)(Dart_NativeArguments args) {
33 const char* filename = 85 const char* filename =
34 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0)); 86 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
35 int64_t mode = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1)); 87 int64_t mode = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1));
36 File::DartFileOpenMode dart_file_mode = 88 File::DartFileOpenMode dart_file_mode =
37 static_cast<File::DartFileOpenMode>(mode); 89 static_cast<File::DartFileOpenMode>(mode);
38 File::FileOpenMode file_mode = File::DartModeToFileMode(dart_file_mode); 90 File::FileOpenMode file_mode = File::DartModeToFileMode(dart_file_mode);
39 // Check that the file exists before opening it only for 91 // Check that the file exists before opening it only for
40 // reading. This is to prevent the opening of directories as 92 // reading. This is to prevent the opening of directories as
41 // files. Directories can be opened for reading using the posix 93 // files. Directories can be opened for reading using the posix
42 // 'open' call. 94 // 'open' call.
43 File* file = NULL; 95 File* file = File::ScopedOpen(filename, file_mode);
44 file = File::ScopedOpen(filename, file_mode);
45 if (file != NULL) { 96 if (file != NULL) {
46 Dart_SetReturnValue(args, 97 Dart_SetReturnValue(args,
47 Dart_NewInteger(reinterpret_cast<intptr_t>(file))); 98 Dart_NewInteger(reinterpret_cast<intptr_t>(file)));
48 } else { 99 } else {
49 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 100 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
50 } 101 }
51 } 102 }
52 103
53 104
54 void FUNCTION_NAME(File_Exists)(Dart_NativeArguments args) { 105 void FUNCTION_NAME(File_Exists)(Dart_NativeArguments args) {
55 const char* filename = 106 const char* filename =
56 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0)); 107 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
57 bool exists = File::Exists(filename); 108 bool exists = File::Exists(filename);
58 Dart_SetReturnValue(args, Dart_NewBoolean(exists)); 109 Dart_SetReturnValue(args, Dart_NewBoolean(exists));
59 } 110 }
60 111
61 112
62 void FUNCTION_NAME(File_Close)(Dart_NativeArguments args) { 113 void FUNCTION_NAME(File_Close)(Dart_NativeArguments args) {
63 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); 114 File* file = GetFile(args);
64 ASSERT(file != NULL); 115 ASSERT(file != NULL);
65 delete file; 116 file->DeleteWeakHandle(Dart_CurrentIsolate());
117 file->Release();
118
119 // NULL-out the now potentially dangling pointer.
120 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0);
121 SetFile(dart_this, 0);
66 Dart_SetReturnValue(args, Dart_NewInteger(0)); 122 Dart_SetReturnValue(args, Dart_NewInteger(0));
67 } 123 }
68 124
69 125
70 void FUNCTION_NAME(File_GetFD)(Dart_NativeArguments args) {
71 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0));
72 ASSERT(file != NULL);
73 Dart_SetReturnValue(args, Dart_NewInteger(file->GetFD()));
74 }
75
76
77 void FUNCTION_NAME(File_ReadByte)(Dart_NativeArguments args) { 126 void FUNCTION_NAME(File_ReadByte)(Dart_NativeArguments args) {
78 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); 127 File* file = GetFile(args);
79 ASSERT(file != NULL); 128 ASSERT(file != NULL);
80 uint8_t buffer; 129 uint8_t buffer;
81 int64_t bytes_read = file->Read(reinterpret_cast<void*>(&buffer), 1); 130 int64_t bytes_read = file->Read(reinterpret_cast<void*>(&buffer), 1);
82 if (bytes_read == 1) { 131 if (bytes_read == 1) {
83 Dart_SetReturnValue(args, Dart_NewInteger(buffer)); 132 Dart_SetReturnValue(args, Dart_NewInteger(buffer));
84 } else if (bytes_read == 0) { 133 } else if (bytes_read == 0) {
85 Dart_SetReturnValue(args, Dart_NewInteger(-1)); 134 Dart_SetReturnValue(args, Dart_NewInteger(-1));
86 } else { 135 } else {
87 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 136 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
88 } 137 }
89 } 138 }
90 139
91 140
92 void FUNCTION_NAME(File_WriteByte)(Dart_NativeArguments args) { 141 void FUNCTION_NAME(File_WriteByte)(Dart_NativeArguments args) {
93 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); 142 File* file = GetFile(args);
94 ASSERT(file != NULL); 143 ASSERT(file != NULL);
95 int64_t byte = 0; 144 int64_t byte = 0;
96 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &byte)) { 145 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &byte)) {
97 uint8_t buffer = static_cast<uint8_t>(byte & 0xff); 146 uint8_t buffer = static_cast<uint8_t>(byte & 0xff);
98 bool success = file->WriteFully(reinterpret_cast<void*>(&buffer), 1); 147 bool success = file->WriteFully(reinterpret_cast<void*>(&buffer), 1);
99 if (success) { 148 if (success) {
100 Dart_SetReturnValue(args, Dart_NewInteger(1)); 149 Dart_SetReturnValue(args, Dart_NewInteger(1));
101 } else { 150 } else {
102 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 151 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
103 } 152 }
104 } else { 153 } else {
105 OSError os_error(-1, "Invalid argument", OSError::kUnknown); 154 OSError os_error(-1, "Invalid argument", OSError::kUnknown);
106 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); 155 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
107 } 156 }
108 } 157 }
109 158
110 159
111 void FUNCTION_NAME(File_Read)(Dart_NativeArguments args) { 160 void FUNCTION_NAME(File_Read)(Dart_NativeArguments args) {
112 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); 161 File* file = GetFile(args);
113 ASSERT(file != NULL); 162 ASSERT(file != NULL);
114 Dart_Handle length_object = Dart_GetNativeArgument(args, 1); 163 Dart_Handle length_object = Dart_GetNativeArgument(args, 1);
115 int64_t length = 0; 164 int64_t length = 0;
116 if (DartUtils::GetInt64Value(length_object, &length)) { 165 if (DartUtils::GetInt64Value(length_object, &length)) {
117 uint8_t* buffer = NULL; 166 uint8_t* buffer = NULL;
118 Dart_Handle external_array = IOBuffer::Allocate(length, &buffer); 167 Dart_Handle external_array = IOBuffer::Allocate(length, &buffer);
119 int64_t bytes_read = file->Read(reinterpret_cast<void*>(buffer), length); 168 int64_t bytes_read = file->Read(reinterpret_cast<void*>(buffer), length);
120 if (bytes_read < 0) { 169 if (bytes_read < 0) {
121 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 170 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
122 } else { 171 } else {
(...skipping 20 matching lines...) Expand all
143 } 192 }
144 } 193 }
145 } else { 194 } else {
146 OSError os_error(-1, "Invalid argument", OSError::kUnknown); 195 OSError os_error(-1, "Invalid argument", OSError::kUnknown);
147 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); 196 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
148 } 197 }
149 } 198 }
150 199
151 200
152 void FUNCTION_NAME(File_ReadInto)(Dart_NativeArguments args) { 201 void FUNCTION_NAME(File_ReadInto)(Dart_NativeArguments args) {
153 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); 202 File* file = GetFile(args);
154 ASSERT(file != NULL); 203 ASSERT(file != NULL);
155 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1); 204 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
156 ASSERT(Dart_IsList(buffer_obj)); 205 ASSERT(Dart_IsList(buffer_obj));
157 // start and end arguments are checked in Dart code to be 206 // start and end arguments are checked in Dart code to be
158 // integers and have the property that end <= 207 // integers and have the property that end <=
159 // list.length. Therefore, it is safe to extract their value as 208 // list.length. Therefore, it is safe to extract their value as
160 // intptr_t. 209 // intptr_t.
161 intptr_t start = 210 intptr_t start =
162 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2)); 211 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
163 intptr_t end = 212 intptr_t end =
(...skipping 14 matching lines...) Expand all
178 } else { 227 } else {
179 Dart_SetReturnValue(args, Dart_NewInteger(bytes_read)); 228 Dart_SetReturnValue(args, Dart_NewInteger(bytes_read));
180 } 229 }
181 } else { 230 } else {
182 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 231 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
183 } 232 }
184 } 233 }
185 234
186 235
187 void FUNCTION_NAME(File_WriteFrom)(Dart_NativeArguments args) { 236 void FUNCTION_NAME(File_WriteFrom)(Dart_NativeArguments args) {
188 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); 237 File* file = GetFile(args);
189 ASSERT(file != NULL); 238 ASSERT(file != NULL);
190 239
191 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1); 240 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
192 241
193 // Offset and length arguments are checked in Dart code to be 242 // Offset and length arguments are checked in Dart code to be
194 // integers and have the property that (offset + length) <= 243 // integers and have the property that (offset + length) <=
195 // list.length. Therefore, it is safe to extract their value as 244 // list.length. Therefore, it is safe to extract their value as
196 // intptr_t. 245 // intptr_t.
197 intptr_t start = 246 intptr_t start =
198 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2)); 247 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
(...skipping 27 matching lines...) Expand all
226 275
227 if (!success) { 276 if (!success) {
228 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 277 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
229 } else { 278 } else {
230 Dart_SetReturnValue(args, Dart_Null()); 279 Dart_SetReturnValue(args, Dart_Null());
231 } 280 }
232 } 281 }
233 282
234 283
235 void FUNCTION_NAME(File_Position)(Dart_NativeArguments args) { 284 void FUNCTION_NAME(File_Position)(Dart_NativeArguments args) {
236 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); 285 File* file = GetFile(args);
237 ASSERT(file != NULL); 286 ASSERT(file != NULL);
238 intptr_t return_value = file->Position(); 287 intptr_t return_value = file->Position();
239 if (return_value >= 0) { 288 if (return_value >= 0) {
240 Dart_SetReturnValue(args, Dart_NewInteger(return_value)); 289 Dart_SetReturnValue(args, Dart_NewInteger(return_value));
241 } else { 290 } else {
242 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 291 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
243 } 292 }
244 } 293 }
245 294
246 295
247 void FUNCTION_NAME(File_SetPosition)(Dart_NativeArguments args) { 296 void FUNCTION_NAME(File_SetPosition)(Dart_NativeArguments args) {
248 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); 297 File* file = GetFile(args);
249 ASSERT(file != NULL); 298 ASSERT(file != NULL);
250 int64_t position = 0; 299 int64_t position = 0;
251 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &position)) { 300 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &position)) {
252 if (file->SetPosition(position)) { 301 if (file->SetPosition(position)) {
253 Dart_SetReturnValue(args, Dart_True()); 302 Dart_SetReturnValue(args, Dart_True());
254 } else { 303 } else {
255 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 304 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
256 } 305 }
257 } else { 306 } else {
258 OSError os_error(-1, "Invalid argument", OSError::kUnknown); 307 OSError os_error(-1, "Invalid argument", OSError::kUnknown);
259 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); 308 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
260 } 309 }
261 } 310 }
262 311
263 312
264 void FUNCTION_NAME(File_Truncate)(Dart_NativeArguments args) { 313 void FUNCTION_NAME(File_Truncate)(Dart_NativeArguments args) {
265 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); 314 File* file = GetFile(args);
266 ASSERT(file != NULL); 315 ASSERT(file != NULL);
267 int64_t length = 0; 316 int64_t length = 0;
268 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &length)) { 317 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &length)) {
269 if (file->Truncate(length)) { 318 if (file->Truncate(length)) {
270 Dart_SetReturnValue(args, Dart_True()); 319 Dart_SetReturnValue(args, Dart_True());
271 } else { 320 } else {
272 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 321 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
273 } 322 }
274 } else { 323 } else {
275 OSError os_error(-1, "Invalid argument", OSError::kUnknown); 324 OSError os_error(-1, "Invalid argument", OSError::kUnknown);
276 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); 325 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
277 } 326 }
278 } 327 }
279 328
280 329
281 void FUNCTION_NAME(File_Length)(Dart_NativeArguments args) { 330 void FUNCTION_NAME(File_Length)(Dart_NativeArguments args) {
282 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); 331 File* file = GetFile(args);
283 ASSERT(file != NULL); 332 ASSERT(file != NULL);
284 int64_t return_value = file->Length(); 333 int64_t return_value = file->Length();
285 if (return_value >= 0) { 334 if (return_value >= 0) {
286 Dart_SetReturnValue(args, Dart_NewInteger(return_value)); 335 Dart_SetReturnValue(args, Dart_NewInteger(return_value));
287 } else { 336 } else {
288 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 337 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
289 } 338 }
290 } 339 }
291 340
292 341
(...skipping 15 matching lines...) Expand all
308 int64_t return_value = File::LastModified(name); 357 int64_t return_value = File::LastModified(name);
309 if (return_value >= 0) { 358 if (return_value >= 0) {
310 Dart_SetReturnValue(args, Dart_NewInteger(return_value * kMSPerSecond)); 359 Dart_SetReturnValue(args, Dart_NewInteger(return_value * kMSPerSecond));
311 } else { 360 } else {
312 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 361 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
313 } 362 }
314 } 363 }
315 364
316 365
317 void FUNCTION_NAME(File_Flush)(Dart_NativeArguments args) { 366 void FUNCTION_NAME(File_Flush)(Dart_NativeArguments args) {
318 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); 367 File* file = GetFile(args);
319 ASSERT(file != NULL); 368 ASSERT(file != NULL);
320 if (file->Flush()) { 369 if (file->Flush()) {
321 Dart_SetReturnValue(args, Dart_True()); 370 Dart_SetReturnValue(args, Dart_True());
322 } else { 371 } else {
323 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 372 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
324 } 373 }
325 } 374 }
326 375
327 376
328 void FUNCTION_NAME(File_Lock)(Dart_NativeArguments args) { 377 void FUNCTION_NAME(File_Lock)(Dart_NativeArguments args) {
329 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); 378 File* file = GetFile(args);
330 ASSERT(file != NULL); 379 ASSERT(file != NULL);
331 int64_t lock; 380 int64_t lock;
332 int64_t start; 381 int64_t start;
333 int64_t end; 382 int64_t end;
334 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &lock) && 383 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &lock) &&
335 DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 2), &start) && 384 DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 2), &start) &&
336 DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 3), &end)) { 385 DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 3), &end)) {
337 if ((lock >= File::kLockMin) && (lock <= File::kLockMax) && 386 if ((lock >= File::kLockMin) && (lock <= File::kLockMax) &&
338 (start >= 0) && (end == -1 || end > start)) { 387 (start >= 0) && (end == -1 || end > start)) {
339 if (file->Lock(static_cast<File::LockType>(lock), start, end)) { 388 if (file->Lock(static_cast<File::LockType>(lock), start, end)) {
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 } 746 }
698 } 747 }
699 return CObject::IllegalArgumentError(); 748 return CObject::IllegalArgumentError();
700 } 749 }
701 750
702 751
703 CObject* File::CloseRequest(const CObjectArray& request) { 752 CObject* File::CloseRequest(const CObjectArray& request) {
704 intptr_t return_value = -1; 753 intptr_t return_value = -1;
705 if ((request.Length() == 1) && request[0]->IsIntptr()) { 754 if ((request.Length() == 1) && request[0]->IsIntptr()) {
706 File* file = CObjectToFilePointer(request[0]); 755 File* file = CObjectToFilePointer(request[0]);
707 ASSERT(file != NULL); 756 RefCntReleaseScope<File> rs(file);
708 delete file;
709 return_value = 0; 757 return_value = 0;
758 // We have retained a reference to the file here. Therefore the file's
759 // destructor can't be running. Since no further requests are dispatched by
760 // the Dart code after an async close call, this Close() can't be racing
761 // with any other call on the file. We don't do an extra Release(), and we
762 // don't delete the weak persistent handle. The file is closed here, but the
763 // memory will be cleaned up when the finalizer runs.
764 ASSERT(!file->IsClosed());
765 file->Close();
710 } 766 }
711 return new CObjectIntptr(CObject::NewIntptr(return_value)); 767 return new CObjectIntptr(CObject::NewIntptr(return_value));
712 } 768 }
713 769
714 770
715 CObject* File::PositionRequest(const CObjectArray& request) { 771 CObject* File::PositionRequest(const CObjectArray& request) {
716 if ((request.Length() == 1) && request[0]->IsIntptr()) { 772 if ((request.Length() == 1) && request[0]->IsIntptr()) {
717 File* file = CObjectToFilePointer(request[0]); 773 File* file = CObjectToFilePointer(request[0]);
718 ASSERT(file != NULL); 774 RefCntReleaseScope<File> rs(file);
719 if (!file->IsClosed()) { 775 if (!file->IsClosed()) {
720 intptr_t return_value = file->Position(); 776 intptr_t return_value = file->Position();
721 if (return_value >= 0) { 777 if (return_value >= 0) {
722 return new CObjectIntptr(CObject::NewIntptr(return_value)); 778 return new CObjectIntptr(CObject::NewIntptr(return_value));
723 } else { 779 } else {
724 return CObject::NewOSError(); 780 return CObject::NewOSError();
725 } 781 }
726 } else { 782 } else {
727 return CObject::FileClosedError(); 783 return CObject::FileClosedError();
728 } 784 }
729 } 785 }
730 return CObject::IllegalArgumentError(); 786 return CObject::IllegalArgumentError();
731 } 787 }
732 788
733 789
734 CObject* File::SetPositionRequest(const CObjectArray& request) { 790 CObject* File::SetPositionRequest(const CObjectArray& request) {
735 if ((request.Length() == 2) && 791 if ((request.Length() == 2) &&
736 request[0]->IsIntptr() && 792 request[0]->IsIntptr() &&
737 request[1]->IsInt32OrInt64()) { 793 request[1]->IsInt32OrInt64()) {
738 File* file = CObjectToFilePointer(request[0]); 794 File* file = CObjectToFilePointer(request[0]);
739 ASSERT(file != NULL); 795 RefCntReleaseScope<File> rs(file);
740 if (!file->IsClosed()) { 796 if (!file->IsClosed()) {
741 int64_t position = CObjectInt32OrInt64ToInt64(request[1]); 797 int64_t position = CObjectInt32OrInt64ToInt64(request[1]);
742 if (file->SetPosition(position)) { 798 if (file->SetPosition(position)) {
743 return CObject::True(); 799 return CObject::True();
744 } else { 800 } else {
745 return CObject::NewOSError(); 801 return CObject::NewOSError();
746 } 802 }
747 } else { 803 } else {
748 return CObject::FileClosedError(); 804 return CObject::FileClosedError();
749 } 805 }
750 } 806 }
751 return CObject::IllegalArgumentError(); 807 return CObject::IllegalArgumentError();
752 } 808 }
753 809
754 810
755 CObject* File::TruncateRequest(const CObjectArray& request) { 811 CObject* File::TruncateRequest(const CObjectArray& request) {
756 if ((request.Length() == 2) && 812 if ((request.Length() == 2) &&
757 request[0]->IsIntptr() && 813 request[0]->IsIntptr() &&
758 request[1]->IsInt32OrInt64()) { 814 request[1]->IsInt32OrInt64()) {
759 File* file = CObjectToFilePointer(request[0]); 815 File* file = CObjectToFilePointer(request[0]);
760 ASSERT(file != NULL); 816 RefCntReleaseScope<File> rs(file);
761 if (!file->IsClosed()) { 817 if (!file->IsClosed()) {
762 int64_t length = CObjectInt32OrInt64ToInt64(request[1]); 818 int64_t length = CObjectInt32OrInt64ToInt64(request[1]);
763 if (file->Truncate(length)) { 819 if (file->Truncate(length)) {
764 return CObject::True(); 820 return CObject::True();
765 } else { 821 } else {
766 return CObject::NewOSError(); 822 return CObject::NewOSError();
767 } 823 }
768 } else { 824 } else {
769 return CObject::FileClosedError(); 825 return CObject::FileClosedError();
770 } 826 }
771 } 827 }
772 return CObject::IllegalArgumentError(); 828 return CObject::IllegalArgumentError();
773 } 829 }
774 830
775 831
776 CObject* File::LengthRequest(const CObjectArray& request) { 832 CObject* File::LengthRequest(const CObjectArray& request) {
777 if ((request.Length() == 1) && request[0]->IsIntptr()) { 833 if ((request.Length() == 1) && request[0]->IsIntptr()) {
778 File* file = CObjectToFilePointer(request[0]); 834 File* file = CObjectToFilePointer(request[0]);
779 ASSERT(file != NULL); 835 RefCntReleaseScope<File> rs(file);
780 if (!file->IsClosed()) { 836 if (!file->IsClosed()) {
781 int64_t return_value = file->Length(); 837 int64_t return_value = file->Length();
782 if (return_value >= 0) { 838 if (return_value >= 0) {
783 return new CObjectInt64(CObject::NewInt64(return_value)); 839 return new CObjectInt64(CObject::NewInt64(return_value));
784 } else { 840 } else {
785 return CObject::NewOSError(); 841 return CObject::NewOSError();
786 } 842 }
787 } else { 843 } else {
788 return CObject::FileClosedError(); 844 return CObject::FileClosedError();
789 } 845 }
(...skipping 26 matching lines...) Expand all
816 return CObject::NewOSError(); 872 return CObject::NewOSError();
817 } 873 }
818 } 874 }
819 return CObject::IllegalArgumentError(); 875 return CObject::IllegalArgumentError();
820 } 876 }
821 877
822 878
823 CObject* File::FlushRequest(const CObjectArray& request) { 879 CObject* File::FlushRequest(const CObjectArray& request) {
824 if ((request.Length() == 1) && request[0]->IsIntptr()) { 880 if ((request.Length() == 1) && request[0]->IsIntptr()) {
825 File* file = CObjectToFilePointer(request[0]); 881 File* file = CObjectToFilePointer(request[0]);
826 ASSERT(file != NULL); 882 RefCntReleaseScope<File> rs(file);
827 if (!file->IsClosed()) { 883 if (!file->IsClosed()) {
828 if (file->Flush()) { 884 if (file->Flush()) {
829 return CObject::True(); 885 return CObject::True();
830 } else { 886 } else {
831 return CObject::NewOSError(); 887 return CObject::NewOSError();
832 } 888 }
833 } else { 889 } else {
834 return CObject::FileClosedError(); 890 return CObject::FileClosedError();
835 } 891 }
836 } 892 }
837 return CObject::IllegalArgumentError(); 893 return CObject::IllegalArgumentError();
838 } 894 }
839 895
840 896
841 CObject* File::ReadByteRequest(const CObjectArray& request) { 897 CObject* File::ReadByteRequest(const CObjectArray& request) {
842 if ((request.Length() == 1) && request[0]->IsIntptr()) { 898 if ((request.Length() == 1) && request[0]->IsIntptr()) {
843 File* file = CObjectToFilePointer(request[0]); 899 File* file = CObjectToFilePointer(request[0]);
844 ASSERT(file != NULL); 900 RefCntReleaseScope<File> rs(file);
845 if (!file->IsClosed()) { 901 if (!file->IsClosed()) {
846 uint8_t buffer; 902 uint8_t buffer;
847 int64_t bytes_read = file->Read(reinterpret_cast<void*>(&buffer), 1); 903 int64_t bytes_read = file->Read(reinterpret_cast<void*>(&buffer), 1);
848 if (bytes_read > 0) { 904 if (bytes_read > 0) {
849 return new CObjectIntptr(CObject::NewIntptr(buffer)); 905 return new CObjectIntptr(CObject::NewIntptr(buffer));
850 } else if (bytes_read == 0) { 906 } else if (bytes_read == 0) {
851 return new CObjectIntptr(CObject::NewIntptr(-1)); 907 return new CObjectIntptr(CObject::NewIntptr(-1));
852 } else { 908 } else {
853 return CObject::NewOSError(); 909 return CObject::NewOSError();
854 } 910 }
855 } else { 911 } else {
856 return CObject::FileClosedError(); 912 return CObject::FileClosedError();
857 } 913 }
858 } 914 }
859 return CObject::IllegalArgumentError(); 915 return CObject::IllegalArgumentError();
860 } 916 }
861 917
862 918
863 CObject* File::WriteByteRequest(const CObjectArray& request) { 919 CObject* File::WriteByteRequest(const CObjectArray& request) {
864 if ((request.Length() == 2) && 920 if ((request.Length() == 2) &&
865 request[0]->IsIntptr() && 921 request[0]->IsIntptr() &&
866 request[1]->IsInt32OrInt64()) { 922 request[1]->IsInt32OrInt64()) {
867 File* file = CObjectToFilePointer(request[0]); 923 File* file = CObjectToFilePointer(request[0]);
868 ASSERT(file != NULL); 924 RefCntReleaseScope<File> rs(file);
869 if (!file->IsClosed()) { 925 if (!file->IsClosed()) {
870 int64_t byte = CObjectInt32OrInt64ToInt64(request[1]); 926 int64_t byte = CObjectInt32OrInt64ToInt64(request[1]);
871 uint8_t buffer = static_cast<uint8_t>(byte & 0xff); 927 uint8_t buffer = static_cast<uint8_t>(byte & 0xff);
872 bool success = file->WriteFully(reinterpret_cast<void*>(&buffer), 1); 928 bool success = file->WriteFully(reinterpret_cast<void*>(&buffer), 1);
873 if (success) { 929 if (success) {
874 return new CObjectInt64(CObject::NewInt64(1)); 930 return new CObjectInt64(CObject::NewInt64(1));
875 } else { 931 } else {
876 return CObject::NewOSError(); 932 return CObject::NewOSError();
877 } 933 }
878 } else { 934 } else {
879 return CObject::FileClosedError(); 935 return CObject::FileClosedError();
880 } 936 }
881 } 937 }
882 return CObject::IllegalArgumentError(); 938 return CObject::IllegalArgumentError();
883 } 939 }
884 940
885 941
886 CObject* File::ReadRequest(const CObjectArray& request) { 942 CObject* File::ReadRequest(const CObjectArray& request) {
887 if ((request.Length() == 2) && 943 if ((request.Length() == 2) &&
888 request[0]->IsIntptr() && 944 request[0]->IsIntptr() &&
889 request[1]->IsInt32OrInt64()) { 945 request[1]->IsInt32OrInt64()) {
890 File* file = CObjectToFilePointer(request[0]); 946 File* file = CObjectToFilePointer(request[0]);
891 ASSERT(file != NULL); 947 RefCntReleaseScope<File> rs(file);
892 if (!file->IsClosed()) { 948 if (!file->IsClosed()) {
893 int64_t length = CObjectInt32OrInt64ToInt64(request[1]); 949 int64_t length = CObjectInt32OrInt64ToInt64(request[1]);
894 Dart_CObject* io_buffer = CObject::NewIOBuffer(length); 950 Dart_CObject* io_buffer = CObject::NewIOBuffer(length);
895 ASSERT(io_buffer != NULL); 951 ASSERT(io_buffer != NULL);
896 uint8_t* data = io_buffer->value.as_external_typed_data.data; 952 uint8_t* data = io_buffer->value.as_external_typed_data.data;
897 int64_t bytes_read = file->Read(data, length); 953 int64_t bytes_read = file->Read(data, length);
898 if (bytes_read >= 0) { 954 if (bytes_read >= 0) {
899 CObjectExternalUint8Array* external_array = 955 CObjectExternalUint8Array* external_array =
900 new CObjectExternalUint8Array(io_buffer); 956 new CObjectExternalUint8Array(io_buffer);
901 external_array->SetLength(bytes_read); 957 external_array->SetLength(bytes_read);
(...skipping 11 matching lines...) Expand all
913 } 969 }
914 return CObject::IllegalArgumentError(); 970 return CObject::IllegalArgumentError();
915 } 971 }
916 972
917 973
918 CObject* File::ReadIntoRequest(const CObjectArray& request) { 974 CObject* File::ReadIntoRequest(const CObjectArray& request) {
919 if ((request.Length() == 2) && 975 if ((request.Length() == 2) &&
920 request[0]->IsIntptr() && 976 request[0]->IsIntptr() &&
921 request[1]->IsInt32OrInt64()) { 977 request[1]->IsInt32OrInt64()) {
922 File* file = CObjectToFilePointer(request[0]); 978 File* file = CObjectToFilePointer(request[0]);
923 ASSERT(file != NULL); 979 RefCntReleaseScope<File> rs(file);
924 if (!file->IsClosed()) { 980 if (!file->IsClosed()) {
925 int64_t length = CObjectInt32OrInt64ToInt64(request[1]); 981 int64_t length = CObjectInt32OrInt64ToInt64(request[1]);
926 Dart_CObject* io_buffer = CObject::NewIOBuffer(length); 982 Dart_CObject* io_buffer = CObject::NewIOBuffer(length);
927 ASSERT(io_buffer != NULL); 983 ASSERT(io_buffer != NULL);
928 uint8_t* data = io_buffer->value.as_external_typed_data.data; 984 uint8_t* data = io_buffer->value.as_external_typed_data.data;
929 int64_t bytes_read = file->Read(data, length); 985 int64_t bytes_read = file->Read(data, length);
930 if (bytes_read >= 0) { 986 if (bytes_read >= 0) {
931 CObjectExternalUint8Array* external_array = 987 CObjectExternalUint8Array* external_array =
932 new CObjectExternalUint8Array(io_buffer); 988 new CObjectExternalUint8Array(io_buffer);
933 external_array->SetLength(bytes_read); 989 external_array->SetLength(bytes_read);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
973 } 1029 }
974 1030
975 1031
976 CObject* File::WriteFromRequest(const CObjectArray& request) { 1032 CObject* File::WriteFromRequest(const CObjectArray& request) {
977 if ((request.Length() == 4) && 1033 if ((request.Length() == 4) &&
978 request[0]->IsIntptr() && 1034 request[0]->IsIntptr() &&
979 (request[1]->IsTypedData() || request[1]->IsArray()) && 1035 (request[1]->IsTypedData() || request[1]->IsArray()) &&
980 request[2]->IsInt32OrInt64() && 1036 request[2]->IsInt32OrInt64() &&
981 request[3]->IsInt32OrInt64()) { 1037 request[3]->IsInt32OrInt64()) {
982 File* file = CObjectToFilePointer(request[0]); 1038 File* file = CObjectToFilePointer(request[0]);
983 ASSERT(file != NULL); 1039 RefCntReleaseScope<File> rs(file);
984 if (!file->IsClosed()) { 1040 if (!file->IsClosed()) {
985 int64_t start = CObjectInt32OrInt64ToInt64(request[2]); 1041 int64_t start = CObjectInt32OrInt64ToInt64(request[2]);
986 int64_t end = CObjectInt32OrInt64ToInt64(request[3]); 1042 int64_t end = CObjectInt32OrInt64ToInt64(request[3]);
987 int64_t length = end - start; 1043 int64_t length = end - start;
988 uint8_t* buffer_start; 1044 uint8_t* buffer_start;
989 if (request[1]->IsTypedData()) { 1045 if (request[1]->IsTypedData()) {
990 CObjectTypedData typed_data(request[1]); 1046 CObjectTypedData typed_data(request[1]);
991 start = start * SizeInBytes(typed_data.Type()); 1047 start = start * SizeInBytes(typed_data.Type());
992 length = length * SizeInBytes(typed_data.Type()); 1048 length = length * SizeInBytes(typed_data.Type());
993 buffer_start = typed_data.Buffer() + start; 1049 buffer_start = typed_data.Buffer() + start;
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 } 1192 }
1137 1193
1138 1194
1139 CObject* File::LockRequest(const CObjectArray& request) { 1195 CObject* File::LockRequest(const CObjectArray& request) {
1140 if ((request.Length() == 4) && 1196 if ((request.Length() == 4) &&
1141 request[0]->IsIntptr() && 1197 request[0]->IsIntptr() &&
1142 request[1]->IsInt32OrInt64() && 1198 request[1]->IsInt32OrInt64() &&
1143 request[2]->IsInt32OrInt64() && 1199 request[2]->IsInt32OrInt64() &&
1144 request[3]->IsInt32OrInt64()) { 1200 request[3]->IsInt32OrInt64()) {
1145 File* file = CObjectToFilePointer(request[0]); 1201 File* file = CObjectToFilePointer(request[0]);
1146 ASSERT(file != NULL); 1202 RefCntReleaseScope<File> rs(file);
1147 if (!file->IsClosed()) { 1203 if (!file->IsClosed()) {
1148 int64_t lock = CObjectInt32OrInt64ToInt64(request[1]); 1204 int64_t lock = CObjectInt32OrInt64ToInt64(request[1]);
1149 int64_t start = CObjectInt32OrInt64ToInt64(request[2]); 1205 int64_t start = CObjectInt32OrInt64ToInt64(request[2]);
1150 int64_t end = CObjectInt32OrInt64ToInt64(request[3]); 1206 int64_t end = CObjectInt32OrInt64ToInt64(request[3]);
1151 if (file->Lock(static_cast<File::LockType>(lock), start, end)) { 1207 if (file->Lock(static_cast<File::LockType>(lock), start, end)) {
1152 return CObject::True(); 1208 return CObject::True();
1153 } else { 1209 } else {
1154 return CObject::NewOSError(); 1210 return CObject::NewOSError();
1155 } 1211 }
1156 } else { 1212 } else {
1157 return CObject::FileClosedError(); 1213 return CObject::FileClosedError();
1158 } 1214 }
1159 } 1215 }
1160 return CObject::IllegalArgumentError(); 1216 return CObject::IllegalArgumentError();
1161 } 1217 }
1162 1218
1163 } // namespace bin 1219 } // namespace bin
1164 } // namespace dart 1220 } // namespace dart
1165 1221
1166 #endif // !defined(DART_IO_DISABLED) 1222 #endif // !defined(DART_IO_DISABLED)
OLDNEW
« no previous file with comments | « runtime/bin/file.h ('k') | runtime/bin/file_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698