| ... | ... | @@ -434,24 +434,29 @@ pub const Manifest = struct { |
| 434 | 434 | } |
| 435 | 435 | } |
| 436 | 436 | } else { |
| 437 | | if (self.cache.manifest_dir.createFile(&manifest_file_path, .{ |
| 438 | | .read = true, |
| 439 | | .truncate = false, |
| 440 | | .lock = .Exclusive, |
| 441 | | .lock_nonblocking = self.want_shared_lock, |
| 442 | | })) |manifest_file| { |
| 443 | | self.manifest_file = manifest_file; |
| 444 | | self.have_exclusive_lock = true; |
| 445 | | } else |err| switch (err) { |
| 446 | | // There are no dir components, so you would think that this was |
| 447 | | // unreachable, however we have observed on macOS two processes racing |
| 448 | | // to do openat() with O_CREAT manifest in ENOENT. |
| 449 | | error.WouldBlock, error.FileNotFound => { |
| 450 | | self.manifest_file = try self.cache.manifest_dir.openFile(&manifest_file_path, .{ |
| 451 | | .lock = .Shared, |
| 452 | | }); |
| 453 | | }, |
| 454 | | else => |e| return e, |
| 437 | while (true) { |
| 438 | if (self.cache.manifest_dir.createFile(&manifest_file_path, .{ |
| 439 | .read = true, |
| 440 | .truncate = false, |
| 441 | .lock = .Exclusive, |
| 442 | .lock_nonblocking = self.want_shared_lock, |
| 443 | })) |manifest_file| { |
| 444 | self.manifest_file = manifest_file; |
| 445 | self.have_exclusive_lock = true; |
| 446 | break; |
| 447 | } else |err| switch (err) { |
| 448 | error.WouldBlock => { |
| 449 | self.manifest_file = try self.cache.manifest_dir.openFile(&manifest_file_path, .{ |
| 450 | .lock = .Shared, |
| 451 | }); |
| 452 | break; |
| 453 | }, |
| 454 | // There are no dir components, so you would think that this was |
| 455 | // unreachable, however we have observed on macOS two processes racing |
| 456 | // to do openat() with O_CREAT manifest in ENOENT. |
| 457 | error.FileNotFound => continue, |
| 458 | else => |e| return e, |
| 459 | } |
| 455 | 460 | } |
| 456 | 461 | } |
| 457 | 462 | |