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

Unified Diff: sdk/lib/_internal/pub/lib/src/io.dart

Issue 333963002: Retry renames on Windows. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/pub/lib/src/io.dart
diff --git a/sdk/lib/_internal/pub/lib/src/io.dart b/sdk/lib/_internal/pub/lib/src/io.dart
index f93f34c6d2eccfb801e5519acf96d8044b2edbfc..7483a5a17b76a65ef0e1be1be7869cf597044bb8 100644
--- a/sdk/lib/_internal/pub/lib/src/io.dart
+++ b/sdk/lib/_internal/pub/lib/src/io.dart
@@ -270,49 +270,57 @@ List<String> listDir(String dir, {bool recursive: false,
/// a symlink only if that symlink is unbroken and points to a directory.
bool dirExists(String dir) => new Directory(dir).existsSync();
-/// Deletes whatever's at [path], whether it's a file, directory, or symlink. If
-/// it's a directory, it will be deleted recursively.
-void deleteEntry(String path) {
- tryDeleteEntry() {
- if (linkExists(path)) {
- log.io("Deleting link $path.");
- new Link(path).deleteSync();
- } else if (dirExists(path)) {
- log.io("Deleting directory $path.");
- new Directory(path).deleteSync(recursive: true);
- } else if (fileExists(path)) {
- log.io("Deleting file $path.");
- new File(path).deleteSync();
- }
- }
-
+/// Try to resiliently perform [operation].
+///
+/// Some file system operations can intermittently fail on Windows because
+/// other processes are locking a file. We've seen this with virus scanners
+/// when we try to delete or move something while it's being scanned. To
+/// mitigate that, on Windows, this will retry the operation a few times if it
+/// fails.
+void _attempt(String description, void operation()) {
if (Platform.operatingSystem != 'windows') {
- tryDeleteEntry();
+ operation();
return;
}
- // On Windows, we can fail to delete an entry if it's in use by another
- // process. The only case where we know this to cause a problem is when
- // testing "pub serve", since it can poll a file at the same time we try to
- // delete it in the test process (issue 16129).
- //
- // TODO(nweiz): Once issue 14428 is fixed for Windows, remove this special
- // handling.
for (var i = 0; i < 2; i++) {
try {
- tryDeleteEntry();
+ operation();
+ return;
} on FileSystemException catch (error) {
- // Errno 32 indicates that the deletion failed because the file was in
- // use.
- if (error.osError.errorCode != 32) rethrow;
+ var reason;
+ if (error.osError.errorCode == 5) {
+ reason = "access was denied";
+ } else if (error.osError.errorCode == 32) {
+ reason = "it was in use by another process";
+ } else {
+ rethrow;
+ }
- log.io("Failed to delete entry because it was in use by another process. "
+ log.io("Failed to $description because $reason. "
"Retrying in 50ms.");
sleep(new Duration(milliseconds: 50));
}
}
- tryDeleteEntry();
+ operation();
nweiz 2014/06/16 20:02:14 It might be nice to catch the error here as well a
Bob Nystrom 2014/06/17 21:30:29 Done.
+}
+
+/// Deletes whatever's at [path], whether it's a file, directory, or symlink. If
+/// it's a directory, it will be deleted recursively.
+void deleteEntry(String path) {
+ _attempt("delete entry", () {
+ if (linkExists(path)) {
+ log.io("Deleting link $path.");
+ new Link(path).deleteSync();
+ } else if (dirExists(path)) {
+ log.io("Deleting directory $path.");
+ new Directory(path).deleteSync(recursive: true);
+ } else if (fileExists(path)) {
+ log.io("Deleting file $path.");
+ new File(path).deleteSync();
+ }
+ });
}
/// "Cleans" [dir]. If that directory already exists, it will be deleted. Then a
@@ -324,14 +332,16 @@ void cleanDir(String dir) {
/// Renames (i.e. moves) the directory [from] to [to].
void renameDir(String from, String to) {
- log.io("Renaming directory $from to $to.");
- try {
- new Directory(from).renameSync(to);
- } on IOException catch (error) {
- // Ensure that [to] isn't left in an inconsistent state. See issue 12436.
- if (entryExists(to)) deleteEntry(to);
- rethrow;
- }
+ _attempt("rename directory", () {
+ log.io("Renaming directory $from to $to.");
+ try {
+ new Directory(from).renameSync(to);
+ } on IOException catch (error) {
+ // Ensure that [to] isn't left in an inconsistent state. See issue 12436.
+ if (entryExists(to)) deleteEntry(to);
+ rethrow;
+ }
+ });
}
/// Creates a new symlink at path [symlink] that points to [target]. Returns a
« 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