| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef ART_LIBARTBASE_BASE_SCOPED_FLOCK_H_ |
| #define ART_LIBARTBASE_BASE_SCOPED_FLOCK_H_ |
| |
| #include <memory> |
| #include <string> |
| |
| #include <android-base/unique_fd.h> |
| |
| #include "macros.h" |
| #include "os.h" |
| #include "unix_file/fd_file.h" |
| |
| namespace art { |
| |
| class LockedFile; |
| class LockedFileCloseNoFlush; |
| |
| // A scoped File object that calls Close without flushing. |
| using ScopedFlock = std::unique_ptr<LockedFile, LockedFileCloseNoFlush>; |
| |
| class LockedFile : public unix_file::FdFile { |
| public: |
| // Attempts to acquire an exclusive file lock (see flock(2)) on the file |
| // at filename, and blocks until it can do so. |
| // |
| // It is an error if its inode changed (usually due to a new file being |
| // created at the same path) between attempts to lock it. In blocking mode, |
| // locking will be retried if the file changed. In non-blocking mode, false |
| // is returned and no attempt is made to re-acquire the lock. |
| // |
| // The file is opened with the provided flags. |
| static ScopedFlock Open(const char* filename, int flags, bool block, |
| std::string* error_msg); |
| |
| // Calls Open(filename, O_CREAT | O_RDWR, true, errror_msg) |
| static ScopedFlock Open(const char* filename, std::string* error_msg); |
| |
| // Attempt to acquire an exclusive file lock (see flock(2)) on 'file'. |
| // Returns true if the lock could be acquired or false if an error |
| // occured. |
| static ScopedFlock DupOf(const int fd, const std::string& path, |
| const bool read_only_mode, std::string* error_message); |
| |
| // Release a lock held on this file, if any. |
| void ReleaseLock(); |
| |
| private: |
| // Constructors should not be invoked directly, use one of the factory |
| // methods instead. |
| explicit LockedFile(FdFile&& other) : FdFile(std::move(other)) { |
| } |
| |
| // Constructors should not be invoked directly, use one of the factory |
| // methods instead. |
| LockedFile(int fd, const std::string& path, bool check_usage, bool read_only_mode) |
| : FdFile(fd, path, check_usage, read_only_mode) { |
| } |
| }; |
| |
| class LockedFileCloseNoFlush { |
| public: |
| void operator()(LockedFile* ptr) { |
| ptr->ReleaseLock(); |
| UNUSED(ptr->Close()); |
| |
| delete ptr; |
| } |
| }; |
| |
| } // namespace art |
| |
| #endif // ART_LIBARTBASE_BASE_SCOPED_FLOCK_H_ |