1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_RUNTIME_BASE_SCOPED_FLOCK_H_ 18 #define ART_RUNTIME_BASE_SCOPED_FLOCK_H_ 19 20 #include <memory> 21 #include <string> 22 23 #include "base/macros.h" 24 #include "os.h" 25 26 namespace art { 27 28 // A scoped file-lock implemented using flock. The file is locked by calling the Init function and 29 // is released during destruction. Note that failing to unlock the file only causes a warning to be 30 // printed. Users should take care that this does not cause potential deadlocks. 31 // 32 // Only printing a warning on unlock failure is okay since this is only used with either: 33 // 1) a non-blocking Init call, or 34 // 2) as a part of a seperate binary (eg dex2oat) which has it's own timeout logic to prevent 35 // deadlocks. 36 // This means we can be sure that the warning won't cause a deadlock. 37 class ScopedFlock { 38 public: 39 ScopedFlock(); 40 41 // Attempts to acquire an exclusive file lock (see flock(2)) on the file 42 // at filename, and blocks until it can do so. 43 // 44 // Returns true if the lock could be acquired, or false if an error occurred. 45 // It is an error if its inode changed (usually due to a new file being 46 // created at the same path) between attempts to lock it. In blocking mode, 47 // locking will be retried if the file changed. In non-blocking mode, false 48 // is returned and no attempt is made to re-acquire the lock. 49 // 50 // The argument `flush_on_close` controls whether or not the file 51 // will be explicitly flushed before close. 52 // 53 // The file is opened with the provided flags. 54 bool Init(const char* filename, 55 int flags, 56 bool block, 57 bool flush_on_close, 58 std::string* error_msg); 59 // Calls Init(filename, flags, block, true, error_msg); 60 bool Init(const char* filename, int flags, bool block, std::string* error_msg); 61 // Calls Init(filename, O_CREAT | O_RDWR, true, errror_msg) 62 bool Init(const char* filename, std::string* error_msg); 63 // Attempt to acquire an exclusive file lock (see flock(2)) on 'file'. 64 // Returns true if the lock could be acquired or false if an error 65 // occured. 66 bool Init(File* file, std::string* error_msg); 67 68 // Returns the (locked) file associated with this instance. 69 File* GetFile() const; 70 71 // Returns whether a file is held. 72 bool HasFile(); 73 74 ~ScopedFlock(); 75 76 private: 77 std::unique_ptr<File> file_; 78 bool flush_on_close_; 79 DISALLOW_COPY_AND_ASSIGN(ScopedFlock); 80 }; 81 82 } // namespace art 83 84 #endif // ART_RUNTIME_BASE_SCOPED_FLOCK_H_ 85