[Groonga-commit] groonga/grnxx [master] Update the interface of grnxx::io::File.

Back to archive index

susumu.yata null+****@clear*****
Fri Feb 22 16:57:36 JST 2013


susumu.yata	2013-02-22 16:57:36 +0900 (Fri, 22 Feb 2013)

  New Revision: 384b7bf04379351d2cce2cabb95ce1db1f11bcff
  https://github.com/groonga/grnxx/commit/384b7bf04379351d2cce2cabb95ce1db1f11bcff

  Log:
    Update the interface of grnxx::io::File.

  Modified files:
    lib/io/file-posix.cpp
    lib/io/file-posix.hpp
    lib/io/file-windows.cpp
    lib/io/file-windows.hpp
    lib/io/file.cpp
    lib/io/file.hpp
    lib/io/file_info.cpp
    lib/io/file_info.hpp
    lib/io/pool-impl.cpp
    lib/io/pool-impl.hpp
    lib/io/view-posix.cpp
    lib/io/view-posix.hpp
    lib/io/view-windows.cpp
    lib/io/view-windows.hpp
    lib/io/view.cpp
    lib/io/view.hpp
    test/test_io_file.cpp
    test/test_io_file_info.cpp
    test/test_io_view.cpp

  Modified: lib/io/file-posix.cpp (+37 -38)
===================================================================
--- lib/io/file-posix.cpp    2013-02-22 14:49:57 +0900 (1d6c6ed)
+++ lib/io/file-posix.cpp    2013-02-22 16:57:36 +0900 (ffaaedb)
@@ -50,8 +50,7 @@ FileImpl::~FileImpl() {
   }
 }
 
