diff --git a/configure.ac b/configure.ac
index 2e6a9eb5..1f6f14d6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT(rtorrent, 0.9.3, jaris@ifi.uio.no)
+AC_INIT(rtorrent, 0.9.3, sundell.software@gmail.com)
AC_DEFINE(API_VERSION, 8, api version)
@@ -41,15 +41,11 @@ CFLAGS="$CFLAGS $PTHREAD_CFLAGS $CURSES_CFLAGS"
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS $CURSES_CFLAGS"
LIBS="$PTHREAD_LIBS $CURSES_LIB $LIBS"
-PKG_CHECK_MODULES(sigc, sigc++-2.0,
- CXXFLAGS="$CXXFLAGS $sigc_CFLAGS";
- LIBS="$LIBS $sigc_LIBS")
-
-PKG_CHECK_MODULES(libcurl, libcurl >= 7.15.4,
+PKG_CHECK_MODULES([libcurl], libcurl >= 7.15.4,
CXXFLAGS="$CXXFLAGS $libcurl_CFLAGS";
LIBS="$LIBS $libcurl_LIBS")
-PKG_CHECK_MODULES(libtorrent, libtorrent >= 0.13.3,
+PKG_CHECK_MODULES([libtorrent], libtorrent >= 0.13.3,
CXXFLAGS="$CXXFLAGS $libtorrent_CFLAGS";
LIBS="$LIBS $libtorrent_LIBS")
diff --git a/doc/old/rtorrent.1.xml b/doc/old/rtorrent.1.xml
index 9c455859..e8093896 100644
--- a/doc/old/rtorrent.1.xml
+++ b/doc/old/rtorrent.1.xml
@@ -507,29 +507,6 @@ Enable/disable peer exchange for torrents that aren't marked private. Disabled b
-
- schedule = id ,start ,interval ,command
-
-Call command every interval
-seconds, starting from start . An
-interval of zero calls the task once, while a
-start of zero calls it immediately. Currently
-command is forwarded to the option handler.
-
-start and interval may
-optionally use a time format, dd:hh:mm:ss . F.ex to
-start a task every day at 18:00 , use
-18:00:00,24:00:00 .
-
-
-
-
- schedule_remove = id
-
-Delete id from the scheduler.
-
-
-
start_tied =
@@ -580,40 +557,6 @@ torrent::input_error exception on bad input.
-
- stop_on_ratio = min_ratio
- stop_on_ratio = min_ratio ,min_upload
- stop_on_ratio = min_ratio ,min_upload ,max_ratio
-
-Stop torrents when they reach the given upload ratio
-min_ratio in percent. If the optional
-min_upload is given, require a total
-upload amount of this many bytes as well. If the optional
-max_ratio is given, stop the torrent
-when reaching this ratio regardless of the total upload
-amount. Exclude certain torrent by pressing
-Shift+I in the downlist list.
-Use with the schedule option.
-
-
-
-
- on_insert = id ,command
- on_erase = id ,command
- on_open = id ,command
- on_close = id ,command
- on_start = id ,command
- on_stop = id ,command
- on_hash_queued = id ,command
- on_hash_removed = id ,command
- on_hash_done = id ,command
- on_finished = id ,command
-
-Call a command on a download when its state changes. Only a subset of
-commands are available.
-
-
-
@@ -629,6 +572,8 @@ commands are available.
upload_rate = KB
download_rate = KB
+ set_upload_rate = TODO
+ set_download_rate = TODO
Set the maximum global uploand and download rates.
@@ -653,14 +598,19 @@ Set the minimum nad maximum number of peers to allow while seeding, or
max_uploads = value
+ max_downloads = value
+ min_uploads = value
+ min_downloads = value
-Set the maximum number of simultaneous uploads per download.
+Set the maximum/minimum number of simultaneous uploads/downloads per download/upload.
max_uploads_div = value
max_downloads_div = value
+ set_max_uploads_div = value
+ set_max_downloads_div = value
Change the divider used to calculate the max upload and download slots
to use when the throttle is changed. Disable by
@@ -671,6 +621,8 @@ setting 0 .
max_uploads_global = value
max_downloads_global = value
+ set_max_uploads_global = value
+ set_max_downloads_global = value
Max upload and download slots allowed. Disable by
setting 0 .
@@ -746,6 +698,27 @@ not allow connections to UDP trackers.
+
+ http_capath = path
+ http_cacert = filename
+
+Set the certificates to use in http requests. See Curl's
+CURLOPT_CAPATH and CURLOPT_CAINFO options for further information.
+
+
+
+
+
+
+
+
+ DHT-RELATED SETTINGS
+
+ Settings related to DHT
+
+
+
+
dht = disabled|off|auto|on
@@ -779,11 +752,23 @@ The port is optional, with port 6881 being used by default.
- http_capath = path
- http_cacert = filename
+ dht_statistics = TODO
-Set the certificates to use in http requests. See Curl's
-CURLOPT_CAPATH and CURLOPT_CAINFO options for further information.
+TODO
+
+
+
+
+ set_dht_port = TODO
+
+TODO
+
+
+
+
+ set_dht_throttle = TODO
+
+TODO
@@ -791,7 +776,6 @@ CURLOPT_CAPATH and CURLOPT_CAINFO options for further information.
-
USER-INTERFACE SETTINGS
diff --git a/doc/plot/instrumentation_transfers.sh b/doc/plot/instrumentation_transfers.sh
new file mode 100755
index 00000000..297d8b90
--- /dev/null
+++ b/doc/plot/instrumentation_transfers.sh
@@ -0,0 +1,49 @@
+#/bin/bash
+gnuplot << EOF
+
+set terminal png size 1024,768 enhanced
+set xdata time
+set timefmt "%s"
+set format x "%H:%M"
+set y2tics
+set autoscale xfix
+set key autotitle columnhead
+
+# set datafile missing '0'
+
+set format y "%.0f"
+set format y2 "%.0f"
+
+set yrange [0:]
+set y2range [0:]
+
+set output "output_$1_transfer_requests.png"
+plot \
+ "instrumentation_transfers.log.$1" using 1:2 title 'delegated' with lines lw 4 axis x1y1,\
+ "instrumentation_transfers.log.$1" using 1:3 title 'downloading' with lines lw 4 axis x1y1,\
+ "instrumentation_transfers.log.$1" using 1:4 title 'finished' with lines lw 4 axis x1y1,\
+ "instrumentation_transfers.log.$1" using 1:5 title 'skipped' with lines lw 2 axis x1y2,\
+ "instrumentation_transfers.log.$1" using 1:6 title 'unknown' with lines lw 2 axis x1y2,\
+ "instrumentation_transfers.log.$1" using 1:7 title 'unordered' with lines lw 2 axis x1y2,\
+ "instrumentation_transfers.log.$1" using 1:19 title 'unaccounted' with lines lw 2 axis x1y2
+
+set output "output_$1_transfer_queues.png"
+plot \
+ "instrumentation_transfers.log.$1" using 1:8 title 'queue added' with lines lw 2 axis x1y1,\
+ "instrumentation_transfers.log.$1" using 1:9 title 'queue moved' with lines lw 2 axis x1y1,\
+ "instrumentation_transfers.log.$1" using 1:10 title 'queue removed' with lines lw 2 axis x1y1,\
+ "instrumentation_transfers.log.$1" using 1:11 title 'queue total' with lines lw 4 axis x1y2,\
+ "instrumentation_transfers.log.$1" using 1:12 title 'unordered added' with lines lw 2 axis x1y1,\
+ "instrumentation_transfers.log.$1" using 1:13 title 'unordered moved' with lines lw 2 axis x1y1,\
+ "instrumentation_transfers.log.$1" using 1:14 title 'unordered removed' with lines lw 2 axis x1y1,\
+ "instrumentation_transfers.log.$1" using 1:15 title 'unordered total' with lines lw 4 axis x1y2,\
+ "instrumentation_transfers.log.$1" using 1:16 title 'stalled added' with lines lw 2 axis x1y1,\
+ "instrumentation_transfers.log.$1" using 1:17 title 'stalled moved' with lines lw 2 axis x1y1,\
+ "instrumentation_transfers.log.$1" using 1:18 title 'stalled removed' with lines lw 2 axis x1y1,\
+ "instrumentation_transfers.log.$1" using 1:19 title 'stalled total' with lines lw 4 axis x1y2,\
+ "instrumentation_transfers.log.$1" using 1:20 title 'choked added' with lines lw 2 axis x1y1,\
+ "instrumentation_transfers.log.$1" using 1:21 title 'choked moved' with lines lw 2 axis x1y1,\
+ "instrumentation_transfers.log.$1" using 1:22 title 'choked removed' with lines lw 2 axis x1y1,\
+ "instrumentation_transfers.log.$1" using 1:23 title 'choked total' with lines lw 4 axis x1y2
+
+EOF
diff --git a/doc/plot/mincore.sh b/doc/plot/mincore.sh
new file mode 100755
index 00000000..3dfaa630
--- /dev/null
+++ b/doc/plot/mincore.sh
@@ -0,0 +1,30 @@
+#/bin/bash
+gnuplot << EOF
+
+set terminal png size 1024,768 enhanced
+set xdata time
+set timefmt "%s"
+set format x "%H:%M"
+set y2tics
+set autoscale xfix
+set key autotitle columnhead
+
+set format y "%.0f"
+set format y2 "%.0f"
+
+set output "output_$1_incore_sync.png"
+plot \
+ "instrumentation_mincore.log.$1" using 1:6 title 'success' smooth sbezier with lines lw 4 axis x1y1,\
+ "instrumentation_mincore.log.$1" using 1:7 title 'failed' smooth sbezier with lines lw 4 axis x1y1,\
+ "instrumentation_mincore.log.$1" using 1:8 title 'not synced' smooth sbezier with lines lw 4 axis x1y2,\
+ "instrumentation_mincore.log.$1" using 1:9 title 'not deallocated' smooth sbezier with lines lw 4 axis x1y2
+
+set format y "%.0g"
+
+set output "output_$1_incore_alloc.png"
+plot \
+ "instrumentation_mincore.log.$1" using 1:12 title 'allocations' smooth sbezier with lines lw 2 axis x1y1,\
+ "instrumentation_mincore.log.$1" using 1:13 title 'deallocations' smooth sbezier with lines lw 4 axis x1y1,\
+ "instrumentation_mincore.log.$1" using 1:10 title 'alloc failed' smooth sbezier with lines lw 2 axis x1y2
+
+EOF
diff --git a/rak/functional.h b/rak/functional.h
index cc149dbf..ac77b2da 100644
--- a/rak/functional.h
+++ b/rak/functional.h
@@ -627,6 +627,57 @@ make_mem_fun(Object* o, Ret (Object::*f)(Arg1, Arg2, Arg3)) {
return mem_fun3(o, f);
}
+template
+inline void
+slot_list_call(const Container& slot_list) {
+ if (slot_list.empty())
+ return;
+
+ typename Container::const_iterator first = slot_list.begin();
+ typename Container::const_iterator next = slot_list.begin();
+
+ while (++next != slot_list.end()) {
+ (*first)();
+ first = next;
+ }
+
+ (*first)();
+}
+
+template
+inline void
+slot_list_call(const Container& slot_list, Arg1 arg1) {
+ if (slot_list.empty())
+ return;
+
+ typename Container::const_iterator first = slot_list.begin();
+ typename Container::const_iterator next = slot_list.begin();
+
+ while (++next != slot_list.end()) {
+ (*first)(arg1);
+ first = next;
+ }
+
+ (*first)(arg1);
+}
+
+template
+inline void
+slot_list_call(const Container& slot_list, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) {
+ if (slot_list.empty())
+ return;
+
+ typename Container::const_iterator first = slot_list.begin();
+ typename Container::const_iterator next = slot_list.begin();
+
+ while (++next != slot_list.end()) {
+ (*first)(arg1, arg2, arg3, arg4);
+ first = next;
+ }
+
+ (*first)(arg1, arg2, arg3, arg4);
+}
+
}
#endif
diff --git a/rak/timer.h b/rak/timer.h
index 67bdc1c7..e25ad2e6 100644
--- a/rak/timer.h
+++ b/rak/timer.h
@@ -49,6 +49,9 @@ class timer {
timer(int64_t usec = 0) : m_time(usec) {}
timer(timeval tv) : m_time((int64_t)(uint32_t)tv.tv_sec * 1000000 + (int64_t)(uint32_t)tv.tv_usec % 1000000) {}
+ bool is_zero() const { return m_time == 0; }
+ bool is_not_zero() const { return m_time != 0; }
+
int32_t seconds() const { return m_time / 1000000; }
int32_t seconds_ceiling() const { return (m_time + 1000000 - 1) / 1000000; }
int64_t usec() const { return m_time; }
diff --git a/scripts/checks.m4 b/scripts/checks.m4
index 646e5406..598f39b3 100644
--- a/scripts/checks.m4
+++ b/scripts/checks.m4
@@ -21,9 +21,9 @@ AC_DEFUN([TORRENT_CHECK_XFS], [
AC_DEFUN([TORRENT_WITHOUT_XFS], [
AC_ARG_WITH(xfs,
- [ --without-xfs Do not check for XFS filesystem support],
+ AC_HELP_STRING([--without-xfs], [do not check for XFS filesystem support]),
[
- if test "$withval" = "yes"; then
+ if test "$withval" = "yes"; then
TORRENT_CHECK_XFS
fi
], [
@@ -34,7 +34,7 @@ AC_DEFUN([TORRENT_WITHOUT_XFS], [
AC_DEFUN([TORRENT_WITH_XFS], [
AC_ARG_WITH(xfs,
- [ --with-xfs Check for XFS filesystem support],
+ AC_HELP_STRING([--with-xfs], [check for XFS filesystem support]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_XFS
@@ -63,7 +63,7 @@ AC_DEFUN([TORRENT_CHECK_EPOLL], [
AC_DEFUN([TORRENT_WITHOUT_EPOLL], [
AC_ARG_WITH(epoll,
- [ --without-epoll Do not check for epoll support.],
+ AC_HELP_STRING([--without-epoll], [do not check for epoll support]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_EPOLL
@@ -133,7 +133,7 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE_SOCKET_ONLY], [
AC_DEFUN([TORRENT_WITH_KQUEUE], [
AC_ARG_WITH(kqueue,
- [ --with-kqueue enable kqueue. [[default=no]]],
+ AC_HELP_STRING([--with-kqueue], [enable kqueue [[default=no]]]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_KQUEUE
@@ -145,7 +145,7 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [
AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [
AC_ARG_WITH(kqueue,
- [ --without-kqueue Do not check for kqueue support.],
+ AC_HELP_STRING([--without-kqueue], [do not check for kqueue support]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_KQUEUE
@@ -160,8 +160,7 @@ AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [
AC_DEFUN([TORRENT_WITHOUT_VARIABLE_FDSET], [
AC_ARG_WITH(variable-fdset,
-
- [ --without-variable-fdset do not use non-portable variable sized fd_set's.],
+ AC_HELP_STRING([--without-variable-fdset], [do not use non-portable variable sized fd_set's]),
[
if test "$withval" = "yes"; then
AC_DEFINE(USE_VARIABLE_FDSET, 1, defined when we allow the use of fd_set's of any size)
@@ -205,7 +204,7 @@ AC_DEFUN([TORRENT_CHECK_POSIX_FALLOCATE], [
AC_DEFUN([TORRENT_WITH_POSIX_FALLOCATE], [
AC_ARG_WITH(posix-fallocate,
- [ --with-posix-fallocate Check for and use posix_fallocate to allocate files.],
+ AC_HELP_STRING([--with-posix-fallocate], [check for and use posix_fallocate to allocate files]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_POSIX_FALLOCATE
@@ -299,7 +298,7 @@ AC_DEFUN([TORRENT_DISABLED_STATFS], [
AC_DEFUN([TORRENT_WITHOUT_STATVFS], [
AC_ARG_WITH(statvfs,
- [ --without-statvfs Don't try to use statvfs to find free diskspace.],
+ AC_HELP_STRING([--without-statvfs], [don't try to use statvfs to find free diskspace]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_STATVFS
@@ -314,7 +313,7 @@ AC_DEFUN([TORRENT_WITHOUT_STATVFS], [
AC_DEFUN([TORRENT_WITHOUT_STATFS], [
AC_ARG_WITH(statfs,
- [ --without-statfs Don't try to use statfs to find free diskspace.],
+ AC_HELP_STRING([--without-statfs], [don't try to use statfs to find free diskspace]),
[
if test "$have_stat_vfs" = "no"; then
if test "$withval" = "yes"; then
@@ -336,7 +335,7 @@ AC_DEFUN([TORRENT_WITHOUT_STATFS], [
AC_DEFUN([TORRENT_WITH_ADDRESS_SPACE], [
AC_ARG_WITH(address-space,
- AC_HELP_STRING([--with-address-space=MB], [Change the default address space size, default 1024 MB.]),
+ AC_HELP_STRING([--with-address-space=MB], [change the default address space size [[default=1024mb]]]),
[
if test ! -z $withval -a "$withval" != "yes" -a "$withval" != "no"; then
AC_DEFINE_UNQUOTED(DEFAULT_ADDRESS_SPACE_SIZE, [$withval])
@@ -402,7 +401,7 @@ AC_DEFUN([TORRENT_CHECK_CXX11], [
AC_DEFUN([TORRENT_WITH_FASTCGI], [
AC_ARG_WITH(fastcgi,
- [ --with-fastcgi=PATH Enable FastCGI RPC support. (DO NOT USE)],
+ AC_HELP_STRING([--with-fastcgi=PATH], [enable FastCGI RPC support (DO NOT USE)]),
[
AC_MSG_CHECKING([for FastCGI (DO NOT USE)])
@@ -451,7 +450,7 @@ AC_DEFUN([TORRENT_WITH_XMLRPC_C], [
AC_MSG_CHECKING(for XMLRPC-C)
AC_ARG_WITH(xmlrpc-c,
- [ --with-xmlrpc-c=PATH Enable XMLRPC-C support.],
+ AC_HELP_STRING([--with-xmlrpc-c=PATH], [enable XMLRPC-C support]),
[
if test "$withval" = "no"; then
AC_MSG_RESULT(no)
@@ -508,3 +507,33 @@ AC_DEFUN([TORRENT_WITH_INOTIFY], [
AC_LANG_POP(C++)
])
+
+AC_DEFUN([TORRENT_CHECK_PTHREAD_SETNAME_NP], [
+ AC_CHECK_HEADERS(pthread.h)
+
+ AC_MSG_CHECKING(for pthread_setname_np type)
+
+ AC_TRY_LINK([
+ #include
+ #include
+ ],[
+ pthread_t t;
+ pthread_setname_np(t, "foo");
+ ],[
+ AC_DEFINE(HAS_PTHREAD_SETNAME_NP_GENERIC, 1, The function to set pthread name has a pthread_t argumet.)
+ AC_MSG_RESULT(generic)
+ ],[
+ AC_TRY_LINK([
+ #include
+ #include
+ ],[
+ pthread_t t;
+ pthread_setname_np("foo");
+ ],[
+ AC_DEFINE(HAS_PTHREAD_SETNAME_NP_DARWIN, 1, The function to set pthread name has no pthread argument.)
+ AC_MSG_RESULT(darwin)
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
+])
diff --git a/scripts/common.m4 b/scripts/common.m4
index 9c043e59..51276242 100644
--- a/scripts/common.m4
+++ b/scripts/common.m4
@@ -13,7 +13,7 @@ AC_DEFUN([TORRENT_CHECK_CXXFLAGS], [
AC_DEFUN([TORRENT_ENABLE_DEBUG], [
AC_ARG_ENABLE(debug,
- [ --enable-debug enable debug information [[default=yes]]],
+ AC_HELP_STRING([--enable-debug], [enable debug information [[default=yes]]]),
[
if test "$enableval" = "yes"; then
CXXFLAGS="$CXXFLAGS -g -DDEBUG"
@@ -28,7 +28,7 @@ AC_DEFUN([TORRENT_ENABLE_DEBUG], [
AC_DEFUN([TORRENT_ENABLE_WERROR], [
AC_ARG_ENABLE(werror,
- [ --enable-werror enable the -Werror and -Wall flag [[default=no]]],
+ AC_HELP_STRING([--enable-werror], [enable the -Werror and -Wall flag [[default=no]]]),
[
if test "$enableval" = "yes"; then
CXXFLAGS="$CXXFLAGS -Werror -Wall"
@@ -39,7 +39,7 @@ AC_DEFUN([TORRENT_ENABLE_WERROR], [
AC_DEFUN([TORRENT_ENABLE_EXTRA_DEBUG], [
AC_ARG_ENABLE(extra-debug,
- [ --enable-extra-debug enable extra debugging checks. [[default=no]]],
+ AC_HELP_STRING([--enable-extra-debug], [enable extra debugging checks [[default=no]]]),
[
if test "$enableval" = "yes"; then
AC_DEFINE(USE_EXTRA_DEBUG, 1, Enable extra debugging checks.)
@@ -50,7 +50,7 @@ AC_DEFUN([TORRENT_ENABLE_EXTRA_DEBUG], [
AC_DEFUN([TORRENT_WITH_SYSROOT], [
AC_ARG_WITH(sysroot,
- [ --with-sysroot=PATH compile and link with a specific sysroot.],
+ AC_HELP_STRING([--with-sysroot=PATH], [compile and link with a specific sysroot]),
[
AC_MSG_CHECKING(for sysroot)
@@ -72,7 +72,7 @@ AC_DEFUN([TORRENT_WITH_SYSROOT], [
AC_DEFUN([TORRENT_ENABLE_ARCH], [
AC_ARG_ENABLE(arch,
- [ --enable-arch=ARCH comma seprated list of architectures to compile for.],
+ AC_HELP_STRING([--enable-arch=ARCH], [comma seprated list of architectures to compile for]),
[
AC_MSG_CHECKING(for target architectures)
@@ -152,7 +152,7 @@ AC_DEFUN([TORRENT_MINCORE_SIGNEDNESS], [
AC_DEFUN([TORRENT_MINCORE], [
AC_ARG_ENABLE(mincore,
- [ --disable-mincore disable mincore check [[default=enable]]],
+ AC_HELP_STRING([--disable-mincore], [disable mincore check [[default=enable]]]),
[
if test "$enableval" = "yes"; then
TORRENT_MINCORE_SIGNEDNESS()
@@ -259,7 +259,7 @@ AC_DEFUN([TORRENT_CHECK_ALIGNED], [
AC_DEFUN([TORRENT_ENABLE_ALIGNED], [
AC_ARG_ENABLE(aligned,
- [ --enable-aligned enable alignment safe code [[default=check]]],
+ AC_HELP_STRING([--enable-aligned], [enable alignment safe code [[default=check]]]),
[
if test "$enableval" = "yes"; then
AC_DEFINE(USE_ALIGNED, 1, Require byte alignment)
@@ -270,9 +270,40 @@ AC_DEFUN([TORRENT_ENABLE_ALIGNED], [
])
+AC_DEFUN([TORRENT_DISABLE_INSTRUMENTATION], [
+ AC_MSG_CHECKING([if instrumentation should be included])
+
+ AC_ARG_ENABLE(instrumentation,
+ AC_HELP_STRING([--disable-instrumentation], [disable instrumentation [[default=enabled]]]),
+ [
+ if test "$enableval" = "yes"; then
+ AC_DEFINE(LT_INSTRUMENTATION, 1, enable instrumentation)
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+ ],[
+ AC_DEFINE(LT_INSTRUMENTATION, 1, enable instrumentation)
+ AC_MSG_RESULT(yes)
+ ])
+])
+
+
+AC_DEFUN([TORRENT_ENABLE_INTERRUPT_SOCKET], [
+ AC_ARG_ENABLE(interrupt-socket,
+ AC_HELP_STRING([--enable-interrupt-socket], [enable interrupt socket [[default=no]]]),
+ [
+ if test "$enableval" = "yes"; then
+ AC_DEFINE(USE_INTERRUPT_SOCKET, 1, Use interrupt socket instead of pthread_kill)
+ fi
+ ]
+ )
+])
+
+
AC_DEFUN([TORRENT_DISABLE_IPV6], [
AC_ARG_ENABLE(ipv6,
- [ --enable-ipv6 disable ipv6 [[default=no]]],
+ AC_HELP_STRING([--enable-ipv6], [enable ipv6 [[default=no]]]),
[
if test "$enableval" = "yes"; then
AC_DEFINE(RAK_USE_INET6, 1, enable ipv6 stuff)
@@ -282,7 +313,7 @@ AC_DEFUN([TORRENT_DISABLE_IPV6], [
AC_DEFUN([TORRENT_ENABLE_TR1], [
AC_ARG_ENABLE(std_tr1,
- [ --disable-std_tr1 disable check for support for TR1 [[default=enable]]],
+ AC_HELP_STRING([--disable-std_tr1], [disable check for support for TR1 [[default=enable]]]),
[
if test "$enableval" = "yes"; then
TORRENT_CHECK_TR1()
@@ -297,7 +328,7 @@ AC_DEFUN([TORRENT_ENABLE_TR1], [
AC_DEFUN([TORRENT_ENABLE_CXX11], [
AC_ARG_ENABLE(std_c++11,
- [ --disable-std_c++11 disable check for support for C++11 [[default=enable]]],
+ AC_HELP_STRING([--disable-std_c++11], [disable check for support for C++11 [[default=enable]]]),
[
if test "$enableval" = "yes"; then
TORRENT_CHECK_CXX11()
diff --git a/src/command_local.cc b/src/command_local.cc
index df5af765..45c63b89 100644
--- a/src/command_local.cc
+++ b/src/command_local.cc
@@ -287,6 +287,16 @@ apply_log_open_file(const torrent::Object::list_type& args) {
return torrent::Object();
}
+torrent::Object
+apply_log_open_gz_file(const torrent::Object::list_type& args) {
+ if (args.size() != 2)
+ throw torrent::input_error("Invalid number of arguments.");
+
+ torrent::log_open_gz_file_output(args.front().as_string().c_str(),
+ rak::path_expand(args.back().as_string()).c_str());
+ return torrent::Object();
+}
+
torrent::Object
apply_log_add_output(const torrent::Object::list_type& args) {
if (args.size() != 2)
@@ -391,8 +401,9 @@ initialize_command_local() {
CMD2_EXECUTE ("execute.capture", rpc::ExecFile::flag_throw | rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_capture);
CMD2_EXECUTE ("execute.capture_nothrow", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_capture);
- CMD2_ANY_LIST ("log.open_file", tr1::bind(&apply_log_open_file, tr1::placeholders::_2));
- CMD2_ANY_LIST ("log.add_output", tr1::bind(&apply_log_add_output, tr1::placeholders::_2));
+ CMD2_ANY_LIST ("log.open_file", tr1::bind(&apply_log_open_file, tr1::placeholders::_2));
+ CMD2_ANY_LIST ("log.open_gz_file", tr1::bind(&apply_log_open_gz_file, tr1::placeholders::_2));
+ CMD2_ANY_LIST ("log.add_output", tr1::bind(&apply_log_add_output, tr1::placeholders::_2));
CMD2_ANY_STRING ("log.execute", tr1::bind(&apply_log, tr1::placeholders::_2, 0));
CMD2_ANY_STRING ("log.vmmap.dump", tr1::bind(&log_vmmap_dump, tr1::placeholders::_2));
diff --git a/src/command_network.cc b/src/command_network.cc
index 37998931..e6cfd081 100644
--- a/src/command_network.cc
+++ b/src/command_network.cc
@@ -247,7 +247,9 @@ initialize_command_network() {
CMD2_VAR_BOOL ("network.port_random", true);
CMD2_VAR_STRING ("network.port_range", "6881-6999");
- CMD2_ANY ("network.listen.port", tr1::bind(&torrent::ConnectionManager::listen_port, cm));
+ CMD2_ANY ("network.listen.port", tr1::bind(&torrent::ConnectionManager::listen_port, cm));
+ CMD2_ANY ("network.listen.backlog", tr1::bind(&torrent::ConnectionManager::listen_backlog, cm));
+ CMD2_ANY_VALUE_V ("network.listen.backlog.set", tr1::bind(&torrent::ConnectionManager::set_listen_backlog, cm, tr1::placeholders::_2));
CMD2_VAR_BOOL ("protocol.pex", true);
CMD2_ANY_LIST ("protocol.encryption.set", tr1::bind(&apply_encryption, tr1::placeholders::_2));
diff --git a/src/core/curl_stack.cc b/src/core/curl_stack.cc
index f0e6e8ec..a5e0e499 100644
--- a/src/core/curl_stack.cc
+++ b/src/core/curl_stack.cc
@@ -86,34 +86,44 @@ CurlStack::new_socket(int fd) {
void
CurlStack::receive_action(CurlSocket* socket, int events) {
+ if (this <= (CurlStack*)0x100)
+ throw torrent::internal_error("CurlStack::receive_action(...) called with shit == NULL");
+
+ if (this >= (CurlStack*)0x00007fff00000000)
+ throw torrent::internal_error("CurlStack::receive_action(...) called with this == 0x00007fff00000002");
+
+ if (socket != NULL && socket <= (CurlSocket*)0x100)
+ throw torrent::internal_error("CurlStack::receive_action(...) called with socket == NULL");
+
+ if (socket >= (CurlSocket*)0x00007fff00000000)
+ throw torrent::internal_error("CurlStack::receive_action(...) called with socket == 0x00007fff00000002");
+
CURLMcode code;
do {
int count;
#if (LIBCURL_VERSION_NUM >= 0x071003)
- code = curl_multi_socket_action((CURLM*)m_handle, socket != NULL ? socket->file_descriptor() : CURL_SOCKET_TIMEOUT, events, &count);
+ code = curl_multi_socket_action((CURLM*)m_handle,
+ socket != NULL ? socket->file_descriptor() : CURL_SOCKET_TIMEOUT,
+ events,
+ &count);
#else
- code = curl_multi_socket((CURLM*)m_handle, socket != NULL ? socket->file_descriptor() : CURL_SOCKET_TIMEOUT, &count);
+ code = curl_multi_socket((CURLM*)m_handle,
+ socket != NULL ? socket->file_descriptor() : CURL_SOCKET_TIMEOUT,
+ &count);
#endif
if (code > 0)
throw torrent::internal_error("Error calling curl_multi_socket_action.");
- // Socket might be removed when cleaning handles below, future calls should not use it.
+ // Socket might be removed when cleaning handles below, future
+ // calls should not use it.
socket = NULL;
events = 0;
if ((unsigned int)count != size()) {
- // Done with some handles.
- int t;
- CURLMsg* msg;
-
- while ((msg = curl_multi_info_read((CURLM*)m_handle, &t)) != NULL) {
- if (msg->msg != CURLMSG_DONE)
- throw torrent::internal_error("CurlStack::receive_action() msg->msg != CURLMSG_DONE.");
-
- transfer_done(msg->easy_handle, msg->data.result == CURLE_OK ? NULL : curl_easy_strerror(msg->data.result));
- }
+ while (process_done_handle())
+ ; // Do nothing.
if (empty())
priority_queue_erase(&taskScheduler, &m_taskTimeout);
@@ -122,6 +132,23 @@ CurlStack::receive_action(CurlSocket* socket, int events) {
} while (code == CURLM_CALL_MULTI_PERFORM);
}
+bool
+CurlStack::process_done_handle() {
+ int remaining_msgs = 0;
+ CURLMsg* msg = curl_multi_info_read((CURLM*)m_handle, &remaining_msgs);
+
+ if (msg == NULL)
+ return false;
+
+ if (msg->msg != CURLMSG_DONE)
+ throw torrent::internal_error("CurlStack::receive_action() msg->msg != CURLMSG_DONE.");
+
+ transfer_done(msg->easy_handle,
+ msg->data.result == CURLE_OK ? NULL : curl_easy_strerror(msg->data.result));
+
+ return remaining_msgs != 0;
+}
+
void
CurlStack::transfer_done(void* handle, const char* msg) {
iterator itr = std::find_if(begin(), end(), rak::equal(handle, std::mem_fun(&CurlGet::handle)));
diff --git a/src/core/curl_stack.h b/src/core/curl_stack.h
index d17f825c..3b8b341b 100644
--- a/src/core/curl_stack.h
+++ b/src/core/curl_stack.h
@@ -125,6 +125,8 @@ class CurlStack : std::deque {
void receive_timeout();
+ bool process_done_handle();
+
void* m_handle;
unsigned int m_active;
diff --git a/src/core/manager.cc b/src/core/manager.cc
index 7cd58b76..c7373e22 100644
--- a/src/core/manager.cc
+++ b/src/core/manager.cc
@@ -47,8 +47,6 @@
#include
#include
#include
-#include
-#include
#include
#include
#include
@@ -115,7 +113,7 @@ Manager::set_hashing_view(View* v) {
throw torrent::internal_error("Manager::set_hashing_view(...) received NULL or is already set.");
m_hashingView = v;
- v->signal_changed().connect(sigc::mem_fun(this, &Manager::receive_hashing_changed));
+ m_hashingView->signal_changed().push_back(std::tr1::bind(&Manager::receive_hashing_changed, this));
}
torrent::ThrottlePair
diff --git a/src/core/view.cc b/src/core/view.cc
index 871f98ee..1b5fc09c 100644
--- a/src/core/view.cc
+++ b/src/core/view.cc
@@ -138,12 +138,18 @@ struct view_downloads_filter : std::unary_function {
const torrent::Object& m_command;
};
-inline void
+void
View::emit_changed() {
priority_queue_erase(&taskScheduler, &m_delayChanged);
priority_queue_insert(&taskScheduler, &m_delayChanged, cachedTime);
}
+void
+View::emit_changed_now() {
+ for (signal_void::iterator itr = m_signal_changed.begin(), last = m_signal_changed.end(); itr != last; itr++)
+ (*itr)();
+}
+
View::~View() {
if (m_name.empty())
return;
@@ -171,7 +177,7 @@ View::initialize(const std::string& name) {
m_focus = 0;
set_last_changed(rak::timer());
- m_delayChanged.slot() = std::tr1::bind(&signal_type::operator(), &m_signalChanged);
+ m_delayChanged.slot() = std::tr1::bind(&View::emit_changed_now, this);
}
void
diff --git a/src/core/view.h b/src/core/view.h
index 98d366d3..69d9fb79 100644
--- a/src/core/view.h
+++ b/src/core/view.h
@@ -52,8 +52,8 @@
#include
#include
#include
-#include
#include
+#include
#include "globals.h"
@@ -63,8 +63,9 @@ class Download;
class View : private std::vector {
public:
- typedef std::vector base_type;
- typedef sigc::signal0 signal_type;
+ typedef std::vector base_type;
+ typedef std::tr1::function slot_void;
+ typedef std::list signal_void;
using base_type::iterator;
using base_type::const_iterator;
@@ -101,7 +102,7 @@ public:
iterator focus() { return begin() + m_focus; }
const_iterator focus() const { return begin() + m_focus; }
- void set_focus(iterator itr) { m_focus = position(itr); m_signalChanged.emit(); }
+ void set_focus(iterator itr) { m_focus = position(itr); emit_changed(); }
void insert(Download* download) { base_type::push_back(download); }
void erase(Download* download);
@@ -143,7 +144,7 @@ public:
// Don't connect any slots until after initialize else it get's
// triggered when adding the Download's in DownloadList.
- signal_type& signal_changed() { return m_signalChanged; }
+ signal_void& signal_changed() { return m_signal_changed; }
private:
View(const View&);
@@ -154,7 +155,8 @@ private:
inline void insert_visible(Download* d);
inline void erase_internal(iterator itr);
- inline void emit_changed();
+ void emit_changed();
+ void emit_changed_now();
size_type position(const_iterator itr) const { return itr - begin(); }
@@ -176,7 +178,7 @@ private:
rak::timer m_lastChanged;
- signal_type m_signalChanged;
+ signal_void m_signal_changed;
rak::priority_item m_delayChanged;
};
diff --git a/src/display/canvas.cc b/src/display/canvas.cc
index 4394b894..31db4ad4 100644
--- a/src/display/canvas.cc
+++ b/src/display/canvas.cc
@@ -38,7 +38,7 @@
#include
#include
-#include
+#include
#include
#include "canvas.h"
diff --git a/src/display/window_download_list.cc b/src/display/window_download_list.cc
index 0b407138..ead4ddda 100644
--- a/src/display/window_download_list.cc
+++ b/src/display/window_download_list.cc
@@ -48,18 +48,27 @@
namespace display {
+WindowDownloadList::WindowDownloadList() :
+ Window(new Canvas, 0, 120, 1, extent_full, extent_full),
+ m_view(NULL) {
+}
+
WindowDownloadList::~WindowDownloadList() {
- m_connChanged.disconnect();
+ if (m_view != NULL)
+ m_view->signal_changed().erase(m_changed_itr);
+
+ m_view = NULL;
}
void
WindowDownloadList::set_view(core::View* l) {
+ if (m_view != NULL)
+ m_view->signal_changed().erase(m_changed_itr);
+
m_view = l;
- m_connChanged.disconnect();
-
if (m_view != NULL)
- m_connChanged = m_view->signal_changed().connect(sigc::mem_fun(*this, &Window::mark_dirty));
+ m_changed_itr = m_view->signal_changed().insert(m_view->signal_changed().begin(), std::tr1::bind(&Window::mark_dirty, this));
}
void
diff --git a/src/display/window_download_list.h b/src/display/window_download_list.h
index 0fed0c18..8e15cac9 100644
--- a/src/display/window_download_list.h
+++ b/src/display/window_download_list.h
@@ -37,23 +37,18 @@
#ifndef RTORRENT_DISPLAY_WINDOW_DOWNLOAD_LIST_H
#define RTORRENT_DISPLAY_WINDOW_DOWNLOAD_LIST_H
-#include
-
#include "window.h"
#include "core/download_list.h"
-
-namespace core {
- class View;
-}
+#include "core/view.h"
namespace display {
class WindowDownloadList : public Window {
public:
- WindowDownloadList() :
- Window(new Canvas, 0, 120, 1, extent_full, extent_full),
- m_view(NULL) {}
+ typedef core::View::signal_void::iterator signal_void_itr;
+
+ WindowDownloadList();
~WindowDownloadList();
virtual void redraw();
@@ -63,7 +58,7 @@ public:
private:
core::View* m_view;
- sigc::connection m_connChanged;
+ signal_void_itr m_changed_itr;
};
}
diff --git a/src/input/path_input.cc b/src/input/path_input.cc
index 2b951b28..fa8afdaa 100644
--- a/src/input/path_input.cc
+++ b/src/input/path_input.cc
@@ -41,14 +41,10 @@
#include
#include
+#include
+#include
#include
-
-#ifdef __sun__
- #include
- #include
-#else
- #include
-#endif
+#include
#include "path_input.h"
@@ -67,7 +63,8 @@ PathInput::pressed(int key) {
return TextInput::pressed(key);
} else if (m_showNext) {
- m_signalShowNext.emit();
+ for (signal_void::iterator itr = m_signal_show_next.begin(), last = m_signal_show_next.end(); itr != last; itr++)
+ (*itr)();
} else {
receive_do_complete();
@@ -78,17 +75,15 @@ PathInput::pressed(int key) {
struct _transform_filename {
void operator () (utils::directory_entry& entry) {
-#ifdef __sun__
- if (entry.d_type & S_IFDIR)
-#else
if (entry.d_type == DT_DIR)
-#endif
entry.d_name += '/';
}
};
void
PathInput::receive_do_complete() {
+ lt_log_print(torrent::LOG_UI_EVENTS, "path_input: received completion");
+
size_type dirEnd = find_last_delim();
utils::Directory dir(dirEnd != 0 ? str().substr(0, dirEnd) : "./");
@@ -101,7 +96,7 @@ PathInput::receive_do_complete() {
std::for_each(dir.begin(), dir.end(), _transform_filename());
- Range r = find_incomplete(dir, str().substr(dirEnd, get_pos()));
+ range_type r = find_incomplete(dir, str().substr(dirEnd, get_pos()));
if (r.first == r.second)
return; // Show some nice colors here.
@@ -121,8 +116,12 @@ PathInput::receive_do_complete() {
// Only emit if there are more than one option.
m_showNext = ++utils::Directory::iterator(r.first) != r.second;
- if (m_showNext)
- m_signalShowRange.emit(r.first, r.second);
+ if (m_showNext) {
+ lt_log_print(torrent::LOG_UI_EVENTS, "path_input: show next page");
+
+ for (signal_itr_itr::iterator itr = m_signal_show_range.begin(), last = m_signal_show_range.end(); itr != last; itr++)
+ (*itr)(r.first, r.second);
+ }
}
PathInput::size_type
@@ -147,9 +146,9 @@ find_complete_not_compare(const utils::directory_entry& complete, const std::str
return !complete.d_name.compare(0, base.size(), base);
}
-PathInput::Range
+PathInput::range_type
PathInput::find_incomplete(utils::Directory& d, const std::string& f) {
- Range r;
+ range_type r;
r.first = std::find_if(d.begin(), d.end(), rak::bind2nd(std::ptr_fun(&find_complete_not_compare), f));
r.second = std::find_if(r.first, d.end(), rak::bind2nd(std::ptr_fun(&find_complete_compare), f));
diff --git a/src/input/path_input.h b/src/input/path_input.h
index 3564aca2..5134f70f 100644
--- a/src/input/path_input.h
+++ b/src/input/path_input.h
@@ -37,7 +37,8 @@
#ifndef RTORRENT_INPUT_PATH_INPUT_H
#define RTORRENT_INPUT_PATH_INPUT_H
-#include
+#include
+#include
#include "utils/directory.h"
#include "text_input.h"
@@ -46,15 +47,19 @@ namespace input {
class PathInput : public TextInput {
public:
- typedef std::pair Range;
- typedef sigc::signal0 Signal;
- typedef sigc::signal2 SignalShowRange;
+ typedef utils::Directory::iterator directory_itr;
+ typedef std::pair range_type;
+
+ typedef std::tr1::function slot_void;
+ typedef std::tr1::function slot_itr_itr;
+ typedef std::list signal_void;
+ typedef std::list signal_itr_itr;
PathInput();
virtual ~PathInput() {}
- Signal& signal_show_next() { return m_signalShowNext; }
- SignalShowRange& signal_show_range() { return m_signalShowRange; }
+ signal_void& signal_show_next() { return m_signal_show_next; }
+ signal_itr_itr& signal_show_range() { return m_signal_show_range; }
virtual bool pressed(int key);
@@ -62,12 +67,12 @@ private:
void receive_do_complete();
size_type find_last_delim();
- Range find_incomplete(utils::Directory& d, const std::string& f);
+ range_type find_incomplete(utils::Directory& d, const std::string& f);
bool m_showNext;
- Signal m_signalShowNext;
- SignalShowRange m_signalShowRange;
+ signal_void m_signal_show_next;
+ signal_itr_itr m_signal_show_range;
};
}
diff --git a/src/signal_handler.h b/src/signal_handler.h
index a6aba468..f34c2810 100644
--- a/src/signal_handler.h
+++ b/src/signal_handler.h
@@ -37,7 +37,7 @@
#ifndef RTORRENT_SIGNAL_HANDLER_H
#define RTORRENT_SIGNAL_HANDLER_H
-#include
+#include
#include
class SignalHandler {
diff --git a/src/ui/download.h b/src/ui/download.h
index b00622d6..c896c528 100644
--- a/src/ui/download.h
+++ b/src/ui/download.h
@@ -39,7 +39,6 @@
#include
#include
-#include
#include "display/manager.h"
#include "utils/list_focus.h"
diff --git a/src/ui/download_list.cc b/src/ui/download_list.cc
index 78227e83..e3abc9ac 100644
--- a/src/ui/download_list.cc
+++ b/src/ui/download_list.cc
@@ -38,8 +38,6 @@
#include
#include
-#include
-#include
#include
#include
#include
@@ -270,11 +268,14 @@ DownloadList::receive_view_input(Input type) {
ElementStringList* esl = dynamic_cast(m_uiArray[DISPLAY_STRING_LIST]);
- input->signal_show_next().connect(std::tr1::bind(&DownloadList::activate_display, this, DISPLAY_STRING_LIST));
- input->signal_show_next().connect(std::tr1::bind(&ElementStringList::next_screen, *esl));
+ input->signal_show_next().push_back(std::tr1::bind(&DownloadList::activate_display, this, DISPLAY_STRING_LIST));
+ input->signal_show_next().push_back(std::tr1::bind(&ElementStringList::next_screen, esl));
- input->signal_show_range().connect(sigc::hide(sigc::hide(std::tr1::bind(&DownloadList::activate_display, this, DISPLAY_STRING_LIST))));
- input->signal_show_range().connect(sigc::mem_fun(*esl, &ElementStringList::set_range_dirent));
+ input->signal_show_range().push_back(std::tr1::bind(&DownloadList::activate_display, this, DISPLAY_STRING_LIST));
+ input->signal_show_range().push_back(std::tr1::bind(&ElementStringList::set_range_dirent,
+ esl,
+ std::tr1::placeholders::_1,
+ std::tr1::placeholders::_2));
input->bindings()['\n'] = std::tr1::bind(&DownloadList::receive_exit_input, this, type);
input->bindings()[KEY_ENTER] = std::tr1::bind(&DownloadList::receive_exit_input, this, type);
diff --git a/src/ui/element_string_list.cc b/src/ui/element_string_list.cc
index f57b3f97..79f1adf2 100644
--- a/src/ui/element_string_list.cc
+++ b/src/ui/element_string_list.cc
@@ -55,6 +55,8 @@ ElementStringList::activate(display::Frame* frame, bool focus) {
if (is_active())
throw torrent::internal_error("ui::ElementStringList::activate(...) is_active().");
+ lt_log_print(torrent::LOG_UI_EVENTS, "element_string_list: activate");
+
control->input()->push_back(&m_bindings);
m_window = new WStringList();
@@ -69,6 +71,8 @@ ElementStringList::disable() {
if (!is_active())
throw torrent::internal_error("ui::ElementStringList::disable(...) !is_active().");
+ lt_log_print(torrent::LOG_UI_EVENTS, "element_string_list: deactivate");
+
control->input()->erase(&m_bindings);
m_frame->clear();
@@ -80,6 +84,9 @@ ElementStringList::disable() {
void
ElementStringList::next_screen() {
+ if (m_window == NULL)
+ return;
+
if (m_window->get_draw_end() != m_list.end())
m_window->set_range(m_window->get_draw_end(), m_list.end());
else
diff --git a/src/ui/element_string_list.h b/src/ui/element_string_list.h
index fcd4b749..e034988b 100644
--- a/src/ui/element_string_list.h
+++ b/src/ui/element_string_list.h
@@ -41,6 +41,7 @@
#include
#include
#include
+#include
#include "element_base.h"
@@ -69,8 +70,14 @@ public:
while (first != last)
m_list.push_back(*(first++));
- m_window->set_range(m_list.begin(), m_list.end());
- m_window->mark_dirty();
+ if (m_window != NULL) {
+ lt_log_print(torrent::LOG_UI_EVENTS, "element_string_list: set range (visible)");
+
+ m_window->set_range(m_list.begin(), m_list.end());
+ m_window->mark_dirty();
+ } else {
+ lt_log_print(torrent::LOG_UI_EVENTS, "element_string_list: set range (hidden)");
+ }
}
// A hack, clean this up.
@@ -81,8 +88,14 @@ public:
while (first != last)
m_list.push_back((first++)->d_name);
- m_window->set_range(m_list.begin(), m_list.end());
- m_window->mark_dirty();
+ if (m_window != NULL) {
+ lt_log_print(torrent::LOG_UI_EVENTS, "element_string_list: set dirent range (visible)");
+
+ m_window->set_range(m_list.begin(), m_list.end());
+ m_window->mark_dirty();
+ } else {
+ lt_log_print(torrent::LOG_UI_EVENTS, "element_string_list: set dirent range (hidden)");
+ }
}
void next_screen();
diff --git a/src/utils/directory.cc b/src/utils/directory.cc
index f72d0f28..f934aeb8 100644
--- a/src/utils/directory.cc
+++ b/src/utils/directory.cc
@@ -38,14 +38,12 @@
#include
#include
+
#include
+#include
#include
#include
-#ifdef __sun__
-#include
-#endif
-
#include "directory.h"
namespace utils {
diff --git a/src/utils/list_focus.h b/src/utils/list_focus.h
index 5ad3ed4c..25cc0af6 100644
--- a/src/utils/list_focus.h
+++ b/src/utils/list_focus.h
@@ -37,7 +37,7 @@
#ifndef RTORRENT_UTILS_LIST_FOCUS_H
#define RTORRENT_UTILS_LIST_FOCUS_H
-#include
+#include
namespace utils {
@@ -46,15 +46,18 @@ namespace utils {
template
class ListFocus {
public:
- typedef typename Base::iterator iterator;
- typedef typename Base::const_iterator const_iterator;
- typedef typename Base::reverse_iterator reverse_iterator;
- typedef typename Base::const_reverse_iterator const_reverse_iterator;
+ typedef Base base_type;
+ typedef std::tr1::function slot_void;
+ typedef std::list signal_void;
- typedef typename Base::value_type value_type;
- typedef sigc::signal0 Signal;
+ typedef typename base_type::iterator iterator;
+ typedef typename base_type::const_iterator const_iterator;
+ typedef typename base_type::reverse_iterator reverse_iterator;
+ typedef typename base_type::const_reverse_iterator const_reverse_iterator;
- ListFocus(Base* b = NULL) : m_base(b) { if (b) m_focus = b->end(); }
+ typedef typename base_type::value_type value_type;
+
+ ListFocus(base_type* b = NULL) : m_base(b) { if (b) m_focus = b->end(); }
// Convinience functions, would have added more through using, but
// can't.
@@ -64,10 +67,10 @@ public:
reverse_iterator rend() { return m_base->rend(); }
// Don't do erase on this object without making sure focus is right.
- Base& base() { return *m_base; }
+ base_type& base() { return *m_base; }
iterator get_focus() { return m_focus; }
- void set_focus(iterator itr) { m_focus = itr; m_signalChanged.emit(); }
+ void set_focus(iterator itr);
// These are looping increment/decrements.
iterator inc_focus();
@@ -77,15 +80,24 @@ public:
void remove(const value_type& v);
// Be careful with copying signals.
- Signal& signal_changed() { return m_signalChanged; }
+ signal_void& signal_changed() { return m_signal_changed; }
private:
- Base* m_base;
+ void emit_changed();
+
+ base_type* m_base;
iterator m_focus;
- Signal m_signalChanged;
+ signal_void m_signal_changed;
};
+template
+void
+ListFocus ::set_focus(iterator itr) {
+ m_focus = itr;
+ emit_changed();
+}
+
template
typename ListFocus ::iterator
ListFocus ::inc_focus() {
@@ -94,8 +106,7 @@ ListFocus ::inc_focus() {
else
m_focus = begin();
- m_signalChanged.emit();
-
+ emit_changed();
return m_focus;
}
@@ -107,8 +118,7 @@ ListFocus ::dec_focus() {
else
m_focus = end();
- m_signalChanged.emit();
-
+ emit_changed();
return m_focus;
}
@@ -120,7 +130,7 @@ ListFocus ::erase(iterator itr) {
else
return m_base->erase(itr);
- m_signalChanged.emit();
+ emit_changed();
}
template
@@ -136,6 +146,13 @@ ListFocus ::remove(const value_type& v) {
++first;
}
+template
+void
+ListFocus ::emit_changed() {
+ for (signal_void::iterator itr = m_signal_changed.begin(), last = m_signal_changed.end(); itr != last; itr++)
+ (*itr)();
+}
+
}
#endif