/*
* 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.
typedef std::unique_ptr<LockedFile, LockedFileCloseNoFlush> ScopedFlock;
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_