From 31abf85846f4dd1f067ec1c9b1a577821f1709b6 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Sun, 14 Feb 2010 01:20:20 +0000 Subject: [PATCH] * Added support for Linux's fallocate and Darwin's fcntl(...,F_PREALLOCATE,...) to preallocate files by default. The 'system.file_allocate' setting will now only be used to indicate you want posix_fallocate called, which may block while it zeros out the file manually. * Added 'event.download.hash_failed' and 'event.download.hash_final_failed'. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1130 e378c898-3ddf-0310-93e7-cc216c733640 --- scripts/checks.m4 | 80 ++++++++++++++++++++++++++++++++++++++- src/command_network.cc | 2 +- src/core/download_list.cc | 4 +- src/main.cc | 10 +++-- 4 files changed, 88 insertions(+), 8 deletions(-) diff --git a/scripts/checks.m4 b/scripts/checks.m4 index d4cee1ec..94f78612 100644 --- a/scripts/checks.m4 +++ b/scripts/checks.m4 @@ -61,7 +61,6 @@ AC_DEFUN([TORRENT_CHECK_EPOLL], [ ]) ]) - AC_DEFUN([TORRENT_WITHOUT_EPOLL], [ AC_ARG_WITH(epoll, [ --without-epoll Do not check for epoll support.], @@ -75,12 +74,70 @@ AC_DEFUN([TORRENT_WITHOUT_EPOLL], [ ]) +AC_DEFUN([TORRENT_CHECK_KQUEUE], [ + AC_MSG_CHECKING(for kqueue support) + + AC_LINK_IFELSE( + [[#include /* Because OpenBSD's sys/event.h fails to compile otherwise. Yeah... */ + #include + int main() { + int fd = kqueue(); + return 0; + } + ]], + [ + AC_DEFINE(USE_KQUEUE, 1, Use kqueue.) + AC_MSG_RESULT(yes) + ], [ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([TORRENT_CHECK_KQUEUE_SOCKET_ONLY], [ + AC_MSG_CHECKING(whether kqueue supports pipes and ptys) + + AC_RUN_IFELSE( + [[#include + #include + #include + #include + #include + int main() { + struct kevent ev[2], ev_out[2]; + struct timespec ts = { 0, 0 }; + int pfd[2], pty[2], kfd, n; + char buffer[9001]; + if (pipe(pfd) == -1) return 1; + if (fcntl(pfd[1], F_SETFL, O_NONBLOCK) == -1) return 2; + while ((n = write(pfd[1], buffer, sizeof(buffer))) == sizeof(buffer)); + if ((pty[0]=posix_openpt(O_RDWR | O_NOCTTY)) == -1) return 3; + if ((pty[1]=grantpt(pty[0])) == -1) return 4; + EV_SET(ev+0, pfd[1], EVFILT_WRITE, EV_ADD | EV_ENABLE, 0, 0, NULL); + EV_SET(ev+1, pty[1], EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, NULL); + if ((kfd = kqueue()) == -1) return 5; + if ((n = kevent(kfd, ev, 2, NULL, 0, NULL)) == -1) return 6; + if (ev_out[0].flags & EV_ERROR) return 7; + if (ev_out[1].flags & EV_ERROR) return 8; + read(pfd[0], buffer, sizeof(buffer)); + if ((n = kevent(kfd, NULL, 0, ev_out, 2, &ts)) < 1) return 9; + return 0; + } + ]], + [ + AC_MSG_RESULT(yes) + ], [ + AC_DEFINE(KQUEUE_SOCKET_ONLY, 1, kqueue only supports sockets.) + AC_MSG_RESULT(no) + ]) +]) + AC_DEFUN([TORRENT_WITH_KQUEUE], [ AC_ARG_WITH(kqueue, [ --with-kqueue enable kqueue. [[default=no]]], [ if test "$withval" = "yes"; then - AC_DEFINE(USE_KQUEUE, 1, Enable kqueue.) + TORRENT_CHECK_KQUEUE + TORRENT_CHECK_KQUEUE_SOCKET_ONLY fi ]) ]) @@ -100,6 +157,25 @@ AC_DEFUN([TORRENT_WITHOUT_VARIABLE_FDSET], [ ]) +AC_DEFUN([TORRENT_CHECK_FALLOCATE], [ + AC_MSG_CHECKING(for fallocate) + + AC_COMPILE_IFELSE( + [[#include + int main() { + fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 0); + return 0; + } + ]], + [ + AC_DEFINE(HAVE_FALLOCATE, 1, Linux's fallocate supported.) + AC_MSG_RESULT(yes) + ], [ + AC_MSG_RESULT(no) + ]) +]) + + AC_DEFUN([TORRENT_CHECK_POSIX_FALLOCATE], [ AC_MSG_CHECKING(for posix_fallocate) diff --git a/src/command_network.cc b/src/command_network.cc index 1173bff2..a41d50fa 100644 --- a/src/command_network.cc +++ b/src/command_network.cc @@ -493,5 +493,5 @@ initialize_command_network() { // Not really network stuff: ADD_VARIABLE_BOOL ("handshake_log", false); - ADD_VARIABLE_STRING("log.tracker", ""); + rpc::commands.call("system.method.insert", rpc::create_object_list("log.tracker", "string|const", "")); } diff --git a/src/core/download_list.cc b/src/core/download_list.cc index c2537618..d8f0b2e9 100644 --- a/src/core/download_list.cc +++ b/src/core/download_list.cc @@ -438,7 +438,7 @@ DownloadList::hash_done(Download* download) { if (!download->is_hash_checked()) { download->set_hash_failed(true); - rpc::commands.call_catch("event.download.hash_done", rpc::make_target(download), torrent::Object(), "Download event action failed: "); + rpc::commands.call_catch("event.download.hash_failed", rpc::make_target(download), torrent::Object(), "Download event action failed: "); return; } @@ -484,6 +484,7 @@ DownloadList::hash_done(Download* download) { } else { download->set_message("Hash check on download completion found bad chunks, consider using \"safe_sync\"."); control->core()->push_log("Hash check on download completion found bad chunks, consider using \"safe_sync\"."); + rpc::commands.call_catch("event.download.hash_final_failed", rpc::make_target(download), torrent::Object(), "Download event action failed: "); } break; @@ -505,7 +506,6 @@ DownloadList::hash_queue(Download* download, int type) { if (rpc::call_command_value("d.get_hashing", rpc::make_target(download)) != Download::variable_hashing_stopped) throw torrent::internal_error("DownloadList::hash_queue(...) hashing already queued."); -// close_throw(download); // HACK if (download->is_open()) { pause(download, torrent::Download::stop_skip_tracker); diff --git a/src/main.cc b/src/main.cc index c0f79133..91c9c68c 100644 --- a/src/main.cc +++ b/src/main.cc @@ -207,6 +207,8 @@ main(int argc, char** argv) { "system.method.insert = event.download.finished,multi\n" "system.method.insert = event.download.hash_done,multi\n" + "system.method.insert = event.download.hash_failed,multi\n" + "system.method.insert = event.download.hash_final_failed,multi\n" "system.method.insert = event.download.hash_removed,multi\n" "system.method.insert = event.download.hash_queued,multi\n" @@ -264,20 +266,22 @@ main(int argc, char** argv) { "view_add = complete\n" "view_filter = complete,d.get_complete=\n" - "view_filter_on = complete,event.download.hash_done,event.download.finished\n" + "view_filter_on = complete,event.download.hash_done,event.download.hash_failed,event.download.hash_final_failed,event.download.finished\n" "view_sort_new = complete,less=d.get_state_changed=\n" "view_sort_current = complete,less=d.get_state_changed=\n" "view_add = incomplete\n" "view_filter = incomplete,not=$d.get_complete=\n" - "view_filter_on = incomplete,event.download.hash_done,event.download.finished\n" + "view_filter_on = incomplete,event.download.hash_done,event.download.hash_failed," + "event.download.hash_final_failed,event.download.finished\n" "view_sort_new = incomplete,less=d.get_state_changed=\n" "view_sort_current = incomplete,less=d.get_state_changed=\n" // The hashing view does not include stopped torrents. "view_add = hashing\n" "view_filter = hashing,d.get_hashing=\n" - "view_filter_on = hashing,event.download.hash_queued,event.download.hash_removed,event.download.hash_done\n" + "view_filter_on = hashing,event.download.hash_queued,event.download.hash_removed," + "event.download.hash_done,event.download.hash_failed,event.download.hash_final_failed\n" // "view_sort_new = hashing,less=d.get_state_changed=\n" // "view_sort_current = hashing,less=d.get_state_changed=\n"