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

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

Issue 9310082: Run all directory async operations on a separate thread using native ports (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Adderssed review comments from ager@ (and rebased) Created 8 years, 10 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 | « runtime/bin/directory_posix.cc ('k') | 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 #include "bin/directory.h" 5 #include "bin/directory.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <sys/stat.h> 8 #include <sys/stat.h>
9 9
10 #include "bin/platform.h" 10 #include "bin/platform.h"
(...skipping 17 matching lines...) Expand all
28 snprintf(os_error_message, os_error_message_len, "OS Error %d", error_code); 28 snprintf(os_error_message, os_error_message_len, "OS Error %d", error_code);
29 } 29 }
30 os_error_message[os_error_message_len - 1] = '\0'; 30 os_error_message[os_error_message_len - 1] = '\0';
31 return error_code; 31 return error_code;
32 } 32 }
33 33
34 34
35 // Forward declaration. 35 // Forward declaration.
36 static bool ListRecursively(const char* dir_name, 36 static bool ListRecursively(const char* dir_name,
37 bool recursive, 37 bool recursive,
38 Dart_Port dir_port, 38 DirectoryListing* listing);
39 Dart_Port file_port,
40 Dart_Port done_port,
41 Dart_Port error_port);
42 static bool DeleteRecursively(const char* dir_name); 39 static bool DeleteRecursively(const char* dir_name);
43 40
44 41
45 static bool HandleDir(char* dir_name, 42 static bool HandleDir(char* dir_name,
46 char* path, 43 char* path,
47 int path_length, 44 int path_length,
48 bool recursive, 45 bool recursive,
49 Dart_Port dir_port, 46 DirectoryListing* listing) {
50 Dart_Port file_port,
51 Dart_Port done_port,
52 Dart_Port error_port) {
53 if (strcmp(dir_name, ".") != 0 && 47 if (strcmp(dir_name, ".") != 0 &&
54 strcmp(dir_name, "..") != 0) { 48 strcmp(dir_name, "..") != 0) {
55 size_t written = snprintf(path + path_length, 49 size_t written = snprintf(path + path_length,
56 MAX_PATH - path_length, 50 MAX_PATH - path_length,
57 "%s", 51 "%s",
58 dir_name); 52 dir_name);
59 if (written != strlen(dir_name)) { 53 if (written != strlen(dir_name)) {
60 return false; 54 return false;
61 } 55 }
62 if (dir_port != 0) { 56 bool ok = listing->HandleDirectory(dir_name);
63 Dart_Handle name = Dart_NewString(path); 57 if (!ok) return ok;
64 Dart_Post(dir_port, name);
65 }
66 if (recursive) { 58 if (recursive) {
67 return ListRecursively(path, 59 return ListRecursively(path, recursive, listing);
68 recursive,
69 dir_port,
70 file_port,
71 done_port,
72 error_port);
73 } 60 }
74 } 61 }
75 return true; 62 return true;
76 } 63 }
77 64
78 65
79 static bool HandleFile(char* file_name, 66 static bool HandleFile(char* file_name,
80 char* path, 67 char* path,
81 int path_length, 68 int path_length,
82 Dart_Port file_port) { 69 DirectoryListing* listing) {
83 if (file_port != 0) { 70 size_t written = snprintf(path + path_length,
84 size_t written = snprintf(path + path_length, 71 MAX_PATH - path_length,
85 MAX_PATH - path_length, 72 "%s",
86 "%s", 73 file_name);
87 file_name); 74 if (written != strlen(file_name)) {
88 if (written != strlen(file_name)) { 75 return false;
89 return false; 76 };
90 }; 77 return listing->HandleFile(file_name);
91 Dart_Handle name = Dart_NewString(path);
92 Dart_Post(file_port, name);
93 }
94 return true;
95 } 78 }
96 79
97 80
98 static bool HandleEntry(LPWIN32_FIND_DATA find_file_data, 81 static bool HandleEntry(LPWIN32_FIND_DATA find_file_data,
99 char* path, 82 char* path,
100 int path_length, 83 int path_length,
101 bool recursive, 84 bool recursive,
102 Dart_Port dir_port, 85 DirectoryListing* listing) {
103 Dart_Port file_port,
104 Dart_Port done_port,
105 Dart_Port error_port) {
106 DWORD attributes = find_file_data->dwFileAttributes; 86 DWORD attributes = find_file_data->dwFileAttributes;
107 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { 87 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
108 return HandleDir(find_file_data->cFileName, 88 return HandleDir(find_file_data->cFileName,
109 path, 89 path,
110 path_length, 90 path_length,
111 recursive, 91 recursive,
112 dir_port, 92 listing);
113 file_port,
114 done_port,
115 error_port);
116 } else { 93 } else {
117 return HandleFile(find_file_data->cFileName, path, path_length, file_port); 94 return HandleFile(find_file_data->cFileName, path, path_length, listing);
118 } 95 }
119 } 96 }
120 97
121 98
122 // ComputeFullSearchPath must be called with a path array of size at 99 // ComputeFullSearchPath must be called with a path array of size at
123 // least MAX_PATH. 100 // least MAX_PATH.
124 static bool ComputeFullSearchPath(const char* dir_name, 101 static bool ComputeFullSearchPath(const char* dir_name,
125 char* path, 102 char* path,
126 int* path_length) { 103 int* path_length) {
127 // GetFullPathName only works in a multi-threaded environment if 104 // GetFullPathName only works in a multi-threaded environment if
(...skipping 11 matching lines...) Expand all
139 MAX_PATH - *path_length, 116 MAX_PATH - *path_length,
140 "%s", 117 "%s",
141 "\\*"); 118 "\\*");
142 if (written != 2) { 119 if (written != 2) {
143 return false; 120 return false;
144 } 121 }
145 *path_length += written; 122 *path_length += written;
146 return true; 123 return true;
147 } 124 }
148 125
149 static void PostError(Dart_Port error_port, 126 static void PostError(DirectoryListing* listing,
150 const char* prefix, 127 const char* prefix,
151 const char* suffix) { 128 const char* suffix) {
152 if (error_port != 0) { 129 char* error_str = Platform::StrError(GetLastError());
153 char* error_str = Platform::StrError(GetLastError()); 130 int error_message_size =
154 int error_message_size = 131 strlen(prefix) + strlen(suffix) + strlen(error_str) + 3;
155 strlen(prefix) + strlen(suffix) + strlen(error_str) + 3; 132 char* message = static_cast<char*>(malloc(error_message_size + 1));
156 char* message = static_cast<char*>(malloc(error_message_size + 1)); 133 size_t written = snprintf(message,
157 size_t written = snprintf(message, 134 error_message_size + 1,
158 error_message_size + 1, 135 "%s%s (%s)",
159 "%s%s (%s)", 136 prefix,
160 prefix, 137 suffix,
161 suffix, 138 error_str);
162 error_str); 139 ASSERT(written == error_message_size);
163 ASSERT(written == error_message_size); 140 free(error_str);
164 free(error_str); 141 listing->HandleError(message);
165 Dart_Post(error_port, Dart_NewString(message)); 142 free(message);
166 free(message);
167 }
168 } 143 }
169 144
170 145
171 static bool ListRecursively(const char* dir_name, 146 static bool ListRecursively(const char* dir_name,
172 bool recursive, 147 bool recursive,
173 Dart_Port dir_port, 148 DirectoryListing* listing) {
174 Dart_Port file_port,
175 Dart_Port done_port,
176 Dart_Port error_port) {
177 // Compute full path for the directory currently being listed. The 149 // Compute full path for the directory currently being listed. The
178 // path buffer will be used to construct the current path in the 150 // path buffer will be used to construct the current path in the
179 // recursive traversal. path_length does not always equal 151 // recursive traversal. path_length does not always equal
180 // strlen(path) but indicates the current prefix of path that is the 152 // strlen(path) but indicates the current prefix of path that is the
181 // path of the current directory in the traversal. 153 // path of the current directory in the traversal.
182 char* path = static_cast<char*>(malloc(MAX_PATH)); 154 char* path = static_cast<char*>(malloc(MAX_PATH));
183 int path_length = 0; 155 int path_length = 0;
184 bool valid = ComputeFullSearchPath(dir_name, path, &path_length); 156 bool valid = ComputeFullSearchPath(dir_name, path, &path_length);
185 if (!valid) { 157 if (!valid) {
186 PostError(error_port, "Directory listing failed for: ", dir_name); 158 PostError(listing, "Directory listing failed for: ", dir_name);
187 free(path); 159 free(path);
188 return false; 160 return false;
189 } 161 }
190 162
191 WIN32_FIND_DATA find_file_data; 163 WIN32_FIND_DATA find_file_data;
192 HANDLE find_handle = FindFirstFile(path, &find_file_data); 164 HANDLE find_handle = FindFirstFile(path, &find_file_data);
193 165
194 // Adjust the path by removing the '*' used for the search. 166 // Adjust the path by removing the '*' used for the search.
195 path_length -= 1; 167 path_length -= 1;
196 path[path_length] = '\0'; 168 path[path_length] = '\0';
197 169
198 if (find_handle == INVALID_HANDLE_VALUE) { 170 if (find_handle == INVALID_HANDLE_VALUE) {
199 PostError(error_port, "Directory listing failed for: ", path); 171 PostError(listing, "Directory listing failed for: ", path);
200 free(path); 172 free(path);
201 return false; 173 return false;
202 } 174 }
203 175
204 bool success = HandleEntry(&find_file_data, 176 bool success = HandleEntry(&find_file_data,
205 path, 177 path,
206 path_length, 178 path_length,
207 recursive, 179 recursive,
208 dir_port, 180 listing);
209 file_port,
210 done_port,
211 error_port);
212 181
213 while ((FindNextFile(find_handle, &find_file_data) != 0) && success) { 182 while ((FindNextFile(find_handle, &find_file_data) != 0) && success) {
214 success = success && HandleEntry(&find_file_data, 183 success = success && HandleEntry(&find_file_data,
215 path, 184 path,
216 path_length, 185 path_length,
217 recursive, 186 recursive,
218 dir_port, 187 listing);
219 file_port,
220 done_port,
221 error_port);
222 } 188 }
223 189
224 if (GetLastError() != ERROR_NO_MORE_FILES) { 190 if (GetLastError() != ERROR_NO_MORE_FILES) {
225 success = false; 191 success = false;
226 PostError(error_port, "Directory listing failed", ""); 192 PostError(listing, "Directory listing failed", "");
227 } 193 }
228 194
229 if (FindClose(find_handle) == 0) { 195 if (FindClose(find_handle) == 0) {
230 PostError(error_port, "Failed to close directory", ""); 196 PostError(listing, "Failed to close directory", "");
231 } 197 }
232 free(path); 198 free(path);
233 199
234 return success; 200 return success;
235 } 201 }
236 202
237 203
238 static bool DeleteFile(char* file_name, 204 static bool DeleteFile(char* file_name,
239 char* path, 205 char* path,
240 int path_length) { 206 int path_length) {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 if ((GetLastError() != ERROR_NO_MORE_FILES) || 282 if ((GetLastError() != ERROR_NO_MORE_FILES) ||
317 (FindClose(find_handle) == 0) || 283 (FindClose(find_handle) == 0) ||
318 (RemoveDirectory(dir_name) == 0)) { 284 (RemoveDirectory(dir_name) == 0)) {
319 return false; 285 return false;
320 } 286 }
321 287
322 return success; 288 return success;
323 } 289 }
324 290
325 291
326 void Directory::List(const char* dir_name, 292 bool Directory::List(const char* dir_name,
327 bool recursive, 293 bool recursive,
328 Dart_Port dir_port, 294 DirectoryListing* listing) {
329 Dart_Port file_port, 295 bool completed = ListRecursively(dir_name, recursive, listing);
330 Dart_Port done_port, 296 return completed;
331 Dart_Port error_port) {
332 bool result = ListRecursively(dir_name,
333 recursive,
334 dir_port,
335 file_port,
336 done_port,
337 error_port);
338 if (done_port != 0) {
339 Dart_Handle value = Dart_NewBoolean(result);
340 Dart_Post(done_port, value);
341 }
342 } 297 }
343 298
344 299
345 Directory::ExistsResult Directory::Exists(const char* dir_name) { 300 Directory::ExistsResult Directory::Exists(const char* dir_name) {
346 struct stat entry_info; 301 struct stat entry_info;
347 int stat_success = stat(dir_name, &entry_info); 302 int stat_success = stat(dir_name, &entry_info);
348 if (stat_success == 0) { 303 if (stat_success == 0) {
349 if ((entry_info.st_mode & S_IFMT) == S_IFDIR) { 304 if ((entry_info.st_mode & S_IFMT) == S_IFDIR) {
350 return EXISTS; 305 return EXISTS;
351 } else { 306 } else {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 } 395 }
441 396
442 397
443 bool Directory::Delete(const char* dir_name, bool recursive) { 398 bool Directory::Delete(const char* dir_name, bool recursive) {
444 if (!recursive) { 399 if (!recursive) {
445 return (RemoveDirectory(dir_name) != 0); 400 return (RemoveDirectory(dir_name) != 0);
446 } else { 401 } else {
447 return DeleteRecursively(dir_name); 402 return DeleteRecursively(dir_name);
448 } 403 }
449 } 404 }
OLDNEW
« no previous file with comments | « runtime/bin/directory_posix.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698