| 639 | } |
| 640 | |
| 641 | Status LockFile(const std::string& filename, FileLock** lock) override { |
| 642 | *lock = nullptr; |
| 643 | |
| 644 | int fd = ::open(filename.c_str(), O_RDWR | O_CREAT | kOpenBaseFlags, 0644); |
| 645 | if (fd < 0) { |
| 646 | return PosixError(filename, errno); |
| 647 | } |
| 648 | |
| 649 | if (!locks_.Insert(filename)) { |
| 650 | ::close(fd); |
| 651 | return Status::IOError("lock " + filename, "already held by process"); |
| 652 | } |
| 653 | |
| 654 | if (LockOrUnlock(fd, true) == -1) { |
| 655 | int lock_errno = errno; |
| 656 | ::close(fd); |
| 657 | locks_.Remove(filename); |
| 658 | return PosixError("lock " + filename, lock_errno); |
| 659 | } |
| 660 | |
| 661 | *lock = new PosixFileLock(fd, filename); |
| 662 | return Status::OK(); |
| 663 | } |
| 664 | |
| 665 | Status UnlockFile(FileLock* lock) override { |
| 666 | PosixFileLock* posix_file_lock = static_cast<PosixFileLock*>(lock); |