Browse Source

Implemented fast file allocation in MinGW32 build.

We use SetFilePointerEx and SetEndOfFile to allocate extents.  This
only works with NTFS. To enable this feature, --file-allocation=falloc
must be given.
Tatsuhiro Tsujikawa 14 years ago
parent
commit
e958f5dab3
2 changed files with 23 additions and 3 deletions
  1. 5 2
      configure.ac
  2. 18 1
      src/AbstractDiskWriter.cc

+ 5 - 2
configure.ac

@@ -12,6 +12,7 @@ AC_CONFIG_HEADERS([config.h])
 
 case "$target" in
   *mingw*|*cygwin*)
+    win_build=yes
     LIBS="-lws2_32 -lcrypto -lwsock32 -lgdi32 -lwinmm $LIBS"
     ;;
 esac
@@ -381,12 +382,14 @@ AM_CONDITIONAL([HAVE_EPOLL], [test "x$have_epoll" = "xyes"])
 AC_CHECK_FUNCS([posix_fallocate],[have_posix_fallocate=yes])
 ARIA2_CHECK_FALLOCATE
 if test "x$have_posix_fallocate" = "xyes" ||
-   test "x$have_fallocate" = "xyes"; then
+   test "x$have_fallocate" = "xyes" ||
+   test "x$win_build" = "xyes"; then
   AC_DEFINE([HAVE_SOME_FALLOCATE], [1],
             [Define to 1 if *_fallocate is available.])
 fi
 AM_CONDITIONAL([HAVE_SOME_FALLOCATE],
-  [test "x$have_posix_fallocate" = "xyes" || test "x$have_fallocate" = "xyes"])
+  [test "x$have_posix_fallocate" = "xyes" || test "x$have_fallocate" = "xyes" \
+  || test "x$win_build" = "xyes"])
 
 
 AC_CHECK_FUNCS([asctime_r],

+ 18 - 1
src/AbstractDiskWriter.cc

@@ -233,7 +233,24 @@ void AbstractDiskWriter::allocate(off_t offset, uint64_t length)
   if(fd_ == -1) {
     throw DL_ABORT_EX("File not yet opened.");
   }
-# ifdef HAVE_FALLOCATE
+# ifdef __MINGW32__
+  LARGE_INTEGER fileLength;
+  fileLength.QuadPart = offset+length;
+  HANDLE handle = LongToHandle(_get_osfhandle(fd_));
+  int r;
+  r = SetFilePointerEx(handle, fileLength, 0, FILE_BEGIN);
+  if(r == 0) {
+    throw DL_ABORT_EX2(fmt("SetFilePointerEx failed. cause: %lx",
+                           GetLastError()),
+                       error_code::FILE_IO_ERROR);
+  }
+  r = SetEndOfFile(handle);
+  if(r == 0) {
+    throw DL_ABORT_EX2(fmt("SetEndOfFile failed. cause: %lx",
+                           GetLastError()),
+                       error_code::FILE_IO_ERROR);
+  }
+# elif HAVE_FALLOCATE
   // For linux, we use fallocate to detect file system supports
   // fallocate or not.
   int r;