-std::unique_ptr<FileImpl> FileImpl::open(FileFlags flags, const char *path,
-                                         int permission) {
+FileImpl *FileImpl::open(FileFlags flags, const char *path, int permission) {
   std::unique_ptr<FileImpl> file(new (std::nothrow) FileImpl);
   if (!file) {
     GRNXX_ERROR() << "new grnxx::io::FileImpl failed";
@@ -63,7 +62,42 @@ std::unique_ptr<FileImpl> FileImpl::open(FileFlags flags, const char *path,
   } else {
     file->open_regular_file(flags, path, permission);
   }
-  return file;
+  return file.release();
+}
+
+bool FileImpl::exists(const char *path) {
+  if (!path) {
+    GRNXX_ERROR() << "invalid argument: path = " << path;
+    GRNXX_THROW();
+  }
+
+  struct stat stat;
+  if (::stat(path, &stat) != 0) {
+    return false;
+  }
+  return S_ISREG(stat.st_mode);
+}
+
+void FileImpl::unlink(const char *path) {
+  if (!path) {
+    GRNXX_ERROR() << "invalid argument: path = " << path;
+    GRNXX_THROW();
+  }
+
+  if (::unlink(path) != 0) {
+    GRNXX_ERROR() << "failed to unlink file: path = " << path
+                  << ": '::unlink' " << Error(errno);
+    GRNXX_THROW();
+  }
+}
+
+bool FileImpl::unlink_if_exists(const char *path) {
+  if (!path) {
+    GRNXX_ERROR() << "invalid argument: path = " << path;
+    GRNXX_THROW();
+  }
+
+  return ::unlink(path) == 0;
 }
 
 void FileImpl::lock(FileLockMode mode) {
@@ -334,41 +368,6 @@ uint64_t FileImpl::size() const {
   return stat.st_size;
 }
 
-bool FileImpl::exists(const char *path) {
-  if (!path) {
-    GRNXX_ERROR() << "invalid argument: path = " << path;
-    GRNXX_THROW();
-  }
-
-  struct stat stat;
-  if (::stat(path, &stat) != 0) {
-    return false;
-  }
-  return S_ISREG(stat.st_mode);
-}
-
-void FileImpl::unlink(const char *path) {
-  if (!path) {
-    GRNXX_ERROR() << "invalid argument: path = " << path;
-    GRNXX_THROW();
-  }
-
-  if (::unlink(path) != 0) {
-    GRNXX_ERROR() << "failed to unlink file: path = " << path
-                  << ": '::unlink' " << Error(errno);
-    GRNXX_THROW();
-  }
-}
-
-bool FileImpl::unlink_if_exists(const char *path) {
-  if (!path) {
-    GRNXX_ERROR() << "invalid argument: path = " << path;
-    GRNXX_THROW();
-  }
-
-  return ::unlink(path) == 0;
-}
-
 FileImpl::FileImpl()
   : path_(), flags_(FileFlags::none()), fd_(-1), locked_(false),
     unlink_at_close_(false) {}

  Modified: lib/io/file-posix.hpp (+6 -15)
===================================================================
--- lib/io/file-posix.hpp    2013-02-22 14:49:57 +0900 (53e8033)
+++ lib/io/file-posix.hpp    2013-02-22 16:57:36 +0900 (50171ee)
@@ -25,12 +25,15 @@
 namespace grnxx {
 namespace io {
 
-class FileImpl {
+class FileImpl : public File {
  public:
   ~FileImpl();
 
-  static std::unique_ptr<FileImpl> open(FileFlags flags, const char *path,
-                                        int permission);
+  static FileImpl *open(FileFlags flags, const char *path, int permission);
+
+  static bool exists(const char *path);
+  static void unlink(const char *path);
+  static bool unlink_if_exists(const char *path);
 
   void lock(FileLockMode mode);
   bool lock(FileLockMode mode, Duration timeout);
@@ -70,10 +73,6 @@ class FileImpl {
 
   StringBuilder &write_to(StringBuilder &builder) const;
 
-  static bool exists(const char *path);
-  static void unlink(const char *path);
-  static bool unlink_if_exists(const char *path);
-
  private:
   String path_;
   FileFlags flags_;
@@ -85,16 +84,8 @@ class FileImpl {
 
   void open_regular_file(FileFlags flags, const char *path, int permission);
   void open_temporary_file(FileFlags flags, const char *path, int permission);
-
-  FileImpl(const FileImpl &);
-  FileImpl &operator=(const FileImpl &);
 };
 
-inline StringBuilder &operator<<(StringBuilder &builder,
-                                 const FileImpl &file) {
-  return file.write_to(builder);
-}
-
 }  // namespace io
 }  // namespace grnxx
 

  Modified: lib/io/file-windows.cpp (+35 -35)
===================================================================
--- lib/io/file-windows.cpp    2013-02-22 14:49:57 +0900 (80567af)
+++ lib/io/file-windows.cpp    2013-02-22 16:57:36 +0900 (a4f676f)
@@ -61,6 +61,41 @@ std::unique_ptr<FileImpl> FileImpl::open(FileFlags flags, const char *path,
   return file;
 }
 
+bool FileImpl::exists(const char *path) {
+  if (!path) {
+    GRNXX_ERROR() << "invalid argument: path = " << path;
+    GRNXX_THROW();
+  }
+
+  struct _stat stat;
+  if (::_stat(path, &stat) != 0) {
+    return false;
+  }
+  return stat.st_mode & _S_IFREG;
+}
+
+void FileImpl::unlink(const char *path) {
+  if (!path) {
+    GRNXX_ERROR() << "invalid argument: path = " << path;
+    GRNXX_THROW();
+  }
+
+  if (!::DeleteFile(path)) {
+    GRNXX_ERROR() << "failed to unlink file: path = " << path
+                  << ": '::DeleteFile' " << Error(::GetLastError());
+    GRNXX_THROW();
+  }
+}
+
+bool FileImpl::unlink_if_exists(const char *path) {
+  if (!path) {
+    GRNXX_ERROR() << "invalid argument: path = " << path;
+    GRNXX_THROW();
+  }
+
+  return ::DeleteFile(path);
+}
+
 void FileImpl::lock(FileLockMode mode) {
   if (locked_) {
     GRNXX_ERROR() << "deadlock: file = " << *this;
@@ -312,41 +347,6 @@ uint64_t FileImpl::size() const {
   return file_size.QuadPart;
 }
 
-bool FileImpl::exists(const char *path) {
-  if (!path) {
-    GRNXX_ERROR() << "invalid argument: path = " << path;
-    GRNXX_THROW();
-  }
-
-  struct _stat stat;
-  if (::_stat(path, &stat) != 0) {
-    return false;
-  }
-  return stat.st_mode & _S_IFREG;
-}
-
-void FileImpl::unlink(const char *path) {
-  if (!path) {
-    GRNXX_ERROR() << "invalid argument: path = " << path;
-    GRNXX_THROW();
-  }
-
-  if (!::DeleteFile(path)) {
-    GRNXX_ERROR() << "failed to unlink file: path = " << path
-                  << ": '::DeleteFile' " << Error(::GetLastError());
-    GRNXX_THROW();
-  }
-}
-
-bool FileImpl::unlink_if_exists(const char *path) {
-  if (!path) {
-    GRNXX_ERROR() << "invalid argument: path = " << path;
-    GRNXX_THROW();
-  }
-
-  return ::DeleteFile(path);
-}
-
 FileImpl::FileImpl()
   : path_(), flags_(FileFlags::none()), handle_(INVALID_HANDLE_VALUE),
     append_mode_(false), locked_(false), unlink_at_close_(false) {}

  Modified: lib/io/file-windows.hpp (+4 -4)
===================================================================
--- lib/io/file-windows.hpp    2013-02-22 14:49:57 +0900 (26cdaf3)
+++ lib/io/file-windows.hpp    2013-02-22 16:57:36 +0900 (46cc503)
@@ -41,6 +41,10 @@ class FileImpl {
   static std::unique_ptr<FileImpl> open(FileFlags flags, const char *path,
                                         int permission);
 
+  static bool exists(const char *path);
+  static void unlink(const char *path);
+  static bool unlink_if_exists(const char *path);
+
   void lock(FileLockMode mode);
   bool lock(FileLockMode mode, Duration timeout);
   bool try_lock(FileLockMode mode);
@@ -79,10 +83,6 @@ class FileImpl {
 
   StringBuilder &write_to(StringBuilder &builder) const;
 
-  static bool exists(const char *path);
-  static void unlink(const char *path);
-  static bool unlink_if_exists(const char *path);
-
  private:
   String path_;
   FileFlags flags_;

  Modified: lib/io/file.cpp (+3 -118)
===================================================================
--- lib/io/file.cpp    2013-02-22 14:49:57 +0900 (096bcbc)
+++ lib/io/file.cpp    2013-02-22 16:57:36 +0900 (acc6b61)
@@ -60,115 +60,11 @@ std::ostream &operator<<(std::ostream &stream, FileFlags flags) {
   return stream.write(builder.c_str(), builder.length());
 }
 
-File::File() : impl_() {}
-
-File::File(FileFlags flags, const char *path, int permission)
-  : impl_(FileImpl::open(flags, path, permission)) {}
-
+File::File() {}
 File::~File() {}
 
-File::File(const File &file) : impl_(file.impl_) {}
-
-File &File::operator=(const File &file) {
-  impl_ = file.impl_;
-  return *this;
-}
-
-File::File(File &&file) : impl_(std::move(file.impl_)) {}
-
-File &File::operator=(File &&file) {
-  impl_ = std::move(file.impl_);
-  return *this;
-}
-
-void File::lock(FileLockMode mode) {
-  throw_if_impl_is_invalid();
-  impl_->lock(mode);
-}
-
-bool File::lock(FileLockMode mode, Duration timeout) {
-  throw_if_impl_is_invalid();
-  return impl_->lock(mode, timeout);
-}
-
-bool File::try_lock(FileLockMode mode) {
-  throw_if_impl_is_invalid();
-  return impl_->try_lock(mode);
-}
-
-bool File::unlock() {
-  throw_if_impl_is_invalid();
-  return impl_->unlock();
-}
-
-uint64_t File::read(void *buf, uint64_t size) {
-  throw_if_impl_is_invalid();
-  return impl_->read(buf, size);
-}
-
-uint64_t File::read(void *buf, uint64_t size, uint64_t offset) {
-  throw_if_impl_is_invalid();
-  return impl_->read(buf, size, offset);
-}
-
-uint64_t File::write(const void *buf, uint64_t size) {
-  throw_if_impl_is_invalid();
-  return impl_->write(buf, size);
-}
-
-uint64_t File::write(const void *buf, uint64_t size, uint64_t offset) {
-  throw_if_impl_is_invalid();
-  return impl_->write(buf, size, offset);
-}
-
-void File::sync() {
-  throw_if_impl_is_invalid();
-  impl_->sync();
-}
-
-uint64_t File::seek(int64_t offset, int whence) {
-  throw_if_impl_is_invalid();
-  return impl_->seek(offset, whence);
-}
-
-uint64_t File::tell() const {
-  throw_if_impl_is_invalid();
-  return impl_->tell();
-}
-
-void File::resize(uint64_t size) {
-  throw_if_impl_is_invalid();
-  impl_->resize(size);
-}
-
-uint64_t File::size() const {
-  throw_if_impl_is_invalid();
-  return impl_->size();
-}
-
-bool File::unlink_at_close() const {
-  return impl_ ? impl_->unlink_at_close() : false;
-}
-
-void File::set_unlink_at_close(bool value) {
-  throw_if_impl_is_invalid();
-  impl_->set_unlink_at_close(value);
-}
-
-String File::path() const {
-  return impl_ ? impl_->path() : String();
-}
-
-FileFlags File::flags() const {
-  return impl_ ? impl_->flags() : FileFlags::none();
-}
-
-const void *File::handle() const {
-  return impl_ ? impl_->handle() : nullptr;
-}
-
-void File::swap(File &file) {
-  impl_.swap(file.impl_);
+File *File::open(FileFlags flags, const char *path, int permission) {
+  return FileImpl::open(flags, path, permission);
 }
 
 bool File::exists(const char *path) {
@@ -183,16 +79,5 @@ bool File::unlink_if_exists(const char *path) {
   return FileImpl::unlink_if_exists(path);
 }
 
-void File::throw_if_impl_is_invalid() const {
-  if (!impl_) {
-    GRNXX_ERROR() << "invalid instance: file = " << *this;
-    GRNXX_THROW();
-  }
-}
-
-StringBuilder &File::write_to(StringBuilder &builder) const {
-  return impl_ ? impl_->write_to(builder) : (builder << "n/a");
-}
-
 }  // namespace io
 }  // namespace grnxx

  Modified: lib/io/file.hpp (+25 -54)
===================================================================
--- lib/io/file.hpp    2013-02-22 14:49:57 +0900 (aeff6b7)
+++ lib/io/file.hpp    2013-02-22 16:57:36 +0900 (588a439)
@@ -65,97 +65,68 @@ enum FileLockMode {
   FILE_LOCK_SHARED    = 0x2000   // Create a shared lock.
 };
 
-class FileImpl;
-
 // Note: Windows ignores permission.
 class File {
  public:
   File();
-  explicit File(FileFlags flags, const char *path = nullptr,
-                int permission = 0644);
-  ~File();
-
-  File(const File &file);
-  File &operator=(const File &file);
+  virtual ~File();
 
-  File(File &&file);
-  File &operator=(File &&file);
+  static File *open(FileFlags flags, const char *path = nullptr,
+                    int permission = 0644);
 
-  explicit operator bool() const {
-    return static_cast<bool>(impl_);
-  }
-
-  void open(FileFlags flags, const char *path) {
-    *this = File(flags | FILE_OPEN, path);
-  }
-  void close() {
-    *this = File();
-  }
+  static bool exists(const char *path);
+  static void unlink(const char *path);
+  static bool unlink_if_exists(const char *path);
 
   // The following functions operate advisory locks for files, not for
   // FileImpl instances. The word "advisory" indicates that the file is
   // accessible even if it is locked.
 
-  void lock(FileLockMode mode);
+  virtual void lock(FileLockMode mode) = 0;
   // lock() returns true on success, false on failure.
-  bool lock(FileLockMode mode, Duration timeout);
+  virtual bool lock(FileLockMode mode, Duration timeout) = 0;
   // try_lock() returns false if the file is already locked.
-  bool try_lock(FileLockMode mode);
+  virtual bool try_lock(FileLockMode mode) = 0;
   // unlock() returns false if the file is not locked.
-  bool unlock();
+  virtual bool unlock() = 0;
 
   // The following functions are not thread-safe.
 
   // read() reads data from file at most size bytes and returns the number of
   // actually read bytes.
-  uint64_t read(void *buf, uint64_t size);
-  uint64_t read(void *buf, uint64_t size, uint64_t offset);
+  virtual uint64_t read(void *buf, uint64_t size) = 0;
+  virtual uint64_t read(void *buf, uint64_t size, uint64_t offset) = 0;
   // write() writes data into file at most size bytes and returns the number
   // of actually written bytes.
-  uint64_t write(const void *buf, uint64_t size);
-  uint64_t write(const void *buf, uint64_t size, uint64_t offset);
+  virtual uint64_t write(const void *buf, uint64_t size) = 0;
+  virtual uint64_t write(const void *buf, uint64_t size, uint64_t offset) = 0;
 
-  void sync();
+  virtual void sync() = 0;
 
   // seek() moves the file pointer and returns the new position.
-  uint64_t seek(int64_t offset, int whence = SEEK_SET);
+  virtual uint64_t seek(int64_t offset, int whence = SEEK_SET) = 0;
   // tell() returns the current position.
-  uint64_t tell() const;
+  virtual uint64_t tell() const = 0;
 
   // resize() resizes the file and moves the file pointer to the new
   // end-of-file.
-  void resize(uint64_t size);
+  virtual void resize(uint64_t size) = 0;
   // size() returns the file size in bytes.
-  uint64_t size() const;
+  virtual uint64_t size() const = 0;
 
   // If true, the associated path will be unlinked after closing the file
   // handle.
-  bool unlink_at_close() const;
-  void set_unlink_at_close(bool value);
-
-  String path() const;
-  FileFlags flags() const;
-
-  const void *handle() const;
+  virtual bool unlink_at_close() const = 0;
+  virtual void set_unlink_at_close(bool value) = 0;
 
-  void swap(File &file);
+  virtual String path() const = 0;
+  virtual FileFlags flags() const = 0;
 
-  StringBuilder &write_to(StringBuilder &builder) const;
+  virtual const void *handle() const = 0;
 
-  static bool exists(const char *path);
-  static void unlink(const char *path);
-  static bool unlink_if_exists(const char *path);
-
- private:
-  std::shared_ptr<FileImpl> impl_;
-
-  void throw_if_impl_is_invalid() const;
+  virtual StringBuilder &write_to(StringBuilder &builder) const = 0;
 };
 
-inline void swap(File &lhs, File &rhs) {
-  lhs.swap(rhs);
-}
-
 inline StringBuilder &operator<<(StringBuilder &builder, const File &file) {
   return file.write_to(builder);
 }

  Modified: lib/io/file_info.cpp (+7 -7)
===================================================================
--- lib/io/file_info.cpp    2013-02-22 14:49:57 +0900 (edf8ee1)
+++ lib/io/file_info.cpp    2013-02-22 16:57:36 +0900 (5075ed9)
@@ -40,7 +40,7 @@ typedef struct stat Stat;
 class Impl : public FileInfo {
  public:
   static Impl *stat(const char *path);
-  static Impl *stat(const File &file);
+  static Impl *stat(File *file);
 
   bool is_file() const {
 #ifdef GRNXX_WINDOWS
@@ -127,17 +127,17 @@ Impl *Impl::stat(const char *path) {
   return file_info.release();
 }
 
-Impl *Impl::stat(const File &file) {
+Impl *Impl::stat(File *file) {
   Stat stat;
 #ifdef GRNXX_WINDOWS
-  if (::_stat(file.path().c_str(), &stat) != 0) {
+  if (::_stat(file->path().c_str(), &stat) != 0) {
     if (errno != ENOENT) {
-      GRNXX_WARNING() << "failed to get file information: file = " << file
+      GRNXX_WARNING() << "failed to get file information: file = " << *file
                       << ": '::_stat' " << Error(errno);
     }
 #else  // GRNXX_WINDOWS
-  if (::fstat(*static_cast<const int *>(file.handle()), &stat) != 0) {
-    GRNXX_WARNING() << "failed to get file information: file = " << file
+  if (::fstat(*static_cast<const int *>(file->handle()), &stat) != 0) {
+    GRNXX_WARNING() << "failed to get file information: file = " << *file
                     << ": '::fstat' " << Error(errno);
 #endif  // GRNXX_WINDOWS
     return nullptr;
@@ -177,7 +177,7 @@ FileInfo *FileInfo::stat(const char *path) {
   return Impl::stat(path);
 }
 
-FileInfo *FileInfo::stat(const File &file) {
+FileInfo *FileInfo::stat(File *file) {
   return Impl::stat(file);
 }
 

  Modified: lib/io/file_info.hpp (+1 -1)
===================================================================
--- lib/io/file_info.hpp    2013-02-22 14:49:57 +0900 (112680d)
+++ lib/io/file_info.hpp    2013-02-22 16:57:36 +0900 (ee2908f)
@@ -32,7 +32,7 @@ class FileInfo {
 
   // Return nullptr iff "path" is not a valid path.
   static FileInfo *stat(const char *path);
-  static FileInfo *stat(const File &file);
+  static FileInfo *stat(File *file);
 
   virtual bool is_file() const = 0;
   virtual bool is_directory() const = 0;

  Modified: lib/io/pool-impl.cpp (+24 -24)
===================================================================
--- lib/io/pool-impl.cpp    2013-02-22 14:49:57 +0900 (e975663)
+++ lib/io/pool-impl.cpp    2013-02-22 16:57:36 +0900 (419d3d5)
@@ -170,7 +170,7 @@ StringBuilder &PoolImpl::write_to(StringBuilder &builder) const {
       } else {
         builder << ", ";
       }
-      builder << '[' << i << "] = " << files_[i];
+      builder << '[' << i << "] = " << *files_[i];
     }
   }
   builder << (is_empty ? "{}" : " }");
@@ -225,8 +225,8 @@ void PoolImpl::unlink(const char *path) {
     GRNXX_THROW();
   } else {
     // FIXME
-    File file(FILE_OPEN, path);
-    if (!file.try_lock(FILE_LOCK_EXCLUSIVE)) {
+    std::unique_ptr<File> file(File::open(FILE_OPEN, path));
+    if (!file->try_lock(FILE_LOCK_EXCLUSIVE)) {
       GRNXX_ERROR() << "failed to lock file: path = " << path;
       GRNXX_THROW();
     }
@@ -289,7 +289,7 @@ void PoolImpl::open_temporary_pool(PoolFlags, const char *path,
                                    const PoolOptions &options) {
   path_ = Path::full_path(path);
   flags_ = POOL_TEMPORARY;
-  files_[0].open(FILE_TEMPORARY, path_.c_str());
+  files_[0].reset(File::open(FILE_TEMPORARY, path_.c_str()));
   setup_header(options);
 }
 
@@ -314,23 +314,23 @@ void PoolImpl::open_regular_pool(PoolFlags flags, const char *path,
     flags_ |= POOL_OPEN;
     file_flags |= FILE_OPEN;
   }
-  files_[0].open(file_flags, path_.c_str());
-  files_[0].set_unlink_at_close(true);
+  files_[0].reset(File::open(file_flags, path_.c_str()));
+  files_[0]->set_unlink_at_close(true);
 
   if (flags & POOL_CREATE) {
-    if (files_[0].size() == 0) {
-      if (files_[0].lock(FILE_LOCK_EXCLUSIVE, Duration::seconds(10))) {
-        if (files_[0].size() == 0) {
+    if (files_[0]->size() == 0) {
+      if (files_[0]->lock(FILE_LOCK_EXCLUSIVE, Duration::seconds(10))) {
+        if (files_[0]->size() == 0) {
           setup_header(options);
-          files_[0].unlock();
-          if (!files_[0].lock(FILE_LOCK_SHARED, Duration::seconds(10))) {
+          files_[0]->unlock();
+          if (!files_[0]->lock(FILE_LOCK_SHARED, Duration::seconds(10))) {
             GRNXX_ERROR() << "failed to lock file: path = " << path
                           << ", full_path = " << path_
                           << ", flags = " << flags;
             GRNXX_THROW();
           }
         } else {
-          files_[0].unlock();
+          files_[0]->unlock();
         }
       }
     }
@@ -340,13 +340,13 @@ void PoolImpl::open_regular_pool(PoolFlags flags, const char *path,
     if ((flags & POOL_OPEN) || (~flags & POOL_CREATE)) {
       const Time start_time = Time::now();
       while ((Time::now() - start_time) < Duration::seconds(10)) {
-        if (files_[0].size() != 0) {
+        if (files_[0]->size() != 0) {
           break;
         }
         Thread::sleep(Duration::milliseconds(10));
       }
     }
-    if (files_[0].lock(FILE_LOCK_SHARED, Duration::seconds(10))) {
+    if (files_[0]->lock(FILE_LOCK_SHARED, Duration::seconds(10))) {
       check_header();
     }
   }
@@ -357,13 +357,13 @@ void PoolImpl::open_regular_pool(PoolFlags flags, const char *path,
     GRNXX_THROW();
   }
 
-  files_[0].set_unlink_at_close(false);
+  files_[0]->set_unlink_at_close(false);
 }
 
 void PoolImpl::setup_header(const PoolOptions &options) {
   if (files_[0]) {
-    files_[0].resize(POOL_HEADER_CHUNK_SIZE);
-    header_chunk_ = View::open(get_view_flags(), files_[0],
+    files_[0]->resize(POOL_HEADER_CHUNK_SIZE);
+    header_chunk_ = View::open(get_view_flags(), files_[0].get(),
                                0, POOL_HEADER_CHUNK_SIZE);
   } else {
     header_chunk_ = View::open(get_view_flags(), POOL_HEADER_CHUNK_SIZE);
@@ -374,7 +374,7 @@ void PoolImpl::setup_header(const PoolOptions &options) {
 }
 
 void PoolImpl::check_header() {
-  header_chunk_ = View::open(get_view_flags(), files_[0],
+  header_chunk_ = View::open(get_view_flags(), files_[0].get(),
                              0, POOL_HEADER_CHUNK_SIZE);
   header_ = static_cast<PoolHeader *>(header_chunk_.address());
 
@@ -425,7 +425,7 @@ View *PoolImpl::mmap_chunk(const ChunkInfo &chunk_info) {
   if (flags_ & POOL_ANONYMOUS) {
     return View::open(get_view_flags(), chunk_info.size());
   } else {
-    File &file = files_[chunk_info.file_id()];
+    std::unique_ptr<File> &file = files_[chunk_info.file_id()];
     if (!file) {
       FileFlags file_flags = FILE_CREATE_OR_OPEN;
       if (flags_ & POOL_TEMPORARY) {
@@ -434,22 +434,22 @@ View *PoolImpl::mmap_chunk(const ChunkInfo &chunk_info) {
         file_flags = FILE_READ_ONLY;
       }
       const String &path = generate_path(chunk_info.file_id());
-      file.open(file_flags, path.c_str());
+      file.reset(File::open(file_flags, path.c_str()));
     }
 
     const uint64_t min_file_size = chunk_info.offset() + chunk_info.size();
-    if (file.size() < min_file_size) {
+    if (file->size() < min_file_size) {
       Lock lock(mutable_inter_process_file_mutex());
       if (!lock) {
         GRNXX_ERROR() << "failed to lock files";
         GRNXX_THROW();
       }
-      if (file.size() < min_file_size) {
-        file.resize(min_file_size);
+      if (file->size() < min_file_size) {
+        file->resize(min_file_size);
       }
     }
 
-    return View::open(get_view_flags(), file,
+    return View::open(get_view_flags(), file.get(),
                       chunk_info.offset(), chunk_info.size());
   }
 }

  Modified: lib/io/pool-impl.hpp (+1 -1)
===================================================================
--- lib/io/pool-impl.hpp    2013-02-22 14:49:57 +0900 (a70d3d9)
+++ lib/io/pool-impl.hpp    2013-02-22 16:57:36 +0900 (3aef73f)
@@ -81,7 +81,7 @@ class PoolImpl {
   String path_;
   PoolFlags flags_;
   PoolHeader *header_;
-  File files_[POOL_MAX_NUM_FILES];
+  std::unique_ptr<File> files_[POOL_MAX_NUM_FILES];
   Chunk header_chunk_;
   Chunk block_chunks_[POOL_MAX_NUM_BLOCK_CHUNKS];
   Chunk block_info_chunks_[POOL_MAX_NUM_BLOCK_INFO_CHUNKS];

  Modified: lib/io/view-posix.cpp (+9 -9)
===================================================================
--- lib/io/view-posix.cpp    2013-02-22 14:49:57 +0900 (a90bd47)
+++ lib/io/view-posix.cpp    2013-02-22 16:57:36 +0900 (05f7c56)
@@ -55,17 +55,17 @@ ViewImpl *ViewImpl::open(ViewFlags flags, uint64_t size) {
   return view.release();
 }
 
-ViewImpl *ViewImpl::open(ViewFlags flags, const File &file) {
+ViewImpl *ViewImpl::open(ViewFlags flags, File *file) {
   std::unique_ptr<ViewImpl> view(new (std::nothrow) ViewImpl);
   if (!view) {
     GRNXX_ERROR() << "new grnxx::io::ViewImpl failed";
     GRNXX_THROW();
   }
-  view->open_view(flags, file, 0, file.size());
+  view->open_view(flags, file, 0, file->size());
   return view.release();
 }
 
-ViewImpl *ViewImpl::open(ViewFlags flags, const File &file,
+ViewImpl *ViewImpl::open(ViewFlags flags, File *file,
                          uint64_t offset, uint64_t size) {
   std::unique_ptr<ViewImpl> view(new (std::nothrow) ViewImpl);
   if (!view) {
@@ -135,7 +135,7 @@ void ViewImpl::open_view(ViewFlags, uint64_t size) {
   }
 }
 
-void ViewImpl::open_view(ViewFlags flags, const File &file,
+void ViewImpl::open_view(ViewFlags flags, File *file,
                          uint64_t offset, uint64_t size) {
   if ((size == 0) || (size > std::numeric_limits<size_t>::max())) {
     GRNXX_ERROR() << "invalid argument: size = " << size << ": (0, "
@@ -151,11 +151,11 @@ void ViewImpl::open_view(ViewFlags flags, const File &file,
   size_ = size;
 
   int protection_flags = PROT_READ | PROT_WRITE;
-  if ((file.flags() & FILE_READ_ONLY) ||
-      ((~file.flags() & FILE_WRITE_ONLY) && (flags & VIEW_READ_ONLY))) {
+  if ((file->flags() & FILE_READ_ONLY) ||
+      ((~file->flags() & FILE_WRITE_ONLY) && (flags & VIEW_READ_ONLY))) {
     flags_ |= VIEW_READ_ONLY;
     protection_flags = PROT_READ;
-  } else if ((file.flags() & FILE_WRITE_ONLY) ||
+  } else if ((file->flags() & FILE_WRITE_ONLY) ||
              (flags & VIEW_WRITE_ONLY)) {
     flags_ |= VIEW_WRITE_ONLY;
     protection_flags = PROT_WRITE;
@@ -171,9 +171,9 @@ void ViewImpl::open_view(ViewFlags flags, const File &file,
   }
 
   address_ = ::mmap(nullptr, size, protection_flags, map_flags,
-                    *static_cast<const int *>(file.handle()), offset);
+                    *static_cast<const int *>(file->handle()), offset);
   if (address_ == MAP_FAILED) {
-    GRNXX_ERROR() << "failed to map view: file = " << file
+    GRNXX_ERROR() << "failed to map view: file = " << *file
                   << ", flags = " << flags << ", offset = " << offset
                   << ", size = " << size << ": '::mmap' " << Error(errno);
     GRNXX_THROW();

  Modified: lib/io/view-posix.hpp (+3 -3)
===================================================================
--- lib/io/view-posix.hpp    2013-02-22 14:49:57 +0900 (0de0a82)
+++ lib/io/view-posix.hpp    2013-02-22 16:57:36 +0900 (1f2bc87)
@@ -30,8 +30,8 @@ class ViewImpl : public View {
   ~ViewImpl();
 
   static ViewImpl *open(ViewFlags flags, uint64_t size);
-  static ViewImpl *open(ViewFlags flags, const File &file);
-  static ViewImpl *open(ViewFlags flags, const File &file,
+  static ViewImpl *open(ViewFlags flags, File *file);
+  static ViewImpl *open(ViewFlags flags, File *file,
                         uint64_t offset, uint64_t size);
 
   void sync();
@@ -57,7 +57,7 @@ class ViewImpl : public View {
   ViewImpl();
 
   void open_view(ViewFlags flags, uint64_t size);
-  void open_view(ViewFlags flags, const File &file,
+  void open_view(ViewFlags flags, File *file,
                  uint64_t offset, uint64_t size);
 };
 

  Modified: lib/io/view-windows.cpp (+12 -12)
===================================================================
--- lib/io/view-windows.cpp    2013-02-22 14:49:57 +0900 (c312fd3)
+++ lib/io/view-windows.cpp    2013-02-22 16:57:36 +0900 (828d5f2)
@@ -58,7 +58,7 @@ ViewImpl *ViewImpl::open(ViewFlags flags, uint64_t size) {
   return view.release();
 }
 
-ViewImpl *ViewImpl::open(ViewFlags flags, const File &file) {
+ViewImpl *ViewImpl::open(ViewFlags flags, File *file) {
   std::unique_ptr<ViewImpl> view(new (std::nothrow) ViewImpl);
   if (!view) {
     GRNXX_ERROR() << "new grnxx::io::ViewImpl failed";
@@ -68,7 +68,7 @@ ViewImpl *ViewImpl::open(ViewFlags flags, const File &file) {
   return view.release();
 }
 
-ViewImpl *ViewImpl::open(ViewFlags flags, const File &file,
+ViewImpl *ViewImpl::open(ViewFlags flags, File *file,
                          uint64_t offset, uint64_t size) {
   if (size == 0) {
     GRNXX_ERROR() << "invalid argument: size = " << size;
@@ -135,11 +135,11 @@ void ViewImpl::open_view(ViewFlags, uint64_t size) {
   }
 }
 
-void ViewImpl::open_view(ViewFlags flags, const File &file,
+void ViewImpl::open_view(ViewFlags flags, File *file,
                            uint64_t offset, uint64_t size) {
-  const uint64_t file_size = file.size();
+  const uint64_t file_size = file->size();
   if (file_size == 0) {
-    GRNXX_ERROR() << "invalid argument: file = " << file;
+    GRNXX_ERROR() << "invalid argument: file = " << *file;
     GRNXX_THROW();
   }
   if (flags & (VIEW_ANONYMOUS | VIEW_HUGE_TLB)) {
@@ -161,14 +161,14 @@ void ViewImpl::open_view(ViewFlags flags, const File &file,
 
   int protection_mode = PAGE_READWRITE;
   DWORD desired_access = FILE_MAP_WRITE;
-  if ((file.flags() & FILE_READ_ONLY) ||
-      ((~file.flags() & FILE_WRITE_ONLY) && (flags & VIEW_READ_ONLY))) {
+  if ((file->flags() & FILE_READ_ONLY) ||
+      ((~file->flags() & FILE_WRITE_ONLY) && (flags & VIEW_READ_ONLY))) {
     flags_ |= VIEW_READ_ONLY;
     protection_mode = PAGE_READONLY;
     desired_access = FILE_MAP_READ;
-  } else if (file.flags() & FILE_WRITE_ONLY) {
+  } else if (file->flags() & FILE_WRITE_ONLY) {
     // Write-only memory mapping is not supported on Windows.
-    GRNXX_ERROR() << "mapping file is write-only: file = " << file;
+    GRNXX_ERROR() << "mapping file is write-only: file = " << *file;
     GRNXX_THROW();
   } else {
     // VIEW_WRITE_ONLY is ignored because write-only memory mapping is not
@@ -188,11 +188,11 @@ void ViewImpl::open_view(ViewFlags flags, const File &file,
 
   const DWORD size_high = static_cast<DWORD>((offset + size) >> 32);
   const DWORD size_low = static_cast<DWORD>((offset + size) & 0xFFFFFFFFU);
-  handle_ = ::CreateFileMapping(*static_cast<const HANDLE *>(file.handle()),
+  handle_ = ::CreateFileMapping(*static_cast<const HANDLE *>(file->handle()),
                                 nullptr, protection_mode, size_high, size_low,
                                 nullptr);
   if (!handle_) {
-    GRNXX_ERROR() << "failed to create file mapping: file = " << file
+    GRNXX_ERROR() << "failed to create file mapping: file = " << *file
                   << ", flags = " << flags << ", offset = " << offset
                   << ", size = " << size
                   << ": '::CreateFileMapping' " << Error(::GetLastError());
@@ -204,7 +204,7 @@ void ViewImpl::open_view(ViewFlags flags, const File &file,
   address_ = ::MapViewOfFile(handle_, desired_access, offset_high, offset_low,
                              static_cast<SIZE_T>(size));
   if (!address_) {
-    GRNXX_ERROR() << "failed to map view: file = " << file
+    GRNXX_ERROR() << "failed to map view: file = " << *file
                   << ", flags = " << flags << ", offset = " << offset
                   << ", size = " << size
                   << ": '::MapViewOfFile' " << Error(::GetLastError());

  Modified: lib/io/view-windows.hpp (+3 -3)
===================================================================
--- lib/io/view-windows.hpp    2013-02-22 14:49:57 +0900 (293220a)
+++ lib/io/view-windows.hpp    2013-02-22 16:57:36 +0900 (e530f4b)
@@ -39,8 +39,8 @@ class ViewImpl : public View {
   ~ViewImpl();
 
   static ViewImpl *open(ViewFlags flags, uint64_t size);
-  static ViewImpl *open(ViewFlags flags, const File &file);
-  static ViewImpl *open(ViewFlags flags, const File &file,
+  static ViewImpl *open(ViewFlags flags, File *file);
+  static ViewImpl *open(ViewFlags flags, File *file,
                         uint64_t offset, uint64_t size);
 
   void sync();
@@ -67,7 +67,7 @@ class ViewImpl : public View {
   ViewImpl();
 
   void open_view(ViewFlags flags, uint64_t size);
-  void open_view(ViewFlags flags, const File &file,
+  void open_view(ViewFlags flags, File *file,
                  uint64_t offset, uint64_t size);
 };
 

  Modified: lib/io/view.cpp (+2 -2)
===================================================================
--- lib/io/view.cpp    2013-02-22 14:49:57 +0900 (85abad0)
+++ lib/io/view.cpp    2013-02-22 16:57:36 +0900 (91f47b1)
@@ -66,11 +66,11 @@ View *View::open(ViewFlags flags, uint64_t size) {
   return ViewImpl::open(flags, size);
 }
 
-View *View::open(ViewFlags flags, const File &file) {
+View *View::open(ViewFlags flags, File *file) {
   return ViewImpl::open(flags, file);
 }
 
-View *View::open(ViewFlags flags, const File &file,
+View *View::open(ViewFlags flags, File *file,
                  uint64_t offset, uint64_t size) {
   return ViewImpl::open(flags, file, offset, size);
 }

  Modified: lib/io/view.hpp (+2 -2)
===================================================================
--- lib/io/view.hpp    2013-02-22 14:49:57 +0900 (636b844)
+++ lib/io/view.hpp    2013-02-22 16:57:36 +0900 (4db217c)
@@ -68,8 +68,8 @@ class View {
   // Create a file-backed memory mapping.
   // Available flags are as follows:
   //  VIEW_READ_ONLY, VIEW_WRITE_ONLY, VIEW_SHARED, VIEW_PRIVATE.
-  static View *open(ViewFlags flags, const File &file);
-  static View *open(ViewFlags flags, const File &file,
+  static View *open(ViewFlags flags, File *file);
+  static View *open(ViewFlags flags, File *file,
                     uint64_t offset, uint64_t size);
 
   virtual void sync() = 0;

  Modified: test/test_io_file.cpp (+95 -85)
===================================================================
--- test/test_io_file.cpp    2013-02-22 14:49:57 +0900 (2338be9)
+++ test/test_io_file.cpp    2013-02-22 16:57:36 +0900 (59dab38)
@@ -28,13 +28,14 @@ void test_create() {
   assert(!grnxx::io::File::exists(FILE_PATH));
   assert(!grnxx::io::File::unlink_if_exists(FILE_PATH));
 
-  grnxx::io::File file(grnxx::io::FILE_CREATE, FILE_PATH);
+  std::unique_ptr<grnxx::io::File> file(
+      grnxx::io::File::open(grnxx::io::FILE_CREATE, FILE_PATH));
 
-  assert(file.path() == FILE_PATH);
-  assert(file.tell() == 0);
-  assert(file.size() == 0);
+  assert(file->path() == FILE_PATH);
+  assert(file->tell() == 0);
+  assert(file->size() == 0);
 
-  file.close();
+  file.reset();
 
   assert(grnxx::io::File::exists(FILE_PATH));
   grnxx::io::File::unlink(FILE_PATH);
@@ -47,11 +48,13 @@ void test_open() {
   const char FILE_PATH[] = "temp.grn";
 
   grnxx::io::File::unlink_if_exists(FILE_PATH);
-  grnxx::io::File(grnxx::io::FILE_CREATE, FILE_PATH);
+  std::unique_ptr<grnxx::io::File> file(
+      grnxx::io::File::open(grnxx::io::FILE_CREATE, FILE_PATH));
+  file.reset();
 
-  grnxx::io::File file(grnxx::io::FILE_OPEN, FILE_PATH);
+  file.reset(grnxx::io::File::open(grnxx::io::FILE_OPEN, FILE_PATH));
+  file.reset();
 
-  file.close();
   grnxx::io::File::unlink(FILE_PATH);
 }
 
@@ -60,12 +63,13 @@ void test_create_or_open() {
 
   grnxx::io::File::unlink_if_exists(FILE_PATH);
 
-  grnxx::io::File file(grnxx::io::FILE_CREATE_OR_OPEN, FILE_PATH);
+  std::unique_ptr<grnxx::io::File> file(
+      grnxx::io::File::open(grnxx::io::FILE_CREATE_OR_OPEN, FILE_PATH));
+  file.reset();
 
-  file.close();
-  file.open(grnxx::io::FILE_CREATE_OR_OPEN, FILE_PATH);
+  file.reset(grnxx::io::File::open(grnxx::io::FILE_CREATE_OR_OPEN, FILE_PATH));
+  file.reset();
 
-  file.close();
   grnxx::io::File::unlink(FILE_PATH);
 }
 
@@ -73,13 +77,14 @@ void test_write() {
   const char FILE_PATH[] = "temp.grn";
 
   grnxx::io::File::unlink_if_exists(FILE_PATH);
-  grnxx::io::File file(grnxx::io::FILE_CREATE, FILE_PATH);
+  std::unique_ptr<grnxx::io::File> file(
+      grnxx::io::File::open(grnxx::io::FILE_CREATE, FILE_PATH));
 
-  assert(file.write("0123456789", 10) == 10);
-  assert(file.tell() == 10);
-  assert(file.size() == 10);
+  assert(file->write("0123456789", 10) == 10);
+  assert(file->tell() == 10);
+  assert(file->size() == 10);
 
-  file.close();
+  file.reset();
   grnxx::io::File::unlink(FILE_PATH);
 }
 
@@ -88,17 +93,18 @@ void test_resize() {
   const std::uint64_t FILE_SIZE = 1 << 20;
 
   grnxx::io::File::unlink_if_exists(FILE_PATH);
-  grnxx::io::File file(grnxx::io::FILE_CREATE, FILE_PATH);
+  std::unique_ptr<grnxx::io::File> file(
+      grnxx::io::File::open(grnxx::io::FILE_CREATE, FILE_PATH));
 
-  file.resize(FILE_SIZE);
-  assert(file.tell() == FILE_SIZE);
-  assert(file.size() == FILE_SIZE);
+  file->resize(FILE_SIZE);
+  assert(file->tell() == FILE_SIZE);
+  assert(file->size() == FILE_SIZE);
 
-  file.resize(0);
-  assert(file.tell() == 0);
-  assert(file.size() == 0);
+  file->resize(0);
+  assert(file->tell() == 0);
+  assert(file->size() == 0);
 
-  file.close();
+  file.reset();
   grnxx::io::File::unlink(FILE_PATH);
 }
 
@@ -107,24 +113,25 @@ void test_seek() {
   const std::uint64_t FILE_SIZE = 1 << 20;
 
   grnxx::io::File::unlink_if_exists(FILE_PATH);
-  grnxx::io::File file(grnxx::io::FILE_CREATE, FILE_PATH);
+  std::unique_ptr<grnxx::io::File> file(
+      grnxx::io::File::open(grnxx::io::FILE_CREATE, FILE_PATH));
 
-  file.resize(FILE_SIZE);
+  file->resize(FILE_SIZE);
 
-  assert(file.seek(0) == 0);
-  assert(file.tell() == 0);
+  assert(file->seek(0) == 0);
+  assert(file->tell() == 0);
 
-  assert(file.seek(FILE_SIZE / 2) == (FILE_SIZE / 2));
-  assert(file.tell() == (FILE_SIZE / 2));
+  assert(file->seek(FILE_SIZE / 2) == (FILE_SIZE / 2));
+  assert(file->tell() == (FILE_SIZE / 2));
 
-  assert(file.seek(FILE_SIZE / 4, SEEK_CUR) ==
+  assert(file->seek(FILE_SIZE / 4, SEEK_CUR) ==
          ((FILE_SIZE / 2) + (FILE_SIZE / 4)));
-  assert(file.tell() == ((FILE_SIZE / 2) + (FILE_SIZE / 4)));
+  assert(file->tell() == ((FILE_SIZE / 2) + (FILE_SIZE / 4)));
 
-  assert(file.seek(-(FILE_SIZE / 2), SEEK_END) == (FILE_SIZE / 2));
-  assert(file.tell() == (FILE_SIZE / 2));
+  assert(file->seek(-(FILE_SIZE / 2), SEEK_END) == (FILE_SIZE / 2));
+  assert(file->tell() == (FILE_SIZE / 2));
 
-  file.close();
+  file.reset();
   grnxx::io::File::unlink(FILE_PATH);
 }
 
@@ -132,56 +139,57 @@ void test_read() {
   const char FILE_PATH[] = "temp.grn";
 
   grnxx::io::File::unlink_if_exists(FILE_PATH);
-  grnxx::io::File file(grnxx::io::FILE_CREATE, FILE_PATH);
+  std::unique_ptr<grnxx::io::File> file(
+      grnxx::io::File::open(grnxx::io::FILE_CREATE, FILE_PATH));
 
-  file.write("0123456789", 10);
-  file.seek(0);
+  file->write("0123456789", 10);
+  file->seek(0);
 
   char buf[256];
-  assert(file.read(buf, sizeof(buf)) == 10);
+  assert(file->read(buf, sizeof(buf)) == 10);
   assert(std::memcmp(buf, "0123456789", 10) == 0);
-  assert(file.tell() == 10);
+  assert(file->tell() == 10);
 
-  file.seek(3);
+  file->seek(3);
 
-  assert(file.read(buf, 5) == 5);
-  assert(file.tell() == 8);
+  assert(file->read(buf, 5) == 5);
+  assert(file->tell() == 8);
   assert(std::memcmp(buf, "34567", 5) == 0);
 
-  file.close();
+  file.reset();
   grnxx::io::File::unlink(FILE_PATH);
 }
 
 void test_temporary() {
   const char FILE_PATH[] = "temp.grn";
 
-  grnxx::io::File file(grnxx::io::FILE_TEMPORARY, FILE_PATH);
+  std::unique_ptr<grnxx::io::File> file(
+      grnxx::io::File::open(grnxx::io::FILE_TEMPORARY, FILE_PATH));
 
-  assert(file.write("0123456789", 10) == 10);
-  assert(file.seek(0) == 0);
+  assert(file->write("0123456789", 10) == 10);
+  assert(file->seek(0) == 0);
 
   char buf[256];
-  assert(file.read(buf, sizeof(buf)) == 10);
+  assert(file->read(buf, sizeof(buf)) == 10);
   assert(std::memcmp(buf, "0123456789", 10) == 0);
 
-  grnxx::String path = file.path();
-
-  file.close();
+  grnxx::String path = file->path();
 
+  file.reset();
   assert(!grnxx::io::File::exists(path.c_str()));
 }
 
 void test_unlink_at_close() {
   const char FILE_PATH[] = "temp.grn";
 
-  grnxx::io::File file(grnxx::io::FILE_CREATE, FILE_PATH);
-
-  file.set_unlink_at_close(true);
+  std::unique_ptr<grnxx::io::File> file(
+      grnxx::io::File::open(grnxx::io::FILE_CREATE, FILE_PATH));
 
-  assert(file.unlink_at_close());
+  file->set_unlink_at_close(true);
 
-  file.close();
+  assert(file->unlink_at_close());
 
+  file.reset();
   assert(!grnxx::io::File::exists(FILE_PATH));
 }
 
@@ -189,34 +197,36 @@ void test_lock() {
   const char FILE_PATH[] = "temp.grn";
 
   grnxx::io::File::unlink_if_exists(FILE_PATH);
-  grnxx::io::File file_1(grnxx::io::FILE_CREATE, FILE_PATH);
-
-  assert(!file_1.unlock());
-  assert(file_1.try_lock(grnxx::io::FILE_LOCK_EXCLUSIVE));
-  assert(!file_1.try_lock(grnxx::io::FILE_LOCK_SHARED));
-  assert(file_1.unlock());
-
-  assert(file_1.try_lock(grnxx::io::FILE_LOCK_SHARED));
-  assert(file_1.unlock());
-  assert(!file_1.unlock());
-
-  grnxx::io::File file_2(grnxx::io::FILE_OPEN, FILE_PATH);
-
-  assert(file_1.try_lock(grnxx::io::FILE_LOCK_EXCLUSIVE));
-  assert(!file_2.try_lock(grnxx::io::FILE_LOCK_SHARED));
-  assert(!file_2.try_lock(grnxx::io::FILE_LOCK_EXCLUSIVE));
-  assert(!file_2.unlock());
-  assert(file_1.unlock());
-
-  assert(file_1.try_lock(grnxx::io::FILE_LOCK_SHARED));
-  assert(!file_2.try_lock(grnxx::io::FILE_LOCK_EXCLUSIVE));
-  assert(file_2.try_lock(grnxx::io::FILE_LOCK_SHARED));
-  assert(file_1.unlock());
-  assert(!file_1.try_lock(grnxx::io::FILE_LOCK_EXCLUSIVE));
-  assert(file_2.unlock());
-
-  file_1 = grnxx::io::File();
-  file_2 = grnxx::io::File();
+  std::unique_ptr<grnxx::io::File> file_1(
+      grnxx::io::File::open(grnxx::io::FILE_CREATE, FILE_PATH));
+
+  assert(!file_1->unlock());
+  assert(file_1->try_lock(grnxx::io::FILE_LOCK_EXCLUSIVE));
+  assert(!file_1->try_lock(grnxx::io::FILE_LOCK_SHARED));
+  assert(file_1->unlock());
+
+  assert(file_1->try_lock(grnxx::io::FILE_LOCK_SHARED));
+  assert(file_1->unlock());
+  assert(!file_1->unlock());
+
+  std::unique_ptr<grnxx::io::File> file_2(
+      grnxx::io::File::open(grnxx::io::FILE_OPEN, FILE_PATH));
+
+  assert(file_1->try_lock(grnxx::io::FILE_LOCK_EXCLUSIVE));
+  assert(!file_2->try_lock(grnxx::io::FILE_LOCK_SHARED));
+  assert(!file_2->try_lock(grnxx::io::FILE_LOCK_EXCLUSIVE));
+  assert(!file_2->unlock());
+  assert(file_1->unlock());
+
+  assert(file_1->try_lock(grnxx::io::FILE_LOCK_SHARED));
+  assert(!file_2->try_lock(grnxx::io::FILE_LOCK_EXCLUSIVE));
+  assert(file_2->try_lock(grnxx::io::FILE_LOCK_SHARED));
+  assert(file_1->unlock());
+  assert(!file_1->try_lock(grnxx::io::FILE_LOCK_EXCLUSIVE));
+  assert(file_2->unlock());
+
+  file_1.reset();
+  file_2.reset();
   grnxx::io::File::unlink(FILE_PATH);
 }
 

  Modified: test/test_io_file_info.cpp (+5 -4)
===================================================================
--- test/test_io_file_info.cpp    2013-02-22 14:49:57 +0900 (6a93723)
+++ test/test_io_file_info.cpp    2013-02-22 16:57:36 +0900 (471e084)
@@ -36,8 +36,9 @@ void test_existent_file() {
   const std::uint64_t FILE_SIZE = 12345;
 
   grnxx::io::File::unlink_if_exists(FILE_PATH);
-  grnxx::io::File file(grnxx::io::FILE_CREATE, FILE_PATH);
-  file.resize(FILE_SIZE);
+  std::unique_ptr<grnxx::io::File> file(
+      grnxx::io::File::open(grnxx::io::FILE_CREATE, FILE_PATH));
+  file->resize(FILE_SIZE);
 
   std::unique_ptr<grnxx::io::FileInfo> file_info(
       grnxx::io::FileInfo::stat(FILE_PATH));
@@ -49,12 +50,12 @@ void test_existent_file() {
   assert(!file_info->is_directory());
   assert(file_info->size() == FILE_SIZE);
 
-  file_info.reset(grnxx::io::FileInfo::stat(file));
+  file_info.reset(grnxx::io::FileInfo::stat(file.get()));
   assert(file_info);
 
   GRNXX_NOTICE() << "file_info (regular) = " << *file_info;
 
-  file.close();
+  file.reset();
   grnxx::io::File::unlink(FILE_PATH);
 }
 

  Modified: test/test_io_view.cpp (+7 -6)
===================================================================
--- test/test_io_view.cpp    2013-02-22 14:49:57 +0900 (b7cd474)
+++ test/test_io_view.cpp    2013-02-22 16:57:36 +0900 (7241b90)
@@ -47,13 +47,14 @@ void test_file_backed_mmap() {
   const std::uint64_t MMAP_SIZE = 1 << 20;
 
   // Create a file of "FILE_SIZE" bytes.
-  grnxx::io::File file(grnxx::io::FILE_TEMPORARY, FILE_PATH);
-  file.resize(FILE_SIZE);
-  assert(file.size() == FILE_SIZE);
+  std::unique_ptr<grnxx::io::File> file(
+      grnxx::io::File::open(grnxx::io::FILE_TEMPORARY, FILE_PATH));
+  file->resize(FILE_SIZE);
+  assert(file->size() == FILE_SIZE);
 
   // Create a memory mapping on "file".
   std::unique_ptr<grnxx::io::View> view(
-      grnxx::io::View::open(grnxx::io::VIEW_SHARED, file));
+      grnxx::io::View::open(grnxx::io::VIEW_SHARED, file.get()));
   assert(view);
 
   GRNXX_NOTICE() << "view = " << *view;
@@ -66,7 +67,7 @@ void test_file_backed_mmap() {
 
   // Recreate a memory mapping on "file".
   view.reset();
-  view.reset(grnxx::io::View::open(grnxx::io::VIEW_PRIVATE, file));
+  view.reset(grnxx::io::View::open(grnxx::io::VIEW_PRIVATE, file.get()));
   assert(view);
 
   GRNXX_NOTICE() << "view = " << *view;
@@ -84,7 +85,7 @@ void test_file_backed_mmap() {
   view.reset();
   view.reset(grnxx::io::View::open(grnxx::io::VIEW_SHARED |
                                    grnxx::io::VIEW_PRIVATE,
-                                   file, FILE_SIZE / 2, MMAP_SIZE));
+                                   file.get(), FILE_SIZE / 2, MMAP_SIZE));
   assert(view);
 
   GRNXX_NOTICE() << "view = " << *view;
-------------- next part --------------
HTML����������������������������...
다운로드 



More information about the Groonga-commit mailing list
Back to archive index