/*
 * 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_
