mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-06 18:22:32 +00:00
Compare commits
58 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d3ecc83b32 | |||
| 457d5170b8 | |||
| 1c598d51ef | |||
| 644ea6c23f | |||
| de3615a72c | |||
| e9e4064bb3 | |||
| 04fc51e76b | |||
| 24693fc19e | |||
| 9661a2aaa9 | |||
| aaf42c247e | |||
| cba48f4a10 | |||
| 4463bf418e | |||
| 8bd7c79755 | |||
| f2b83d50e8 | |||
| ab40059891 | |||
| b9d880dea3 | |||
| b4c59d2c7a | |||
| 231606afc1 | |||
| a9196b43d4 | |||
| 8203949259 | |||
| 537c692f47 | |||
| 95b1a19ef1 | |||
| a4ab0112dc | |||
| 897a6face2 | |||
| 3ab38583b8 | |||
| 1003013f10 | |||
| 7bbd9a02a0 | |||
| f0809ec29d | |||
| e8c1f3ed2c | |||
| 3618b9dc4f | |||
| df8cb53ed2 | |||
| 2d565d1c80 | |||
| de6c48ca3f | |||
| 5fb61b2857 | |||
| 46e94259e8 | |||
| 9ff373fe58 | |||
| 6d888c008d | |||
| 9fe4d188e9 | |||
| 9d5b769d78 | |||
| 55615abe9e | |||
| 303edab9ec | |||
| 877c00d54e | |||
| 4c63cee7a2 | |||
| 58a74cee48 | |||
| 85e74b5542 | |||
| 6f8c1246dc | |||
| 97415c656b | |||
| 3d9c083032 | |||
| dd221ac66a | |||
| 25f729fab5 | |||
| 316b0b51d5 | |||
| a8622e5c80 | |||
| d1dd5ac080 | |||
| 9f2b81534a | |||
| 2ab7460cbc | |||
| 2a998df4f1 | |||
| d5b28c30a9 | |||
| a5a1e2fde5 |
@@ -16,6 +16,9 @@ jobs:
|
||||
# OPTIONAL: auto-closing conversations requires the `contents` permission
|
||||
contents: write
|
||||
steps:
|
||||
- name: Sleep for 30 seconds
|
||||
run: sleep 30s
|
||||
shell: bash
|
||||
- name: Download analysis results
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
|
||||
@@ -14,6 +14,8 @@ jobs:
|
||||
- name: Fetch libtorrent
|
||||
run: |
|
||||
git clone https://github.com/rakshasa/libtorrent
|
||||
cd libtorrent
|
||||
git checkout stable-0.15
|
||||
- name: Build libtorrent
|
||||
run: |
|
||||
cd libtorrent
|
||||
|
||||
@@ -14,6 +14,8 @@ jobs:
|
||||
- name: Fetch libtorrent
|
||||
run: |
|
||||
git clone https://github.com/rakshasa/libtorrent
|
||||
cd libtorrent
|
||||
git checkout stable-0.15
|
||||
- name: Build libtorrent
|
||||
run: |
|
||||
cd libtorrent
|
||||
|
||||
+1
-4
@@ -4,20 +4,17 @@ SUBDIRS = \
|
||||
test
|
||||
|
||||
EXTRA_DIST= \
|
||||
rtorrent.lua \
|
||||
rak/address_info.h \
|
||||
rak/algorithm.h \
|
||||
rak/allocators.h \
|
||||
rak/error_number.h \
|
||||
rak/file_stat.h \
|
||||
rak/fs_stat.h \
|
||||
rak/path.h \
|
||||
rak/partial_queue.h \
|
||||
rak/priority_queue.h \
|
||||
rak/priority_queue_default.h \
|
||||
rak/regex.h \
|
||||
rak/socket_address.h \
|
||||
rak/string_manip.h \
|
||||
rak/timer.h \
|
||||
rak/unordered_vector.h \
|
||||
scripts/checks.m4 \
|
||||
scripts/common.m4 \
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
BUILDING
|
||||
|
||||
Run "aclocal -I scripts && autoconf -i && autoheader && automake --add-missing"
|
||||
to generate the configure scripts if necessary. The man page "doc/rtorrent.1"
|
||||
must be generated with "docbook2man rtorrent.1.xml" if it is missing.
|
||||
|
||||
Note that rtorrent follows the development of libtorrent closely, and
|
||||
thus the versions must be in sync. This should not be nessesary in the
|
||||
future, when the library API stabilizes.
|
||||
|
||||
USAGE
|
||||
|
||||
See the man page or website for instructions.
|
||||
|
||||
LICENSE
|
||||
|
||||
GNU GPL, see COPYING. "libtorrent/src/utils/sha_fast.{cc,h}" is
|
||||
originally from the Mozilla NSS and is under a triple license; MPL,
|
||||
LGPL and GPL. An exception to non-NSS code has been added for linking
|
||||
to OpenSSL as requested by Debian, though the author considers that
|
||||
library to be part of the Operative System and thus linking is allowed
|
||||
according to the GPL.
|
||||
|
||||
Use whatever fits your purpose, the code required to compile with
|
||||
Mozilla's NSS implementation of SHA1 has been retained and can be
|
||||
compiled if the user wishes to avoid using OpenSSL.
|
||||
|
||||
DEPENDENCIES
|
||||
|
||||
libcurl >= 7.12.0
|
||||
ncurses
|
||||
|
||||
CONTACT
|
||||
|
||||
Jari Sundell
|
||||
|
||||
Skomakerveien 33
|
||||
3185 Skoppum, NORWAY
|
||||
|
||||
Send bug reports, suggestions and patches to
|
||||
<sundell.software@gmail.com> or to the mailinglist.
|
||||
@@ -1,40 +1,88 @@
|
||||
[](https://paypal.me/jarisundelljp)
|
||||
|
||||
RTorrent BitTorrent Client
|
||||
========
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
A ncurses-based command line torrent client for high performance.
|
||||
|
||||
To learn how to use rTorrent visit the [Wiki](https://github.com/rakshasa/rtorrent/wiki).
|
||||
|
||||
Stable
|
||||
------
|
||||
|
||||
* [https://github.com/rakshasa/rtorrent-archive/raw/master/libtorrent-0.13.8.tar.gz](https://github.com/rakshasa/rtorrent-archive/raw/master/libtorrent-0.13.8.tar.gz)
|
||||
* [https://github.com/rakshasa/rtorrent-archive/raw/master/rtorrent-0.9.8.tar.gz](https://github.com/rakshasa/rtorrent-archive/raw/master/rtorrent-0.9.8.tar.gz)
|
||||
|
||||
Unstable
|
||||
------
|
||||
|
||||
* [https://github.com/rakshasa/rtorrent-archive/raw/master/libtorrent-0.14.0.tar.gz](https://github.com/rakshasa/rtorrent-archive/raw/master/libtorrent-0.14.0.tar.gz)
|
||||
* [https://github.com/rakshasa/rtorrent-archive/raw/master/rtorrent-0.10.0.tar.gz](https://github.com/rakshasa/rtorrent-archive/raw/master/rtorrent-0.10.0.tar.gz)
|
||||
Download the [latest stable release](https://github.com/rakshasa/rtorrent/releases/latest)
|
||||
|
||||
Related Projects
|
||||
----------------
|
||||
|
||||
* [https://github.com/rakshasa/rbedit](https://github.com/rakshasa/rbedit): A dependency-free bencode editor.
|
||||
* [https://github.com/rakshasa/rbedit](https://github.com/rakshasa/rbedit): A dependency-free bencode editor.
|
||||
|
||||
Donate to rTorrent development
|
||||
------------------------------
|
||||
|
||||
* [Paypal](https://paypal.me/jarisundellno)
|
||||
* [Patreon](https://www.patreon.com/rtorrent)
|
||||
* [SubscribeStar](https://www.subscribestar.com/rtorrent)
|
||||
* Bitcoin: 1MpmXm5AHtdBoDaLZstJw8nupJJaeKu8V8
|
||||
* Ethereum: 0x9AB1e3C3d8a875e870f161b3e9287Db0E6DAfF78
|
||||
* Litecoin: LdyaVR67LBnTf6mAT4QJnjSG2Zk67qxmfQ
|
||||
* Cardano: addr1qytaslmqmk6dspltw06sp0zf83dh09u79j49ceh5y26zdcccgq4ph7nmx6kgmzeldauj43254ey97f3x4xw49d86aguqwfhlte
|
||||
* [Paypal](https://paypal.me/jarisundellno)
|
||||
* [Patreon](https://www.patreon.com/rtorrent)
|
||||
* [SubscribeStar](https://www.subscribestar.com/rtorrent)
|
||||
* Bitcoin: 1MpmXm5AHtdBoDaLZstJw8nupJJaeKu8V8
|
||||
* Ethereum: 0x9AB1e3C3d8a875e870f161b3e9287Db0E6DAfF78
|
||||
* Litecoin: LdyaVR67LBnTf6mAT4QJnjSG2Zk67qxmfQ
|
||||
* Cardano: addr1qytaslmqmk6dspltw06sp0zf83dh09u79j49ceh5y26zdcccgq4ph7nmx6kgmzeldauj43254ey97f3x4xw49d86aguqwfhlte
|
||||
|
||||
|
||||
Help keep rTorrent development going by donating to its creator.
|
||||
|
||||
|
||||
BUILDING
|
||||
--------
|
||||
|
||||
Jump into the github cloned directory
|
||||
|
||||
```
|
||||
cd rtorrent
|
||||
```
|
||||
|
||||
## Install build dependencies
|
||||
|
||||
Install [libtorrent](https://libtorrent.org/) with the same version rTorrent.
|
||||
|
||||
Generate configure scripts:
|
||||
|
||||
```
|
||||
autoreconf -ivf
|
||||
```
|
||||
|
||||
Optionally, generate man pages:
|
||||
|
||||
```
|
||||
docbook2man rtorrent.1.xml
|
||||
```
|
||||
|
||||
Man pages output to "doc/rtorrent.1".
|
||||
|
||||
RTorrent follows the development of [libtorrent](https://libtorrent.org/) closely, and thus the versions must be in sync.
|
||||
|
||||
## USAGE
|
||||
|
||||
Refer to User Guide: https://github.com/rakshasa/rtorrent/wiki/User-Guide
|
||||
|
||||
## LICENSE
|
||||
|
||||
GNU GPL, see COPYING. "libtorrent/src/utils/sha_fast.{cc,h}" is
|
||||
originally from the Mozilla NSS and is under a triple license; MPL,
|
||||
LGPL and GPL. An exception to non-NSS code has been added for linking to OpenSSL as requested by Debian, though the author considers that library to be part of the Operative System and thus linking is allowed according to the GPL.
|
||||
|
||||
Use whatever fits your purpose, the code required to compile with
|
||||
Mozilla's NSS implementation of SHA1 has been retained and can be
|
||||
compiled if the user wishes to avoid using OpenSSL.
|
||||
|
||||
## DEPENDENCIES
|
||||
|
||||
* libcurl >= 7.12.0
|
||||
* libtorrent = (same version)
|
||||
* ncurses
|
||||
|
||||
## BUILD DEPENDENCIES
|
||||
|
||||
* libtoolize
|
||||
* aclocal
|
||||
* autoconf
|
||||
* autoheader
|
||||
* automake
|
||||
|
||||
+7
-10
@@ -1,6 +1,6 @@
|
||||
m4_pattern_allow([PKG_CHECK_EXISTS])
|
||||
|
||||
AC_INIT([rtorrent],[0.15.2],[sundell.software@gmail.com])
|
||||
AC_INIT([rtorrent],[0.15.7],[sundell.software@gmail.com])
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIRS([scripts])
|
||||
@@ -10,7 +10,7 @@ AM_PROG_AR
|
||||
LT_INIT
|
||||
|
||||
AC_PROG_CXX
|
||||
AC_DEFINE([API_VERSION], [11], [api version])
|
||||
AC_DEFINE([API_VERSION], [15], [api version])
|
||||
|
||||
# Filter out unwanted flags added by autoconf on some systems, e.g. MacOS.
|
||||
TORRENT_REMOVE_UNWANTED(CXX, $CXX, -std=c++11 -std=gnu++11)
|
||||
@@ -54,7 +54,7 @@ fi
|
||||
|
||||
PKG_CHECK_MODULES([LIBCURL], [libcurl],, [LIBCURL_CHECK_CONFIG])
|
||||
PKG_CHECK_MODULES([CPPUNIT], [cppunit],, [no_cppunit="yes"])
|
||||
PKG_CHECK_MODULES([DEPENDENCIES], [libtorrent >= 0.15.2])
|
||||
PKG_CHECK_MODULES([DEPENDENCIES], [libtorrent >= 0.15.7])
|
||||
|
||||
AC_LANG_PUSH(C++)
|
||||
TORRENT_WITH_XMLRPC_C
|
||||
@@ -71,13 +71,6 @@ AC_DEFINE(HAVE_CONFIG_H, 1, true if config.h was included)
|
||||
AC_DEFINE(USER_AGENT, [std::string(PACKAGE "/" VERSION "/") + torrent::version()], Http user agent)
|
||||
|
||||
AC_CHECK_FUNCS(posix_memalign)
|
||||
TORRENT_CHECK_CACHELINE()
|
||||
TORRENT_CHECK_POPCOUNT()
|
||||
|
||||
CC_ATTRIBUTE_UNUSED(
|
||||
AC_DEFINE([__UNUSED], [__attribute__((unused))], [Wrapper around unused attribute]),
|
||||
AC_DEFINE([__UNUSED], [], [Null-wrapper if unused attribute is unsupported])
|
||||
)
|
||||
|
||||
dnl Only update global build variables immediately before generating the output,
|
||||
dnl to avoid affecting the global build environment for other autoconf checks.
|
||||
@@ -85,10 +78,14 @@ LIBS="$PTHREAD_LIBS $CURSES_LIB $CURSES_LIBS $LIBCURL $LIBCURL_LIBS $DEPENDENCIE
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS $LIBCURL_CPPFLAGS $LIBCURL_CFLAGS $DEPENDENCIES_CFLAGS $CURSES_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS $LIBCURL_CPPFLAGS $LIBCURL_CFLAGS $DEPENDENCIES_CFLAGS $CURSES_CFLAGS"
|
||||
|
||||
TORRENT_CHECK_CACHELINE()
|
||||
TORRENT_CHECK_POPCOUNT()
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
doc/Makefile
|
||||
src/Makefile
|
||||
test/Makefile
|
||||
])
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
+1
-1
@@ -556,4 +556,4 @@ log messages, but may be useful to debug connection problems.
|
||||
.SH "AUTHORS"
|
||||
.PP
|
||||
|
||||
Jari "Rakshasa" Sundell <jaris@ifi.uio.no>
|
||||
Jari "Rakshasa" Sundell
|
||||
|
||||
@@ -1112,7 +1112,7 @@ log messages, but may be useful to debug connection problems.
|
||||
<para>
|
||||
<simplelist type="vert">
|
||||
|
||||
<member>Jari "Rakshasa" Sundell <email>jaris@ifi.uio.no</email></member>
|
||||
<member>Jari "Rakshasa" Sundell <email>sundell.software@gmail.com</email></member>
|
||||
|
||||
</simplelist>
|
||||
</para>
|
||||
|
||||
@@ -73,6 +73,10 @@
|
||||
#
|
||||
#network.port_random.set = no
|
||||
|
||||
# Set RPC type
|
||||
#network.rpc.use_xmlrpc.set = true
|
||||
#network.rpc.use_jsonrpc.set = true
|
||||
|
||||
# Check hash for finished torrents. Might be useful until the bug is
|
||||
# fixed that causes lack of disk-space not to be properly reported.
|
||||
#
|
||||
|
||||
@@ -76,6 +76,8 @@ schedule2 = monitor_diskspace, 15, 60, ((close_low_diskspace, 1000M))
|
||||
##network.http.capath.set = "/etc/ssl/certs"
|
||||
##network.http.ssl_verify_peer.set = 0
|
||||
##network.http.ssl_verify_host.set = 0
|
||||
#network.rpc.use_xmlrpc.set = true
|
||||
#network.rpc.use_jsonrpc.set = true
|
||||
|
||||
# Some additional values and commands
|
||||
method.insert = system.startup_time, value|const, (system.time)
|
||||
|
||||
+1
-4
@@ -29,10 +29,7 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell
|
||||
|
||||
// Wrapper for addrinfo with focus on zero-copy conversion to and from
|
||||
// the c-type and wrapper.
|
||||
|
||||
+2
-4
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#ifndef RAK_ALGORITHM_H
|
||||
#define RAK_ALGORITHM_H
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
// rak - Rakshasa's toolbox
|
||||
// Copyright (C) 2005-2007, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
// Some allocators for cacheline aligned chunks of memory, etc.
|
||||
|
||||
#ifndef RAK_ALLOCATORS_H
|
||||
#define RAK_ALLOCATORS_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace rak {
|
||||
|
||||
template <class T = void*>
|
||||
class cacheline_allocator {
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef const void* const_void_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T value_type;
|
||||
|
||||
cacheline_allocator() throw() { }
|
||||
cacheline_allocator(const cacheline_allocator&) throw() { }
|
||||
template <class U>
|
||||
cacheline_allocator(const cacheline_allocator<U>&) throw() { }
|
||||
~cacheline_allocator() throw() { }
|
||||
|
||||
template <class U>
|
||||
struct rebind { typedef cacheline_allocator<U> other; };
|
||||
|
||||
// return address of values
|
||||
pointer address (reference value) const { return &value; }
|
||||
const_pointer address (const_reference value) const { return &value; }
|
||||
|
||||
size_type max_size () const throw() { return std::numeric_limits<size_t>::max() / sizeof(T); }
|
||||
|
||||
pointer allocate(size_type num, const_void_pointer hint = 0) { return alloc_size(num*sizeof(T)); }
|
||||
|
||||
static pointer alloc_size(size_type size) {
|
||||
pointer ptr = NULL;
|
||||
int __UNUSED result = posix_memalign((void**)&ptr, LT_SMP_CACHE_BYTES, size);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void construct (pointer p, const T& value) { new((void*)p)T(value); }
|
||||
void destroy (pointer p) { p->~T(); }
|
||||
void deallocate (pointer p, size_type num) { free((void*)p); }
|
||||
};
|
||||
|
||||
|
||||
template <class T1, class T2>
|
||||
bool operator== (const cacheline_allocator<T1>&, const cacheline_allocator<T2>&) throw() {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T1, class T2>
|
||||
bool operator!= (const cacheline_allocator<T1>&, const cacheline_allocator<T2>&) throw() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Operator new with custom allocators:
|
||||
//
|
||||
|
||||
template <typename T>
|
||||
void* operator new(size_t s, rak::cacheline_allocator<T> a) { return a.alloc_size(s); }
|
||||
|
||||
#endif // namespace rak
|
||||
+1
-4
@@ -29,10 +29,7 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
#ifndef RAK_ERROR_NUMBER_H
|
||||
#define RAK_ERROR_NUMBER_H
|
||||
|
||||
+2
-4
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#ifndef RAK_FILE_STAT_H
|
||||
#define RAK_FILE_STAT_H
|
||||
|
||||
+2
-4
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#ifndef RAK_PARTIAL_QUEUE_H
|
||||
#define RAK_PARTIAL_QUEUE_H
|
||||
|
||||
+2
-4
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
// Various functions for manipulating file paths. Also consider making
|
||||
// a directory iterator.
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
// priority_queue is a priority queue implemented using a binary
|
||||
// heap. It can contain multiple instances of a value.
|
||||
|
||||
#ifndef RAK_PRIORITY_QUEUE_H
|
||||
#define RAK_PRIORITY_QUEUE_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace rak {
|
||||
|
||||
template <typename Value, typename Compare, typename Equal>
|
||||
class priority_queue : public std::vector<Value> {
|
||||
public:
|
||||
typedef std::vector<Value> base_type;
|
||||
typedef typename base_type::reference reference;
|
||||
typedef typename base_type::const_reference const_reference;
|
||||
typedef typename base_type::iterator iterator;
|
||||
typedef typename base_type::const_iterator const_iterator;
|
||||
typedef typename base_type::value_type value_type;
|
||||
|
||||
using base_type::begin;
|
||||
using base_type::end;
|
||||
using base_type::size;
|
||||
using base_type::empty;
|
||||
using base_type::clear;
|
||||
|
||||
priority_queue(Compare l = Compare(), Equal e = Equal())
|
||||
: m_compare(l), m_equal(e) {}
|
||||
|
||||
const_reference top() const {
|
||||
return base_type::front();
|
||||
}
|
||||
|
||||
void pop() {
|
||||
std::pop_heap(begin(), end(), m_compare);
|
||||
base_type::pop_back();
|
||||
}
|
||||
|
||||
void update() {
|
||||
std::make_heap(begin(), end(), m_compare);
|
||||
}
|
||||
|
||||
void push(const value_type& value) {
|
||||
base_type::push_back(value);
|
||||
std::push_heap(begin(), end(), m_compare);
|
||||
}
|
||||
|
||||
template <typename Key>
|
||||
iterator find(const Key& key) {
|
||||
return std::find_if(begin(), end(), [&](auto& value) { return m_equal(value, key); });
|
||||
}
|
||||
|
||||
template <typename Key>
|
||||
bool erase(const Key& key) {
|
||||
iterator itr = find(key);
|
||||
|
||||
if (itr == end())
|
||||
return false;
|
||||
|
||||
erase(itr);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Removes 'itr' from the queue.
|
||||
void erase(iterator itr) {
|
||||
base_type::erase(itr);
|
||||
std::make_heap(begin(), end(), m_compare);
|
||||
}
|
||||
|
||||
private:
|
||||
Compare m_compare;
|
||||
Equal m_equal;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,122 +0,0 @@
|
||||
#ifndef RAK_PRIORITY_QUEUE_DEFAULT_H
|
||||
#define RAK_PRIORITY_QUEUE_DEFAULT_H
|
||||
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <rak/priority_queue.h>
|
||||
#include <rak/timer.h>
|
||||
|
||||
#include "torrent/exceptions.h"
|
||||
|
||||
namespace rak {
|
||||
|
||||
class priority_item {
|
||||
public:
|
||||
typedef std::function<void (void)> slot_void;
|
||||
|
||||
priority_item() {}
|
||||
~priority_item() {
|
||||
assert(!is_queued() && "priority_item::~priority_item() called on a queued item.");
|
||||
|
||||
m_time = timer();
|
||||
m_slot = slot_void();
|
||||
}
|
||||
|
||||
bool is_valid() const { return (bool)m_slot; }
|
||||
bool is_queued() const { return m_time != timer(); }
|
||||
|
||||
slot_void& slot() { return m_slot; }
|
||||
|
||||
const timer& time() const { return m_time; }
|
||||
void clear_time() { m_time = timer(); }
|
||||
void set_time(const timer& t) { m_time = t; }
|
||||
|
||||
bool compare(const timer& t) const { return m_time > t; }
|
||||
|
||||
private:
|
||||
priority_item(const priority_item&);
|
||||
void operator = (const priority_item&);
|
||||
|
||||
timer m_time;
|
||||
slot_void m_slot;
|
||||
};
|
||||
|
||||
struct priority_compare {
|
||||
bool operator () (const priority_item* const p1, const priority_item* const p2) const {
|
||||
return p1->time() > p2->time();
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::equal_to<priority_item*> priority_equal;
|
||||
typedef priority_queue<priority_item*, priority_compare, priority_equal> priority_queue_default;
|
||||
|
||||
inline void
|
||||
priority_queue_perform(priority_queue_default* queue, timer t) {
|
||||
while (!queue->empty() && queue->top()->time() <= t) {
|
||||
priority_item* v = queue->top();
|
||||
queue->pop();
|
||||
|
||||
v->clear_time();
|
||||
v->slot()();
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
priority_queue_insert(priority_queue_default* queue, priority_item* item, timer t) {
|
||||
if (t == timer())
|
||||
throw torrent::internal_error("priority_queue_insert(...) received a bad timer.");
|
||||
|
||||
if (!item->is_valid())
|
||||
throw torrent::internal_error("priority_queue_insert(...) called on an invalid item.");
|
||||
|
||||
if (item->is_queued())
|
||||
throw torrent::internal_error("priority_queue_insert(...) called on an already queued item.");
|
||||
|
||||
if (queue->find(item) != queue->end())
|
||||
throw torrent::internal_error("priority_queue_insert(...) item found in queue.");
|
||||
|
||||
item->set_time(t);
|
||||
queue->push(item);
|
||||
}
|
||||
|
||||
inline void
|
||||
priority_queue_erase(priority_queue_default* queue, priority_item* item) {
|
||||
if (!item->is_queued())
|
||||
return;
|
||||
|
||||
// Check is_valid() after is_queued() so that it is safe to call
|
||||
// erase on untouched instances.
|
||||
if (!item->is_valid())
|
||||
throw torrent::internal_error("priority_queue_erase(...) called on an invalid item.");
|
||||
|
||||
// Unqueue it before erasing.
|
||||
item->clear_time();
|
||||
|
||||
if (!queue->erase(item))
|
||||
throw torrent::internal_error("priority_queue_erase(...) could not find item in queue.");
|
||||
}
|
||||
|
||||
inline void
|
||||
priority_queue_update(priority_queue_default* queue, priority_item* item, timer t) {
|
||||
if (t == timer())
|
||||
throw torrent::internal_error("priority_queue_insert(...) received a bad timer.");
|
||||
|
||||
if (!item->is_valid())
|
||||
throw torrent::internal_error("priority_queue_insert(...) called on an invalid item.");
|
||||
|
||||
if (queue->find(item) == queue->end()) {
|
||||
if (item->is_queued())
|
||||
throw torrent::internal_error("priority_queue_update(...) cannot insert an already queued item.");
|
||||
|
||||
item->set_time(t);
|
||||
queue->push(item);
|
||||
|
||||
} else {
|
||||
item->set_time(t);
|
||||
queue->update();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
+2
-4
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
// This is a hacked up whole string pattern matching. Replace with
|
||||
// TR1's regex when that becomes widely available. It is intended for
|
||||
|
||||
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
// Wrappers for the various sockaddr types with focus on zero-copy
|
||||
// casting between the original type and the wrapper class.
|
||||
|
||||
+5
-7
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#ifndef RAK_STRING_MANIP_H
|
||||
#define RAK_STRING_MANIP_H
|
||||
@@ -143,8 +141,8 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator == (__UNUSED const split_iterator_t& itr) const { return m_pos == m_seq->end(); }
|
||||
bool operator != (__UNUSED const split_iterator_t& itr) const { return m_pos != m_seq->end(); }
|
||||
bool operator == (const split_iterator_t&) const { return m_pos == m_seq->end(); }
|
||||
bool operator != (const split_iterator_t&) const { return m_pos != m_seq->end(); }
|
||||
|
||||
private:
|
||||
const Sequence* m_seq;
|
||||
@@ -161,7 +159,7 @@ split_iterator(const Sequence& seq, typename Sequence::value_type delim) {
|
||||
|
||||
template <typename Sequence>
|
||||
inline split_iterator_t<Sequence>
|
||||
split_iterator(__UNUSED const Sequence& seq) {
|
||||
split_iterator(const Sequence&) {
|
||||
return split_iterator_t<Sequence>();
|
||||
}
|
||||
|
||||
|
||||
-110
@@ -1,110 +0,0 @@
|
||||
// libTorrent - BitTorrent library
|
||||
// Copyright (C) 2005-2007, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RAK_TIMER_H
|
||||
#define RAK_TIMER_H
|
||||
|
||||
#include <limits>
|
||||
#include <cinttypes>
|
||||
#include <sys/time.h>
|
||||
|
||||
namespace rak {
|
||||
|
||||
// Don't convert negative Timer to timeval and then back to Timer, that will bork.
|
||||
class timer {
|
||||
public:
|
||||
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; }
|
||||
|
||||
timer round_seconds() const { return (m_time / 1000000) * 1000000; }
|
||||
timer round_seconds_ceiling() const { return ((m_time + 1000000 - 1) / 1000000) * 1000000; }
|
||||
|
||||
timeval tval() const {
|
||||
timeval val;
|
||||
val.tv_sec = m_time / 1000000;
|
||||
val.tv_usec = m_time % 1000000;
|
||||
return val;
|
||||
}
|
||||
|
||||
static timer current();
|
||||
static int64_t current_seconds() { return current().seconds(); }
|
||||
static int64_t current_usec() { return current().usec(); }
|
||||
static timer from_minutes(uint32_t minutes) { return rak::timer((uint64_t)minutes * 60 * 1000000); }
|
||||
static timer from_seconds(uint32_t seconds) { return rak::timer((uint64_t)seconds * 1000000); }
|
||||
static timer from_milliseconds(uint32_t msec) { return rak::timer((uint64_t)msec * 1000); }
|
||||
|
||||
static timer max() { return std::numeric_limits<int64_t>::max(); }
|
||||
|
||||
bool operator < (const timer& t) const { return m_time < t.m_time; }
|
||||
bool operator > (const timer& t) const { return m_time > t.m_time; }
|
||||
bool operator <= (const timer& t) const { return m_time <= t.m_time; }
|
||||
bool operator >= (const timer& t) const { return m_time >= t.m_time; }
|
||||
bool operator == (const timer& t) const { return m_time == t.m_time; }
|
||||
bool operator != (const timer& t) const { return m_time != t.m_time; }
|
||||
|
||||
timer operator - (const timer& t) const { return timer(m_time - t.m_time); }
|
||||
timer operator + (const timer& t) const { return timer(m_time + t.m_time); }
|
||||
timer operator * (int64_t t) const { return timer(m_time * t); }
|
||||
timer operator / (int64_t t) const { return timer(m_time / t); }
|
||||
|
||||
timer operator -= (int64_t t) { m_time -= t; return *this; }
|
||||
timer operator -= (const timer& t) { m_time -= t.m_time; return *this; }
|
||||
|
||||
timer operator += (int64_t t) { m_time += t; return *this; }
|
||||
timer operator += (const timer& t) { m_time += t.m_time; return *this; }
|
||||
|
||||
private:
|
||||
int64_t m_time;
|
||||
};
|
||||
|
||||
inline timer
|
||||
timer::current() {
|
||||
timeval t;
|
||||
gettimeofday(&t, 0);
|
||||
|
||||
return timer(t);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#ifndef RAK_UNORDERED_VECTOR_H
|
||||
#define RAK_UNORDERED_VECTOR_H
|
||||
|
||||
@@ -107,25 +107,6 @@ AC_DEFUN([CC_ATTRIBUTE_NONNULL], [
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_ATTRIBUTE_UNUSED], [
|
||||
AC_CACHE_CHECK([if compiler supports __attribute__((unused))],
|
||||
[cc_cv_attribute_unused],
|
||||
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([
|
||||
void some_function(void *foo, __attribute__((unused)) void *bar);
|
||||
])],
|
||||
[cc_cv_attribute_unused=yes],
|
||||
[cc_cv_attribute_unused=no])
|
||||
])
|
||||
|
||||
if test "x$cc_cv_attribute_unused" = "xyes"; then
|
||||
AC_DEFINE([SUPPORT_ATTRIBUTE_UNUSED], 1, [Define this if the compiler supports the unused attribute])
|
||||
$1
|
||||
else
|
||||
true
|
||||
$2
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_FUNC_EXPECT], [
|
||||
AC_CACHE_CHECK([if compiler has __builtin_expect function],
|
||||
[cc_cv_func_expect],
|
||||
|
||||
@@ -88,49 +88,11 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE], [
|
||||
[
|
||||
AC_DEFINE(USE_KQUEUE, 1, Use kqueue.)
|
||||
AC_MSG_RESULT(yes)
|
||||
TORRENT_CHECK_KQUEUE_SOCKET_ONLY
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([TORRENT_CHECK_KQUEUE_SOCKET_ONLY], [
|
||||
AC_MSG_CHECKING(whether kqueue supports pipes and ptys)
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/time.h>
|
||||
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,
|
||||
|
||||
+17
-7
@@ -29,7 +29,7 @@ AC_DEFUN([TORRENT_REMOVE_UNWANTED],
|
||||
$1="$2"
|
||||
else
|
||||
result=`echo "${values_to_check}" | $GREP -Fvx -- "${unwanted_values}" | $GREP -v '^$'`
|
||||
$1=${result//$'\n'/ }
|
||||
$1=$(echo "$result" | tr -d '\n')
|
||||
fi
|
||||
])
|
||||
|
||||
@@ -117,7 +117,7 @@ AC_DEFUN([TORRENT_CHECK_MADVISE], [
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
void f() { static char test@<:@1024@:>@; madvise((void *)test, sizeof(test), MADV_NORMAL); }
|
||||
void f() { static char test@<:@1024@:>@; madvise((void *)test, sizeof(test), MADV_NORMAL); }
|
||||
])],
|
||||
[
|
||||
AC_MSG_RESULT(yes)
|
||||
@@ -127,6 +127,21 @@ AC_DEFUN([TORRENT_CHECK_MADVISE], [
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([TORRENT_CHECK_POSIX_FADVISE], [
|
||||
AC_MSG_CHECKING(for posix_fadvise)
|
||||
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
|
||||
#include <fcntl.h>
|
||||
void f() { posix_fadvise(0, 0, 0, POSIX_FADV_RANDOM); }
|
||||
])],
|
||||
[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(USE_POSIX_FADVISE, 1, Use posix_fadvise)
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([TORRENT_CHECK_POPCOUNT], [
|
||||
AC_MSG_CHECKING(for __builtin_popcount)
|
||||
|
||||
@@ -152,17 +167,12 @@ AC_DEFUN([TORRENT_CHECK_CACHELINE], [
|
||||
])],
|
||||
[
|
||||
AC_MSG_RESULT(found builtin)
|
||||
dnl AC_DEFINE(LT_SMP_CACHE_BYTES, SMP_CACHE_BYTES, Largest L1 cache size we know of, should work on all archs.)
|
||||
dnl AC_DEFINE(lt_cacheline_aligned, __cacheline_aligned, LibTorrent defined cacheline aligned.)
|
||||
|
||||
dnl Need to fix this so that it uses the stuff defined by the system.
|
||||
|
||||
AC_DEFINE(LT_SMP_CACHE_BYTES, 128, Largest L1 cache size we know of should work on all archs.)
|
||||
AC_DEFINE(lt_cacheline_aligned, __attribute__((__aligned__(LT_SMP_CACHE_BYTES))), LibTorrent defined cacheline aligned.)
|
||||
], [
|
||||
AC_MSG_RESULT(using default 128 bytes)
|
||||
AC_DEFINE(LT_SMP_CACHE_BYTES, 128, Largest L1 cache size we know of should work on all archs.)
|
||||
AC_DEFINE(lt_cacheline_aligned, __attribute__((__aligned__(LT_SMP_CACHE_BYTES))), LibTorrent defined cacheline aligned.)
|
||||
])
|
||||
])
|
||||
|
||||
|
||||
@@ -26,8 +26,6 @@ libsub_root_a_SOURCES = \
|
||||
core/http_queue.h \
|
||||
core/manager.cc \
|
||||
core/manager.h \
|
||||
core/poll_manager.cc \
|
||||
core/poll_manager.h \
|
||||
core/range_map.h \
|
||||
core/view.cc \
|
||||
core/view.h \
|
||||
@@ -200,8 +198,6 @@ libsub_root_a_SOURCES = \
|
||||
option_parser.h \
|
||||
signal_handler.cc \
|
||||
signal_handler.h \
|
||||
thread_base.cc \
|
||||
thread_base.h \
|
||||
thread_worker.cc \
|
||||
thread_worker.h
|
||||
|
||||
|
||||
+32
-26
@@ -1,5 +1,6 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <functional>
|
||||
#include <netdb.h>
|
||||
@@ -12,8 +13,6 @@
|
||||
#include <rak/regex.h>
|
||||
#include <torrent/rate.h>
|
||||
#include <torrent/throttle.h>
|
||||
#include <torrent/tracker_controller.h>
|
||||
#include <torrent/tracker_list.h>
|
||||
#include <torrent/tracker/tracker.h>
|
||||
#include <torrent/connection_manager.h>
|
||||
#include <torrent/data/download_data.h>
|
||||
@@ -308,8 +307,10 @@ apply_d_add_peer(core::Download* download, const std::string& arg) {
|
||||
if (port < 1 || port > 65535)
|
||||
throw torrent::input_error("Invalid port number.");
|
||||
|
||||
assert(std::this_thread::get_id() == torrent::main_thread::thread()->thread_id());
|
||||
|
||||
// Currently discarding SOCK_STREAM.
|
||||
torrent::main_thread()->resolver()->resolve_preferred(NULL, host, AF_UNSPEC, AF_INET, [download, port](torrent::c_sa_shared_ptr sa, int err) {
|
||||
torrent::this_thread::resolver()->resolve_preferred(NULL, host, AF_UNSPEC, AF_INET, [download, port](torrent::c_sa_shared_ptr sa, int err) {
|
||||
if (sa == nullptr) {
|
||||
lt_log_print(torrent::LOG_TORRENT_WARN, "could not resolve hostname for added peer: %s", gai_strerror(err));
|
||||
return;
|
||||
@@ -387,21 +388,24 @@ t_multicall(core::Download* download, const torrent::Object::list_type& args) {
|
||||
|
||||
// Add some pre-parsing of the commands, so we don't spend time
|
||||
// parsing and searching command map for every single call.
|
||||
torrent::Object resultRaw = torrent::Object::create_list();
|
||||
torrent::Object::list_type& result = resultRaw.as_list();
|
||||
torrent::Object result_raw = torrent::Object::create_list();
|
||||
torrent::Object::list_type& result = result_raw.as_list();
|
||||
|
||||
for (int itr = 0, last = download->tracker_list()->size(); itr != last; itr++) {
|
||||
torrent::Object::list_type& row = result.insert(result.end(), torrent::Object::create_list())->as_list();
|
||||
for (uint32_t idx = 0, last = download->tracker_list_size(); idx < last; idx++) {
|
||||
auto& row = result.insert(result.end(), torrent::Object::create_list())->as_list();
|
||||
auto tracker = download->tracker_controller().at(idx);
|
||||
|
||||
if (!tracker.is_valid())
|
||||
continue;
|
||||
|
||||
for (torrent::Object::list_const_iterator cItr = ++args.begin(); cItr != args.end(); cItr++) {
|
||||
const std::string& cmd = cItr->as_string();
|
||||
auto t = download->tracker_list()->at(itr);
|
||||
|
||||
row.push_back(rpc::parse_command(rpc::make_target(&t), cmd.c_str(), cmd.c_str() + cmd.size()).first);
|
||||
row.push_back(rpc::parse_command(rpc::make_target(&tracker), cmd.c_str(), cmd.c_str() + cmd.size()).first);
|
||||
}
|
||||
}
|
||||
|
||||
return resultRaw;
|
||||
return result_raw;
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
@@ -482,7 +486,8 @@ download_tracker_insert(core::Download* download, const torrent::Object::list_ty
|
||||
if (group < 0 || group > 32)
|
||||
throw torrent::input_error("Tracker group number invalid.");
|
||||
|
||||
download->download()->tracker_list()->insert_url(group, args.back().as_string(), true);
|
||||
download->tracker_controller().add_extra_tracker(group, args.back().as_string());
|
||||
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
@@ -542,19 +547,20 @@ download_set_variable_string(core::Download* download, const torrent::Object::st
|
||||
//
|
||||
|
||||
torrent::Object
|
||||
d_list_push_back(core::Download* download, const torrent::Object& rawArgs, const char* first_key, const char* second_key) {
|
||||
download_get_variable(download, first_key, second_key).as_list().push_back(rawArgs);
|
||||
d_list_push_back_string(core::Download* download, const torrent::Object& rawArgs, const char* first_key, const char* second_key) {
|
||||
auto& arg = rawArgs.as_string();
|
||||
download_get_variable(download, first_key, second_key).as_list().push_back(arg);
|
||||
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
d_list_push_back_unique(core::Download* download, const torrent::Object& rawArgs, const char* first_key, const char* second_key) {
|
||||
const torrent::Object& args = (rawArgs.is_list() && !rawArgs.as_list().empty()) ? rawArgs.as_list().front() : rawArgs;
|
||||
d_list_push_back_unique_string(core::Download* download, const torrent::Object& rawArgs, const char* first_key, const char* second_key) {
|
||||
auto& arg = rawArgs.as_string();
|
||||
torrent::Object::list_type& list = download_get_variable(download, first_key, second_key).as_list();
|
||||
|
||||
if (std::find_if(list.begin(), list.end(), [args](const torrent::Object& obj) { return torrent::object_equal(obj, args); }) == list.end())
|
||||
list.push_back(rawArgs);
|
||||
if (std::none_of(list.begin(), list.end(), [arg](const torrent::Object& obj) { return torrent::object_equal(obj, arg); }))
|
||||
list.push_back(arg);
|
||||
|
||||
return torrent::Object();
|
||||
}
|
||||
@@ -564,7 +570,7 @@ d_list_has(core::Download* download, const torrent::Object& rawArgs, const char*
|
||||
const torrent::Object& args = (rawArgs.is_list() && !rawArgs.as_list().empty()) ? rawArgs.as_list().front() : rawArgs;
|
||||
torrent::Object::list_type& list = download_get_variable(download, first_key, second_key).as_list();
|
||||
|
||||
return (int64_t)(std::find_if(list.begin(), list.end(), [args](const torrent::Object& obj) { return torrent::object_equal(obj, args); }) != list.end());
|
||||
return (int64_t)(std::any_of(list.begin(), list.end(), [args](const auto& obj) { return torrent::object_equal(obj, args); }));
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
@@ -586,7 +592,7 @@ d_list_remove(core::Download* download, const torrent::Object& rawArgs, const ch
|
||||
#define CMD2_BIND_CL std::bind(&core::Download::connection_list, std::placeholders::_1)
|
||||
#define CMD2_BIND_FL std::bind(&core::Download::file_list, std::placeholders::_1)
|
||||
#define CMD2_BIND_PL std::bind(&core::Download::c_peer_list, std::placeholders::_1)
|
||||
#define CMD2_BIND_TL std::bind(&core::Download::tracker_list, std::placeholders::_1)
|
||||
#define CMD2_BIND_TC std::bind(&core::Download::tracker_controller, std::placeholders::_1)
|
||||
|
||||
#define CMD2_BIND_INFO std::bind(&core::Download::info, std::placeholders::_1)
|
||||
#define CMD2_BIND_DATA std::bind(&core::Download::data, std::placeholders::_1)
|
||||
@@ -771,8 +777,8 @@ initialize_command_download() {
|
||||
CMD2_DL ("d.views", std::bind(&download_get_variable, std::placeholders::_1, "rtorrent", "views"));
|
||||
CMD2_DL ("d.views.has", std::bind(&d_list_has, std::placeholders::_1, std::placeholders::_2, "rtorrent", "views"));
|
||||
CMD2_DL ("d.views.remove", std::bind(&d_list_remove, std::placeholders::_1, std::placeholders::_2, "rtorrent", "views"));
|
||||
CMD2_DL ("d.views.push_back", std::bind(&d_list_push_back, std::placeholders::_1, std::placeholders::_2, "rtorrent", "views"));
|
||||
CMD2_DL ("d.views.push_back_unique", std::bind(&d_list_push_back_unique, std::placeholders::_1, std::placeholders::_2, "rtorrent", "views"));
|
||||
CMD2_DL ("d.views.push_back", std::bind(&d_list_push_back_string, std::placeholders::_1, std::placeholders::_2, "rtorrent", "views"));
|
||||
CMD2_DL ("d.views.push_back_unique", std::bind(&d_list_push_back_unique_string, std::placeholders::_1, std::placeholders::_2, "rtorrent", "views"));
|
||||
|
||||
// This command really needs to be improved, so we have proper
|
||||
// logging support.
|
||||
@@ -833,15 +839,15 @@ initialize_command_download() {
|
||||
CMD2_DL_V ("d.tracker_announce", std::bind(&torrent::Download::manual_request, CMD2_BIND_DL, false));
|
||||
CMD2_DL_V ("d.tracker_announce.force", std::bind(&torrent::Download::manual_request, CMD2_BIND_DL, true));
|
||||
|
||||
CMD2_DL ("d.tracker_numwant", std::bind(&torrent::TrackerList::numwant, CMD2_BIND_TL));
|
||||
CMD2_DL_VALUE_V ("d.tracker_numwant.set", std::bind(&torrent::TrackerList::set_numwant, CMD2_BIND_TL, std::placeholders::_2));
|
||||
CMD2_DL ("d.tracker_numwant", std::bind(&torrent::tracker::TrackerControllerWrapper::numwant, CMD2_BIND_TC));
|
||||
CMD2_DL_VALUE_V ("d.tracker_numwant.set", std::bind(&torrent::tracker::TrackerControllerWrapper::set_numwant, CMD2_BIND_TC, std::placeholders::_2));
|
||||
// TODO: Deprecate 'd.tracker_focus'.
|
||||
CMD2_DL ("d.tracker_focus", std::bind(&core::Download::tracker_list_size, std::placeholders::_1));
|
||||
CMD2_DL ("d.tracker_size", std::bind(&core::Download::tracker_list_size, std::placeholders::_1));
|
||||
|
||||
CMD2_DL ("d.tracker.has_active", std::bind(&torrent::TrackerList::has_active, CMD2_BIND_TL));
|
||||
CMD2_DL ("d.tracker.has_active_not_scrape", std::bind(&torrent::TrackerList::has_active_not_scrape, CMD2_BIND_TL));
|
||||
CMD2_DL ("d.tracker.has_usable", std::bind(&torrent::TrackerList::has_usable, CMD2_BIND_TL));
|
||||
CMD2_DL ("d.tracker.has_active", std::bind(&torrent::tracker::TrackerControllerWrapper::has_active_trackers, CMD2_BIND_TC));
|
||||
CMD2_DL ("d.tracker.has_active_not_scrape", std::bind(&torrent::tracker::TrackerControllerWrapper::has_active_trackers_not_scrape, CMD2_BIND_TC));
|
||||
CMD2_DL ("d.tracker.has_usable", std::bind(&torrent::tracker::TrackerControllerWrapper::has_usable_trackers, CMD2_BIND_TC));
|
||||
CMD2_DL_LIST ("d.tracker.insert", std::bind(&download_tracker_insert, std::placeholders::_1, std::placeholders::_2));
|
||||
CMD2_DL_VALUE_V ("d.tracker.send_scrape", [](auto download, uint64_t arg) { download->tracker_controller().scrape_request(arg); });
|
||||
|
||||
|
||||
+5
-40
@@ -1,39 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -443,12 +407,13 @@ cmd_catch(rpc::target_type target, const torrent::Object& args) {
|
||||
void
|
||||
initialize_command_dynamic() {
|
||||
// clang-format off
|
||||
#ifdef HAVE_XMLRPC_TINYXML2
|
||||
#ifdef HAVE_XMLRPC_TINYXML2
|
||||
CMD2_ANY ("system.listMethods", std::bind(&system_listMethods)); // only used by tinyxml2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
CMD2_VAR_BOOL ("method.use_deprecated", true);
|
||||
CMD2_VAR_VALUE ("method.use_intermediate", 1);
|
||||
// Keep these for future use when we deprecate more commands.
|
||||
CMD2_VAR_BOOL ("method.use_deprecated", false);
|
||||
CMD2_VAR_VALUE ("method.use_intermediate", 0);
|
||||
|
||||
CMD2_ANY_LIST ("method.insert", std::bind(&system_method_insert, std::placeholders::_2));
|
||||
CMD2_ANY_LIST ("method.insert.value", std::bind(&system_method_insert_object, std::placeholders::_2, rpc::object_storage::flag_value_type));
|
||||
|
||||
+56
-70
@@ -11,6 +11,9 @@
|
||||
#include <torrent/utils/log.h>
|
||||
#include <torrent/utils/directory_events.h>
|
||||
|
||||
#include "globals.h"
|
||||
#include "control.h"
|
||||
#include "command_helpers.h"
|
||||
#include "core/download.h"
|
||||
#include "core/download_list.h"
|
||||
#include "core/manager.h"
|
||||
@@ -19,74 +22,55 @@
|
||||
#include "rpc/parse.h"
|
||||
#include "rpc/parse_commands.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "control.h"
|
||||
#include "command_helpers.h"
|
||||
|
||||
#include "thread_worker.h"
|
||||
|
||||
torrent::Object
|
||||
apply_on_ratio(const torrent::Object& rawArgs) {
|
||||
const std::string& groupName = rawArgs.as_string();
|
||||
auto& group_name = rawArgs.as_string();
|
||||
auto view_itr = control->view_manager()->find(rpc::commands.call("group2." + group_name + ".view", rpc::make_target()).as_string());
|
||||
|
||||
char buffer[32 + groupName.size()];
|
||||
snprintf(buffer, sizeof(buffer), "group2.%s.view", groupName.c_str());
|
||||
|
||||
core::ViewManager::iterator viewItr = control->view_manager()->find(rpc::commands.call(buffer, rpc::make_target()).as_string());
|
||||
|
||||
if (viewItr == control->view_manager()->end())
|
||||
if (view_itr == control->view_manager()->end())
|
||||
throw torrent::input_error("Could not find view.");
|
||||
|
||||
char* bufferStart = buffer + snprintf(buffer, sizeof(buffer), "group2.%s.ratio.", groupName.c_str());
|
||||
|
||||
// first argument: minimum ratio to reach
|
||||
// second argument: minimum upload amount to reach [optional]
|
||||
// third argument: maximum ratio to reach [optional]
|
||||
std::strcpy(bufferStart, "min");
|
||||
int64_t minRatio = rpc::commands.call(buffer, rpc::make_target()).as_value();
|
||||
std::strcpy(bufferStart, "max");
|
||||
int64_t maxRatio = rpc::commands.call(buffer, rpc::make_target()).as_value();
|
||||
std::strcpy(bufferStart, "upload");
|
||||
int64_t minUpload = rpc::commands.call(buffer, rpc::make_target()).as_value();
|
||||
int64_t min_ratio = rpc::commands.call("group2." + group_name + ".ratio.min", rpc::make_target()).as_value();
|
||||
int64_t max_ratio = rpc::commands.call("group2." + group_name + ".ratio.max", rpc::make_target()).as_value();
|
||||
int64_t min_upload = rpc::commands.call("group2." + group_name + ".ratio.upload", rpc::make_target()).as_value();
|
||||
|
||||
std::vector<core::Download*> downloads;
|
||||
|
||||
for (core::View::iterator itr = (*viewItr)->begin_visible(), last = (*viewItr)->end_visible(); itr != last; itr++) {
|
||||
for (auto itr = (*view_itr)->begin_visible(), last = (*view_itr)->end_visible(); itr != last; itr++) {
|
||||
if (!(*itr)->is_seeding() || rpc::call_command_value("d.ignore_commands", rpc::make_target(*itr)) != 0)
|
||||
continue;
|
||||
|
||||
// rpc::parse_command_single(rpc::make_target(*itr), "print={Checked ratio of download.}");
|
||||
int64_t total_done = (*itr)->download()->bytes_done();
|
||||
int64_t total_upload = (*itr)->info()->up_rate()->total();
|
||||
|
||||
int64_t totalDone = (*itr)->download()->bytes_done();
|
||||
int64_t totalUpload = (*itr)->info()->up_rate()->total();
|
||||
|
||||
if (!(totalUpload >= minUpload && totalUpload * 100 >= totalDone * minRatio) &&
|
||||
!(maxRatio > 0 && totalUpload * 100 > totalDone * maxRatio))
|
||||
if (!(total_upload >= min_upload && total_upload * 100 >= total_done * min_ratio) &&
|
||||
!(max_ratio > 0 && total_upload * 100 > total_done * max_ratio))
|
||||
continue;
|
||||
|
||||
downloads.push_back(*itr);
|
||||
}
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "group.%s.ratio.command", groupName.c_str());
|
||||
auto ratio_command = "group." + group_name + ".ratio.command";
|
||||
|
||||
for (std::vector<core::Download*>::iterator itr = downloads.begin(), last = downloads.end(); itr != last; itr++) {
|
||||
// rpc::commands.call("print", rpc::make_target(*itr), "Calling ratio command.");
|
||||
rpc::commands.call_catch(buffer, rpc::make_target(*itr), torrent::Object(), "Ratio reached, but command failed: ");
|
||||
}
|
||||
for (std::vector<core::Download*>::iterator itr = downloads.begin(), last = downloads.end(); itr != last; itr++)
|
||||
rpc::commands.call_catch(ratio_command, rpc::make_target(*itr), torrent::Object(), "Ratio reached, but command failed: ");
|
||||
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
apply_start_tied() {
|
||||
for (core::DownloadList::iterator itr = control->core()->download_list()->begin(); itr != control->core()->download_list()->end(); ++itr) {
|
||||
for (auto itr = control->core()->download_list()->begin(); itr != control->core()->download_list()->end(); ++itr) {
|
||||
if (rpc::call_command_value("d.state", rpc::make_target(*itr)) == 1)
|
||||
continue;
|
||||
|
||||
rak::file_stat fs;
|
||||
const std::string& tiedToFile = rpc::call_command_string("d.tied_to_file", rpc::make_target(*itr));
|
||||
const std::string& tied_to_file = rpc::call_command_string("d.tied_to_file", rpc::make_target(*itr));
|
||||
|
||||
if (!tiedToFile.empty() && fs.update(rak::path_expand(tiedToFile)))
|
||||
if (!tied_to_file.empty() && fs.update(rak::path_expand(tied_to_file)))
|
||||
rpc::parse_command_single(rpc::make_target(*itr), "d.try_start=");
|
||||
}
|
||||
|
||||
@@ -95,14 +79,14 @@ apply_start_tied() {
|
||||
|
||||
torrent::Object
|
||||
apply_stop_untied() {
|
||||
for (core::DownloadList::iterator itr = control->core()->download_list()->begin(); itr != control->core()->download_list()->end(); ++itr) {
|
||||
for (auto itr = control->core()->download_list()->begin(); itr != control->core()->download_list()->end(); ++itr) {
|
||||
if (rpc::call_command_value("d.state", rpc::make_target(*itr)) == 0)
|
||||
continue;
|
||||
|
||||
rak::file_stat fs;
|
||||
const std::string& tiedToFile = rpc::call_command_string("d.tied_to_file", rpc::make_target(*itr));
|
||||
const std::string& tied_to_file = rpc::call_command_string("d.tied_to_file", rpc::make_target(*itr));
|
||||
|
||||
if (!tiedToFile.empty() && !fs.update(rak::path_expand(tiedToFile)))
|
||||
if (!tied_to_file.empty() && !fs.update(rak::path_expand(tied_to_file)))
|
||||
rpc::parse_command_single(rpc::make_target(*itr), "d.try_stop=");
|
||||
}
|
||||
|
||||
@@ -111,11 +95,11 @@ apply_stop_untied() {
|
||||
|
||||
torrent::Object
|
||||
apply_close_untied() {
|
||||
for (core::DownloadList::iterator itr = control->core()->download_list()->begin(); itr != control->core()->download_list()->end(); ++itr) {
|
||||
for (auto itr = control->core()->download_list()->begin(); itr != control->core()->download_list()->end(); ++itr) {
|
||||
rak::file_stat fs;
|
||||
const std::string& tiedToFile = rpc::call_command_string("d.tied_to_file", rpc::make_target(*itr));
|
||||
const std::string& tied_to_file = rpc::call_command_string("d.tied_to_file", rpc::make_target(*itr));
|
||||
|
||||
if (rpc::call_command_value("d.ignore_commands", rpc::make_target(*itr)) == 0 && !tiedToFile.empty() && !fs.update(rak::path_expand(tiedToFile)))
|
||||
if (rpc::call_command_value("d.ignore_commands", rpc::make_target(*itr)) == 0 && !tied_to_file.empty() && !fs.update(rak::path_expand(tied_to_file)))
|
||||
rpc::parse_command_single(rpc::make_target(*itr), "d.try_close=");
|
||||
}
|
||||
|
||||
@@ -124,11 +108,11 @@ apply_close_untied() {
|
||||
|
||||
torrent::Object
|
||||
apply_remove_untied() {
|
||||
for (core::DownloadList::iterator itr = control->core()->download_list()->begin(); itr != control->core()->download_list()->end(); ) {
|
||||
for (auto itr = control->core()->download_list()->begin(); itr != control->core()->download_list()->end(); ) {
|
||||
rak::file_stat fs;
|
||||
const std::string& tiedToFile = rpc::call_command_string("d.tied_to_file", rpc::make_target(*itr));
|
||||
const std::string& tied_to_file = rpc::call_command_string("d.tied_to_file", rpc::make_target(*itr));
|
||||
|
||||
if (!tiedToFile.empty() && !fs.update(rak::path_expand(tiedToFile))) {
|
||||
if (!tied_to_file.empty() && !fs.update(rak::path_expand(tied_to_file))) {
|
||||
// Need to clear tied_to_file so it doesn't try to delete it.
|
||||
rpc::call_command("d.tied_to_file.set", std::string(), rpc::make_target(*itr));
|
||||
|
||||
@@ -149,9 +133,9 @@ apply_schedule(const torrent::Object::list_type& args) {
|
||||
|
||||
torrent::Object::list_const_iterator itr = args.begin();
|
||||
|
||||
const std::string& arg1 = (itr++)->as_string();
|
||||
const std::string& arg2 = (itr++)->as_string();
|
||||
const std::string& arg3 = (itr++)->as_string();
|
||||
auto& arg1 = (itr++)->as_string();
|
||||
auto& arg2 = (itr++)->as_string();
|
||||
auto& arg3 = (itr++)->as_string();
|
||||
|
||||
control->command_scheduler()->parse(arg1, arg2, arg3, *itr);
|
||||
|
||||
@@ -165,7 +149,7 @@ apply_load(const torrent::Object::list_type& args, int flags) {
|
||||
if (argsItr == args.end())
|
||||
throw torrent::input_error("Too few arguments.");
|
||||
|
||||
const std::string& filename = argsItr->as_string();
|
||||
auto& filename = argsItr->as_string();
|
||||
core::Manager::command_list_type commands;
|
||||
|
||||
while (++argsItr != args.end())
|
||||
@@ -210,20 +194,20 @@ apply_download_list(const torrent::Object::list_type& args) {
|
||||
torrent::Object::list_const_iterator argsItr = args.begin();
|
||||
|
||||
core::ViewManager* viewManager = control->view_manager();
|
||||
core::ViewManager::iterator viewItr;
|
||||
core::ViewManager::iterator view_itr;
|
||||
|
||||
if (argsItr != args.end() && !argsItr->as_string().empty())
|
||||
viewItr = viewManager->find((argsItr++)->as_string());
|
||||
view_itr = viewManager->find((argsItr++)->as_string());
|
||||
else
|
||||
viewItr = viewManager->find("default");
|
||||
view_itr = viewManager->find("default");
|
||||
|
||||
if (viewItr == viewManager->end())
|
||||
if (view_itr == viewManager->end())
|
||||
throw torrent::input_error("Could not find view.");
|
||||
|
||||
torrent::Object result = torrent::Object::create_list();
|
||||
torrent::Object::list_type& resultList = result.as_list();
|
||||
|
||||
for (core::View::const_iterator itr = (*viewItr)->begin_visible(), last = (*viewItr)->end_visible(); itr != last; itr++) {
|
||||
for (core::View::const_iterator itr = (*view_itr)->begin_visible(), last = (*view_itr)->end_visible(); itr != last; itr++) {
|
||||
const torrent::HashString* hashString = &(*itr)->info()->hash();
|
||||
|
||||
resultList.push_back(rak::transform_hex(hashString->begin(), hashString->end()));
|
||||
@@ -238,32 +222,31 @@ d_multicall(const torrent::Object::list_type& args) {
|
||||
throw torrent::input_error("Too few arguments.");
|
||||
|
||||
core::ViewManager* viewManager = control->view_manager();
|
||||
core::ViewManager::iterator viewItr;
|
||||
core::ViewManager::iterator view_itr;
|
||||
|
||||
if (!args.front().as_string().empty())
|
||||
viewItr = viewManager->find(args.front().as_string());
|
||||
view_itr = viewManager->find(args.front().as_string());
|
||||
else
|
||||
viewItr = viewManager->find("default");
|
||||
view_itr = viewManager->find("default");
|
||||
|
||||
if (viewItr == viewManager->end())
|
||||
if (view_itr == viewManager->end())
|
||||
throw torrent::input_error("Could not find view.");
|
||||
|
||||
// Add some pre-parsing of the commands, so we don't spend time
|
||||
// parsing and searching command map for every single call.
|
||||
unsigned int dlist_size = (*viewItr)->size_visible();
|
||||
core::Download* dlist[dlist_size];
|
||||
std::vector<core::Download*> dlist((*view_itr)->size_visible());
|
||||
|
||||
std::copy((*viewItr)->begin_visible(), (*viewItr)->end_visible(), dlist);
|
||||
std::copy((*view_itr)->begin_visible(), (*view_itr)->end_visible(), dlist.data());
|
||||
|
||||
torrent::Object resultRaw = torrent::Object::create_list();
|
||||
torrent::Object::list_type& result = resultRaw.as_list();
|
||||
|
||||
for (core::Download** vItr = dlist; vItr != dlist + dlist_size; vItr++) {
|
||||
for (auto download : dlist) {
|
||||
torrent::Object::list_type& row = result.insert(result.end(), torrent::Object::create_list())->as_list();
|
||||
|
||||
for (torrent::Object::list_const_iterator cItr = ++args.begin(); cItr != args.end(); cItr++) {
|
||||
const std::string& cmd = cItr->as_string();
|
||||
row.push_back(rpc::parse_command(rpc::make_target(*vItr), cmd.c_str(), cmd.c_str() + cmd.size()).first);
|
||||
auto& cmd = cItr->as_string();
|
||||
row.push_back(rpc::parse_command(rpc::make_target(download), cmd.c_str(), cmd.c_str() + cmd.size()).first);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,14 +261,14 @@ d_multicall_filtered(const torrent::Object::list_type& args) {
|
||||
|
||||
// Find the given view
|
||||
core::ViewManager* viewManager = control->view_manager();
|
||||
core::ViewManager::iterator viewItr = viewManager->find(arg->as_string().empty() ? "default" : arg->as_string());
|
||||
core::ViewManager::iterator view_itr = viewManager->find(arg->as_string().empty() ? "default" : arg->as_string());
|
||||
|
||||
if (viewItr == viewManager->end())
|
||||
if (view_itr == viewManager->end())
|
||||
throw torrent::input_error("Could not find view '" + arg->as_string() + "'.");
|
||||
|
||||
// Make a filtered copy of the current item list
|
||||
core::View::base_type dlist;
|
||||
(*viewItr)->filter_by(*++arg, dlist);
|
||||
(*view_itr)->filter_by(*++arg, dlist);
|
||||
|
||||
// Generate result by iterating over all items
|
||||
torrent::Object resultRaw = torrent::Object::create_list();
|
||||
@@ -298,7 +281,7 @@ d_multicall_filtered(const torrent::Object::list_type& args) {
|
||||
|
||||
// Call the provided commands and assemble their results
|
||||
for (torrent::Object::list_const_iterator command = arg; command != args.end(); command++) {
|
||||
const std::string& cmdstr = command->as_string();
|
||||
auto& cmdstr = command->as_string();
|
||||
row.push_back(rpc::parse_command(rpc::make_target(*item), cmdstr.c_str(), cmdstr.c_str() + cmdstr.size()).first);
|
||||
}
|
||||
}
|
||||
@@ -316,8 +299,8 @@ directory_watch_added(const torrent::Object::list_type& args) {
|
||||
if (args.size() != 2)
|
||||
throw torrent::input_error("Too few arguments.");
|
||||
|
||||
const std::string& path = args.front().as_string();
|
||||
const std::string& command = args.back().as_string();
|
||||
auto& path = args.front().as_string();
|
||||
auto& command = args.back().as_string();
|
||||
|
||||
if (!control->directory_events()->open())
|
||||
throw torrent::input_error("Could not open inotify:" + std::string(rak::error_number::current().c_str()));
|
||||
@@ -337,7 +320,10 @@ initialize_command_events() {
|
||||
CMD2_ANY ("close_untied", std::bind(&apply_close_untied));
|
||||
CMD2_ANY ("remove_untied", std::bind(&apply_remove_untied));
|
||||
|
||||
// TODO: Deprecate schedule2 in the future.
|
||||
CMD2_ANY_LIST ("schedule", std::bind(&apply_schedule, std::placeholders::_2));
|
||||
CMD2_ANY_LIST ("schedule2", std::bind(&apply_schedule, std::placeholders::_2));
|
||||
CMD2_ANY_STRING_V("schedule.remove", std::bind(&rpc::CommandScheduler::erase_str, control->command_scheduler(), std::placeholders::_2));
|
||||
CMD2_ANY_STRING_V("schedule_remove2", std::bind(&rpc::CommandScheduler::erase_str, control->command_scheduler(), std::placeholders::_2));
|
||||
|
||||
CMD2_ANY_STRING_V("import", std::bind(&apply_import, std::placeholders::_2));
|
||||
|
||||
+3
-5
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
@@ -53,7 +51,7 @@ apply_f_set_priority(torrent::File* file, uint32_t value) {
|
||||
if (value > torrent::PRIORITY_HIGH)
|
||||
throw torrent::input_error("Invalid value.");
|
||||
|
||||
file->set_priority((torrent::priority_t)value);
|
||||
file->set_priority(static_cast<torrent::priority_enum>(value));
|
||||
}
|
||||
|
||||
// TODO: Redundant.
|
||||
|
||||
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
+2
-4
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
+17
-8
@@ -220,9 +220,11 @@ initialize_command_local() {
|
||||
CMD2_VAR_LIST ("file.prioritize_toc.first");
|
||||
CMD2_VAR_LIST ("file.prioritize_toc.last");
|
||||
|
||||
CMD2_ANY ("system.files.advise_random", std::bind(&FM_t::advise_random, fileManager));
|
||||
CMD2_ANY_VALUE_V ("system.files.advise_random.set", std::bind(&FM_t::set_advise_random, fileManager, std::placeholders::_2));
|
||||
CMD2_VAR_BOOL ("system.files.session.fdatasync", true);
|
||||
CMD2_ANY ("system.files.advise_random", std::bind(&FM_t::advise_random, fileManager));
|
||||
CMD2_ANY_VALUE_V ("system.files.advise_random.set", std::bind(&FM_t::set_advise_random, fileManager, std::placeholders::_2));
|
||||
CMD2_ANY ("system.files.advise_random.hashing", std::bind(&FM_t::advise_random_hashing, fileManager));
|
||||
CMD2_ANY_VALUE_V ("system.files.advise_random.hashing.set", std::bind(&FM_t::set_advise_random_hashing, fileManager, std::placeholders::_2));
|
||||
CMD2_VAR_BOOL ("system.files.session.fdatasync", true);
|
||||
|
||||
CMD2_ANY ("system.files.opened_counter", std::bind(&FM_t::files_opened_counter, fileManager));
|
||||
CMD2_ANY ("system.files.closed_counter", std::bind(&FM_t::files_closed_counter, fileManager));
|
||||
@@ -230,9 +232,15 @@ initialize_command_local() {
|
||||
|
||||
CMD2_ANY_STRING ("system.env", std::bind(&system_env, std::placeholders::_2));
|
||||
|
||||
CMD2_ANY ("system.time", std::bind(&rak::timer::seconds, &cachedTime));
|
||||
CMD2_ANY ("system.time_seconds", std::bind(&rak::timer::current_seconds));
|
||||
CMD2_ANY ("system.time_usec", std::bind(&rak::timer::current_usec));
|
||||
CMD2_ANY ("system.time", []([[maybe_unused]] auto t, [[maybe_unused]] auto o) -> torrent::Object {
|
||||
return torrent::this_thread::cached_seconds().count();
|
||||
});
|
||||
CMD2_ANY ("system.time_seconds", []([[maybe_unused]] auto t, [[maybe_unused]] auto o) -> torrent::Object {
|
||||
return torrent::utils::cast_seconds(torrent::utils::time_since_epoch()).count();
|
||||
});
|
||||
CMD2_ANY ("system.time_usec", []([[maybe_unused]] auto t, [[maybe_unused]] auto o) -> torrent::Object {
|
||||
return torrent::utils::time_since_epoch().count();
|
||||
});
|
||||
|
||||
CMD2_ANY_VALUE_V ("system.umask.set", std::bind(&umask, std::placeholders::_2));
|
||||
|
||||
@@ -271,7 +279,7 @@ initialize_command_local() {
|
||||
|
||||
CMD2_ANY ("pieces.stats.total_size", std::bind(&apply_pieces_stats_total_size));
|
||||
|
||||
CMD2_ANY ("pieces.hash.queue_size", std::bind(&torrent::hash_queue_size));
|
||||
CMD2_ANY ("pieces.hash.queue_size", std::bind(&torrent::main_thread::hash_queue_size));
|
||||
CMD2_VAR_BOOL ("pieces.hash.on_completion", true);
|
||||
|
||||
CMD2_VAR_STRING ("directory.default", "./");
|
||||
@@ -292,9 +300,10 @@ initialize_command_local() {
|
||||
CMD2_ANY ("lua.execute.str", std::bind(&rpc::execute_lua, lua_engine, std::placeholders::_1, std::placeholders::_2, rpc::LuaEngine::flag_string));
|
||||
#endif
|
||||
|
||||
#define CMD2_EXECUTE(key, flags) \
|
||||
#define CMD2_EXECUTE(key, flags) \
|
||||
CMD2_ANY(key, std::bind(&rpc::ExecFile::execute_object, &rpc::execFile, std::placeholders::_2, flags));
|
||||
|
||||
CMD2_EXECUTE ("execute", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_throw);
|
||||
CMD2_EXECUTE ("execute2", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_throw);
|
||||
CMD2_EXECUTE ("execute.throw", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_throw);
|
||||
CMD2_EXECUTE ("execute.throw.bg", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_throw | rpc::ExecFile::flag_background);
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <rak/address_info.h>
|
||||
#include <rak/path.h>
|
||||
#include <torrent/connection_manager.h>
|
||||
#include <torrent/tracker_list.h>
|
||||
#include <torrent/tracker/tracker.h>
|
||||
#include <torrent/torrent.h>
|
||||
#include <torrent/rate.h>
|
||||
@@ -15,6 +14,7 @@
|
||||
#include <torrent/utils/log.h>
|
||||
#include <torrent/utils/option_strings.h>
|
||||
|
||||
#include "core/curl_stack.h"
|
||||
#include "core/download.h"
|
||||
#include "core/manager.h"
|
||||
#include "rpc/scgi.h"
|
||||
@@ -72,10 +72,12 @@ initialize_rpc() {
|
||||
return (*d->file_list())[index].get();
|
||||
};
|
||||
rpc::rpc.slot_find_tracker() = [](core::Download* d, uint32_t index) -> torrent::tracker::Tracker {
|
||||
if (index >= d->tracker_list()->size())
|
||||
if (index >= d->tracker_controller().size())
|
||||
throw torrent::input_error("invalid parameters: index not found");
|
||||
|
||||
return d->tracker_list()->at(index);
|
||||
// TODO: This should be rewritten to check if the tracker is valid and use a different
|
||||
// function.
|
||||
return d->tracker_controller().at(index);
|
||||
};
|
||||
rpc::rpc.slot_find_peer() = [](core::Download* d, const torrent::HashString& hash) -> torrent::Peer* {
|
||||
auto itr = d->connection_list()->find(hash.c_str());
|
||||
|
||||
+2
-4
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
@@ -1,39 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -52,7 +16,7 @@ torrent::Object
|
||||
cmd_scheduler_simple_added(core::Download* download) {
|
||||
unsigned int numActive = (*control->view_manager()->find("active"))->size_visible();
|
||||
int64_t maxActive = rpc::call_command("scheduler.max_active", torrent::Object()).as_value();
|
||||
|
||||
|
||||
if (numActive < (uint64_t)maxActive)
|
||||
control->core()->download_list()->resume(download);
|
||||
|
||||
@@ -83,7 +47,7 @@ cmd_scheduler_simple_removed(core::Download* download) {
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
cmd_scheduler_simple_update(core::Download* download) {
|
||||
cmd_scheduler_simple_update([[maybe_unused]] core::Download* download) {
|
||||
core::View* viewActive = *control->view_manager()->find("active");
|
||||
core::View* viewStarted = *control->view_manager()->find("started");
|
||||
|
||||
@@ -91,7 +55,6 @@ cmd_scheduler_simple_update(core::Download* download) {
|
||||
uint64_t maxActive = rpc::call_command("scheduler.max_active", torrent::Object()).as_value();
|
||||
|
||||
if (viewActive->size_visible() < maxActive) {
|
||||
|
||||
for (core::View::iterator itr = viewStarted->begin_visible(), last = viewStarted->end_visible(); itr != last; itr++) {
|
||||
if ((*itr)->is_active())
|
||||
continue;
|
||||
@@ -102,8 +65,7 @@ cmd_scheduler_simple_update(core::Download* download) {
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (viewActive->size_visible() > maxActive) {
|
||||
|
||||
} else {
|
||||
while (viewActive->size_visible() > maxActive)
|
||||
control->core()->download_list()->pause(*viewActive->begin_visible());
|
||||
}
|
||||
|
||||
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
+20
-5
@@ -1,5 +1,6 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <netdb.h>
|
||||
#include <rak/address_info.h>
|
||||
@@ -44,8 +45,10 @@ apply_dht_add_node(const std::string& arg) {
|
||||
if (port < 1 || port > 65535)
|
||||
throw torrent::input_error("Invalid port number.");
|
||||
|
||||
assert(std::this_thread::get_id() == torrent::main_thread::thread()->thread_id());
|
||||
|
||||
// Currently discarding SOCK_STREAM.
|
||||
torrent::main_thread()->resolver()->resolve_specific(nullptr, host, PF_INET, [port](torrent::c_sa_shared_ptr sa, int err) {
|
||||
torrent::this_thread::resolver()->resolve_specific(nullptr, host, PF_INET, [port](torrent::c_sa_shared_ptr sa, int err) {
|
||||
if (sa == nullptr) {
|
||||
lt_log_print(torrent::LOG_DHT_WARN, "Could not resolve host: %s", gai_strerror(err));
|
||||
return;
|
||||
@@ -59,11 +62,23 @@ apply_dht_add_node(const std::string& arg) {
|
||||
|
||||
torrent::Object
|
||||
apply_enable_trackers(int64_t arg) {
|
||||
for (core::Manager::DListItr itr = control->core()->download_list()->begin(), last = control->core()->download_list()->end(); itr != last; ++itr) {
|
||||
std::for_each((*itr)->tracker_list()->begin(), (*itr)->tracker_list()->end(), std::mem_fn(arg ? &torrent::tracker::Tracker::enable : &torrent::tracker::Tracker::disable));
|
||||
if (arg == 0) {
|
||||
for (auto itr : *control->core()->download_list())
|
||||
itr->tracker_controller().for_each([](auto& tracker) { tracker.disable(); });
|
||||
|
||||
if (arg && !rpc::call_command_value("trackers.use_udp"))
|
||||
(*itr)->enable_udp_trackers(false);
|
||||
} else if (rpc::call_command_value("trackers.use_udp") == 0) {
|
||||
for (auto itr : *control->core()->download_list()) {
|
||||
itr->tracker_controller().for_each([](auto& tracker) {
|
||||
if (tracker.type() == torrent::TRACKER_UDP)
|
||||
tracker.disable();
|
||||
else
|
||||
tracker.enable();
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
for (auto itr : *control->core()->download_list())
|
||||
itr->tracker_controller().for_each([](auto& tracker) { tracker.enable(); });
|
||||
}
|
||||
|
||||
return torrent::Object();
|
||||
|
||||
+12
-5
@@ -4,7 +4,6 @@
|
||||
|
||||
#include <ctime>
|
||||
#include <regex>
|
||||
|
||||
#include <rak/algorithm.h>
|
||||
#include <torrent/utils/log.h>
|
||||
|
||||
@@ -95,7 +94,8 @@ apply_view_set(const torrent::Object::list_type& args) {
|
||||
// if (args.front().as_string() == "main")
|
||||
// control->ui()->download_list()->set_view(*itr);
|
||||
// else
|
||||
throw torrent::input_error("No such target.");
|
||||
|
||||
throw torrent::input_error("No such target.");
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
@@ -407,7 +407,9 @@ apply_to_time(const torrent::Object& rawArgs, int flags) {
|
||||
|
||||
torrent::Object
|
||||
apply_to_elapsed_time(const torrent::Object& rawArgs) {
|
||||
uint64_t arg = cachedTime.seconds() - rawArgs.as_value();
|
||||
auto cached_seconds = torrent::this_thread::cached_seconds().count();
|
||||
|
||||
uint64_t arg = cached_seconds - rawArgs.as_value();
|
||||
|
||||
char buffer[48];
|
||||
snprintf(buffer, 48, "%2d:%02d:%02d", (int)(arg / 3600), (int)((arg / 60) % 60), (int)(arg % 60));
|
||||
@@ -605,8 +607,9 @@ apply_elapsed_less(const torrent::Object::list_type& args) {
|
||||
throw torrent::input_error("Wrong argument count.");
|
||||
|
||||
int64_t start_time = rpc::convert_to_value(args.front());
|
||||
auto cached_seconds = torrent::this_thread::cached_seconds().count();
|
||||
|
||||
return (int64_t)(start_time != 0 && rak::timer::current_seconds() - start_time < rpc::convert_to_value(args.back()));
|
||||
return (int64_t)(start_time != 0 && cached_seconds - start_time < rpc::convert_to_value(args.back()));
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
@@ -615,8 +618,9 @@ apply_elapsed_greater(const torrent::Object::list_type& args) {
|
||||
throw torrent::input_error("Wrong argument count.");
|
||||
|
||||
int64_t start_time = rpc::convert_to_value(args.front());
|
||||
auto cached_seconds = torrent::this_thread::cached_seconds().count();
|
||||
|
||||
return (int64_t)(start_time != 0 && rak::timer::current_seconds() - start_time > rpc::convert_to_value(args.back()));
|
||||
return (int64_t)(start_time != 0 && cached_seconds - start_time > rpc::convert_to_value(args.back()));
|
||||
}
|
||||
|
||||
inline std::vector<int64_t>
|
||||
@@ -764,6 +768,7 @@ cmd_status_throttle_names(bool up, const torrent::Object::list_type& args) {
|
||||
torrent::Object
|
||||
apply_set_color(int color_id, const torrent::Object::string_type& color_str) {
|
||||
control->object_storage()->set_str_string(display::color_vars[color_id], color_str);
|
||||
|
||||
display::Canvas::build_colors();
|
||||
return torrent::Object();
|
||||
}
|
||||
@@ -871,9 +876,11 @@ initialize_command_ui() {
|
||||
// Build set/get methods for all color definitions
|
||||
for (int color_id = 1; color_id < display::RCOLOR_MAX; color_id++) {
|
||||
control->object_storage()->insert_str(display::color_vars[color_id], "", rpc::object_storage::flag_string_type);
|
||||
|
||||
CMD2_ANY_STRING(std::string(display::color_vars[color_id]) + ".set", [color_id](const auto&, const auto& arg) {
|
||||
return apply_set_color(color_id, arg);
|
||||
});
|
||||
|
||||
CMD2_ANY(display::color_vars[color_id], [color_id](const auto&, const auto&) {
|
||||
return control->object_storage()->get_str(display::color_vars[color_id]);
|
||||
});
|
||||
|
||||
+22
-32
@@ -5,12 +5,12 @@
|
||||
#include <torrent/connection_manager.h>
|
||||
#include <torrent/utils/directory_events.h>
|
||||
|
||||
#include "core/manager.h"
|
||||
#include "core/download_store.h"
|
||||
#include "core/view_manager.h"
|
||||
#include "core/curl_stack.h"
|
||||
#include "core/dht_manager.h"
|
||||
#include "core/download_store.h"
|
||||
#include "core/http_queue.h"
|
||||
|
||||
#include "core/manager.h"
|
||||
#include "core/view_manager.h"
|
||||
#include "display/canvas.h"
|
||||
#include "display/window.h"
|
||||
#include "display/window_http_queue.h"
|
||||
@@ -23,26 +23,20 @@
|
||||
#include "rpc/command_scheduler.h"
|
||||
#include "rpc/lua.h"
|
||||
#include "rpc/parse_commands.h"
|
||||
#include "rpc/scgi.h"
|
||||
#include "rpc/object_storage.h"
|
||||
#include "ui/root.h"
|
||||
|
||||
#include "control.h"
|
||||
|
||||
Control::Control() :
|
||||
m_ui(new ui::Root()),
|
||||
m_display(new display::Manager()),
|
||||
m_input(new input::Manager()),
|
||||
m_inputStdin(new input::InputEvent(STDIN_FILENO)),
|
||||
|
||||
m_commandScheduler(new rpc::CommandScheduler()),
|
||||
m_objectStorage(new rpc::object_storage()),
|
||||
m_lua_engine(new rpc::LuaEngine()),
|
||||
m_directory_events(new torrent::directory_events()),
|
||||
|
||||
m_tick(0),
|
||||
m_shutdownReceived(false),
|
||||
m_shutdownQuick(false) {
|
||||
m_ui(new ui::Root()),
|
||||
m_display(new display::Manager()),
|
||||
m_input(new input::Manager()),
|
||||
m_inputStdin(new input::InputEvent(STDIN_FILENO)),
|
||||
m_commandScheduler(new rpc::CommandScheduler()),
|
||||
m_objectStorage(new rpc::object_storage()),
|
||||
m_lua_engine(new rpc::LuaEngine()),
|
||||
m_directory_events(new torrent::directory_events()) {
|
||||
|
||||
m_core = new core::Manager();
|
||||
m_viewManager = new core::ViewManager();
|
||||
@@ -50,7 +44,7 @@ Control::Control() :
|
||||
|
||||
m_inputStdin->slot_pressed(std::bind(&input::Manager::pressed, m_input, std::placeholders::_1));
|
||||
|
||||
m_taskShutdown.slot() = std::bind(&Control::handle_shutdown, this);
|
||||
m_task_shutdown.slot() = std::bind(&Control::handle_shutdown, this);
|
||||
|
||||
m_commandScheduler->set_slot_error_message([this](const std::string& msg) { m_core->push_log_std(msg); });
|
||||
}
|
||||
@@ -75,7 +69,7 @@ Control::~Control() {
|
||||
void
|
||||
Control::initialize() {
|
||||
display::Canvas::initialize();
|
||||
display::Window::slot_schedule([this](display::Window* w, rak::timer t) { m_display->schedule(w, t); });
|
||||
display::Window::slot_schedule([this](display::Window* w, std::chrono::microseconds t) { m_display->schedule(w, t); });
|
||||
display::Window::slot_unschedule([this](display::Window* w) { m_display->unschedule(w); });
|
||||
display::Window::slot_adjust([this]() { m_display->adjust_layout(); });
|
||||
|
||||
@@ -90,19 +84,18 @@ Control::initialize() {
|
||||
m_ui->init(this);
|
||||
|
||||
if(!display::Canvas::daemon()) {
|
||||
m_inputStdin->insert(torrent::main_thread()->poll());
|
||||
m_inputStdin->insert(torrent::this_thread::poll());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Control::cleanup() {
|
||||
// delete m_scgi; m_scgi = NULL;
|
||||
rpc::rpc.cleanup();
|
||||
|
||||
priority_queue_erase(&taskScheduler, &m_taskShutdown);
|
||||
torrent::this_thread::scheduler()->erase(&m_task_shutdown);
|
||||
|
||||
if(!display::Canvas::daemon()) {
|
||||
m_inputStdin->remove(torrent::main_thread()->poll());
|
||||
m_inputStdin->remove(torrent::this_thread::poll());
|
||||
}
|
||||
|
||||
m_core->download_store()->disable();
|
||||
@@ -118,8 +111,6 @@ Control::cleanup() {
|
||||
|
||||
void
|
||||
Control::cleanup_exception() {
|
||||
// delete m_scgi; m_scgi = NULL;
|
||||
|
||||
display::Canvas::cleanup();
|
||||
}
|
||||
|
||||
@@ -142,21 +133,20 @@ Control::handle_shutdown() {
|
||||
rpc::commands.call_catch("event.system.shutdown", rpc::make_target(), "shutdown", "System shutdown event action failed: ");
|
||||
|
||||
if (!m_shutdownQuick) {
|
||||
// Temporary hack:
|
||||
if (worker_thread->is_active())
|
||||
worker_thread->queue_item(&ThreadBase::stop_thread);
|
||||
worker_thread->stop_thread_wait();
|
||||
|
||||
torrent::connection_manager()->listen_close();
|
||||
|
||||
m_directory_events->close();
|
||||
m_core->shutdown(false);
|
||||
|
||||
if (!m_taskShutdown.is_queued())
|
||||
priority_queue_insert(&taskScheduler, &m_taskShutdown, cachedTime + rak::timer::from_seconds(5));
|
||||
if (!m_task_shutdown.is_scheduled())
|
||||
torrent::this_thread::scheduler()->wait_for_ceil_seconds(&m_task_shutdown, 5s);
|
||||
|
||||
} else {
|
||||
// Temporary hack:
|
||||
if (worker_thread->is_active())
|
||||
worker_thread->queue_item(&ThreadBase::stop_thread);
|
||||
worker_thread->stop_thread_wait();
|
||||
|
||||
m_core->shutdown(true);
|
||||
}
|
||||
|
||||
+7
-44
@@ -1,48 +1,11 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_CONTROL_H
|
||||
#define RTORRENT_CONTROL_H
|
||||
|
||||
#include <atomic>
|
||||
#include <cinttypes>
|
||||
#include <sys/types.h>
|
||||
#include <rak/timer.h>
|
||||
#include <rak/priority_queue_default.h>
|
||||
#include <torrent/torrent.h>
|
||||
#include <torrent/utils/scheduler.h>
|
||||
|
||||
namespace ui {
|
||||
class Root;
|
||||
@@ -61,7 +24,7 @@ namespace display {
|
||||
namespace input {
|
||||
class InputEvent;
|
||||
class Manager;
|
||||
}
|
||||
}
|
||||
|
||||
namespace rpc {
|
||||
class CommandScheduler;
|
||||
@@ -78,7 +41,7 @@ class Control {
|
||||
public:
|
||||
Control();
|
||||
~Control();
|
||||
|
||||
|
||||
bool is_shutdown_completed();
|
||||
bool is_shutdown_received() { return m_shutdownReceived; }
|
||||
bool is_shutdown_started() { return m_shutdownQuick; }
|
||||
@@ -131,15 +94,15 @@ private:
|
||||
rpc::LuaEngine* m_lua_engine;
|
||||
torrent::directory_events* m_directory_events;
|
||||
|
||||
uint64_t m_tick;
|
||||
uint64_t m_tick{};
|
||||
|
||||
mode_t m_umask;
|
||||
std::string m_workingDirectory;
|
||||
|
||||
rak::priority_item m_taskShutdown;
|
||||
torrent::utils::SchedulerEntry m_task_shutdown;
|
||||
|
||||
std::atomic<bool> m_shutdownReceived;
|
||||
std::atomic<bool> m_shutdownQuick;
|
||||
std::atomic<bool> m_shutdownReceived{};
|
||||
std::atomic<bool> m_shutdownQuick{};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+18
-47
@@ -1,49 +1,14 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "core/curl_get.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <curl/curl.h>
|
||||
#include <curl/easy.h>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
#include "globals.h"
|
||||
#include "curl_get.h"
|
||||
#include "curl_stack.h"
|
||||
#include "core/curl_stack.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
@@ -55,6 +20,12 @@ curl_get_receive_write(void* data, size_t size, size_t nmemb, void* handle) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CurlGet::CurlGet(CurlStack* s) :
|
||||
m_stack(s) {
|
||||
|
||||
m_task_timeout.slot() = [this]() { receive_timeout(); };
|
||||
}
|
||||
|
||||
CurlGet::~CurlGet() {
|
||||
close();
|
||||
}
|
||||
@@ -85,8 +56,7 @@ CurlGet::start() {
|
||||
|
||||
// Normally libcurl should handle the timeout. But sometimes that doesn't
|
||||
// work right so we do a fallback timeout that just aborts the transfer.
|
||||
m_taskTimeout.slot() = std::bind(&CurlGet::receive_timeout, this);
|
||||
priority_queue_update(&taskScheduler, &m_taskTimeout, cachedTime + rak::timer::from_seconds(m_timeout + 5));
|
||||
torrent::this_thread::scheduler()->update_wait_for_ceil_seconds(&m_task_timeout, 5s + 1s*m_timeout);
|
||||
}
|
||||
|
||||
curl_easy_setopt(m_handle, CURLOPT_FORBID_REUSE, (long)1);
|
||||
@@ -105,7 +75,8 @@ CurlGet::start() {
|
||||
|
||||
void
|
||||
CurlGet::close() {
|
||||
priority_queue_erase(&taskScheduler, &m_taskTimeout);
|
||||
torrent::this_thread::scheduler()->erase(&m_task_timeout);
|
||||
|
||||
if (!is_busy())
|
||||
return;
|
||||
|
||||
@@ -132,18 +103,18 @@ CurlGet::receive_timeout() {
|
||||
return m_stack->transfer_done(m_handle, "Timed out");
|
||||
}
|
||||
|
||||
double
|
||||
curl_off_t
|
||||
CurlGet::size_done() {
|
||||
double d = 0.0;
|
||||
curl_easy_getinfo(m_handle, CURLINFO_SIZE_DOWNLOAD, &d);
|
||||
curl_off_t d = 0;
|
||||
curl_easy_getinfo(m_handle, CURLINFO_SIZE_DOWNLOAD_T, &d);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
double
|
||||
curl_off_t
|
||||
CurlGet::size_total() {
|
||||
double d = 0.0;
|
||||
curl_easy_getinfo(m_handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d);
|
||||
curl_off_t d = 0;
|
||||
curl_easy_getinfo(m_handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &d);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
+12
-49
@@ -1,39 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_CORE_CURL_GET_H
|
||||
#define RTORRENT_CORE_CURL_GET_H
|
||||
|
||||
@@ -41,8 +5,7 @@
|
||||
#include <string>
|
||||
#include <curl/curl.h>
|
||||
#include <torrent/http.h>
|
||||
|
||||
#include "rak/priority_queue_default.h"
|
||||
#include <torrent/utils/scheduler.h>
|
||||
|
||||
namespace core {
|
||||
|
||||
@@ -50,9 +13,7 @@ class CurlStack;
|
||||
|
||||
class CurlGet : public torrent::Http {
|
||||
public:
|
||||
friend class CurlStack;
|
||||
|
||||
CurlGet(CurlStack* s) : m_active(false), m_handle(NULL), m_stack(s) {}
|
||||
CurlGet(CurlStack* s);
|
||||
virtual ~CurlGet();
|
||||
|
||||
void start();
|
||||
@@ -66,23 +27,25 @@ public:
|
||||
|
||||
void set_active(bool a) { m_active = a; }
|
||||
|
||||
double size_done();
|
||||
double size_total();
|
||||
curl_off_t size_done();
|
||||
curl_off_t size_total();
|
||||
|
||||
CURL* handle() { return m_handle; }
|
||||
|
||||
private:
|
||||
CurlGet(const CurlGet&);
|
||||
void operator = (const CurlGet&);
|
||||
friend class CurlStack;
|
||||
|
||||
CurlGet(const CurlGet&) = delete;
|
||||
void operator = (const CurlGet&) = delete;
|
||||
|
||||
void receive_timeout();
|
||||
|
||||
bool m_active;
|
||||
bool m_active{};
|
||||
bool m_ipv6;
|
||||
|
||||
rak::priority_item m_taskTimeout;
|
||||
|
||||
CURL* m_handle;
|
||||
torrent::utils::SchedulerEntry m_task_timeout;
|
||||
|
||||
CURL* m_handle{};
|
||||
CurlStack* m_stack;
|
||||
};
|
||||
|
||||
|
||||
+10
-13
@@ -1,18 +1,15 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "curl_socket.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/multi.h>
|
||||
|
||||
#include <torrent/poll.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/utils/thread.h>
|
||||
|
||||
#include "control.h"
|
||||
|
||||
#include "curl_socket.h"
|
||||
#include "curl_stack.h"
|
||||
#include "core/curl_stack.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
@@ -39,22 +36,22 @@ CurlSocket::receive_socket([[maybe_unused]] void* easy_handle, curl_socket_t fd,
|
||||
|
||||
if (socket == NULL) {
|
||||
socket = stack->new_socket(fd);
|
||||
torrent::main_thread()->poll()->open(socket);
|
||||
torrent::this_thread::poll()->open(socket);
|
||||
|
||||
// No interface for libcurl to signal when it's interested in error events.
|
||||
// Assume that hence it must always be interested in them.
|
||||
torrent::main_thread()->poll()->insert_error(socket);
|
||||
torrent::this_thread::poll()->insert_error(socket);
|
||||
}
|
||||
|
||||
if (what == CURL_POLL_NONE || what == CURL_POLL_OUT)
|
||||
torrent::main_thread()->poll()->remove_read(socket);
|
||||
torrent::this_thread::poll()->remove_read(socket);
|
||||
else
|
||||
torrent::main_thread()->poll()->insert_read(socket);
|
||||
torrent::this_thread::poll()->insert_read(socket);
|
||||
|
||||
if (what == CURL_POLL_NONE || what == CURL_POLL_IN)
|
||||
torrent::main_thread()->poll()->remove_write(socket);
|
||||
torrent::this_thread::poll()->remove_write(socket);
|
||||
else
|
||||
torrent::main_thread()->poll()->insert_write(socket);
|
||||
torrent::this_thread::poll()->insert_write(socket);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -68,7 +65,7 @@ CurlSocket::close() {
|
||||
if (m_fileDesc == -1)
|
||||
throw torrent::internal_error("CurlSocket::close() m_fileDesc == -1.");
|
||||
|
||||
torrent::main_thread()->poll()->closed(this);
|
||||
torrent::this_thread::poll()->closed(this);
|
||||
m_fileDesc = -1;
|
||||
}
|
||||
|
||||
|
||||
+1
-36
@@ -1,42 +1,7 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2008, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_CORE_CURL_SOCKET_H
|
||||
#define RTORRENT_CORE_CURL_SOCKET_H
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <torrent/event.h>
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
+17
-10
@@ -37,7 +37,8 @@ CurlStack::shutdown() {
|
||||
front()->close();
|
||||
|
||||
curl_multi_cleanup((CURLM*)m_handle);
|
||||
priority_queue_erase(&taskScheduler, &m_task_timeout);
|
||||
|
||||
torrent::this_thread::scheduler()->erase(&m_task_timeout);
|
||||
}
|
||||
|
||||
CurlGet*
|
||||
@@ -85,7 +86,7 @@ CurlStack::receive_action(CurlSocket* socket, int events) {
|
||||
; // Do nothing.
|
||||
|
||||
if (empty())
|
||||
priority_queue_erase(&taskScheduler, &m_task_timeout);
|
||||
torrent::this_thread::scheduler()->erase(&m_task_timeout);
|
||||
}
|
||||
|
||||
} while (code == CURLM_CALL_MULTI_PERFORM);
|
||||
@@ -140,12 +141,15 @@ void
|
||||
CurlStack::receive_timeout() {
|
||||
receive_action(NULL, 0);
|
||||
|
||||
// Sometimes libcurl forgets to reset the timeout. Try to poll the value in that case, or use 10 seconds.
|
||||
if (!empty() && !m_task_timeout.is_queued()) {
|
||||
long timeout;
|
||||
curl_multi_timeout((CURLM*)m_handle, &timeout);
|
||||
priority_queue_insert(&taskScheduler, &m_task_timeout,
|
||||
cachedTime + rak::timer::from_milliseconds(std::max<unsigned long>(timeout, 10000)));
|
||||
if (!empty() && !m_task_timeout.is_scheduled()) {
|
||||
// Sometimes libcurl forgets to reset the timeout. Try to poll the value in that case, or use 10
|
||||
// seconds max.
|
||||
long timeout_ms;
|
||||
curl_multi_timeout((CURLM*)m_handle, &timeout_ms);
|
||||
|
||||
auto timeout = std::max<std::chrono::microseconds>(std::chrono::milliseconds(timeout_ms), 10s);
|
||||
|
||||
torrent::this_thread::scheduler()->wait_for_ceil_seconds(&m_task_timeout, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,10 +233,13 @@ CurlStack::global_cleanup() {
|
||||
// TODO: Is this function supposed to set a per-handle timeout, or is
|
||||
// it the shortest timeout amongst all handles?
|
||||
int
|
||||
CurlStack::set_timeout(void* handle, long timeout_ms, void* userp) {
|
||||
CurlStack::set_timeout(void*, long timeout_ms, void* userp) {
|
||||
CurlStack* stack = (CurlStack*)userp;
|
||||
|
||||
priority_queue_update(&taskScheduler, &stack->m_task_timeout, cachedTime + rak::timer::from_milliseconds(timeout_ms));
|
||||
if (timeout_ms == -1)
|
||||
torrent::this_thread::scheduler()->erase(&stack->m_task_timeout);
|
||||
else
|
||||
torrent::this_thread::scheduler()->update_wait_for_ceil_seconds(&stack->m_task_timeout, std::chrono::milliseconds(timeout_ms));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
|
||||
#include <deque>
|
||||
#include <string>
|
||||
|
||||
#include "rak/priority_queue_default.h"
|
||||
#include <torrent/utils/scheduler.h>
|
||||
|
||||
namespace core {
|
||||
|
||||
@@ -20,7 +19,7 @@ class CurlSocket;
|
||||
// removal of elements.
|
||||
|
||||
class CurlStack : std::deque<CurlGet*> {
|
||||
public:
|
||||
public:
|
||||
friend class CurlGet;
|
||||
|
||||
typedef std::deque<CurlGet*> base_type;
|
||||
@@ -80,17 +79,17 @@ class CurlStack : std::deque<CurlGet*> {
|
||||
|
||||
void receive_action(CurlSocket* socket, int type);
|
||||
|
||||
static int set_timeout(void* handle, long timeout_ms, void* userp);
|
||||
static int set_timeout(void*, long timeout_ms, void* userp);
|
||||
|
||||
void transfer_done(void* handle, const char* msg);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
void add_get(CurlGet* get);
|
||||
void remove_get(CurlGet* get);
|
||||
|
||||
private:
|
||||
CurlStack(const CurlStack&);
|
||||
void operator = (const CurlStack&);
|
||||
private:
|
||||
CurlStack(const CurlStack&) = delete;
|
||||
void operator = (const CurlStack&) = delete;
|
||||
|
||||
void receive_timeout();
|
||||
|
||||
@@ -103,7 +102,7 @@ class CurlStack : std::deque<CurlGet*> {
|
||||
unsigned int m_active{0};
|
||||
unsigned int m_max_active{32};
|
||||
|
||||
rak::priority_item m_task_timeout;
|
||||
torrent::utils::SchedulerEntry m_task_timeout;
|
||||
|
||||
std::string m_user_agent;
|
||||
std::string m_http_proxy;
|
||||
|
||||
+13
-12
@@ -26,8 +26,8 @@ namespace core {
|
||||
const char* DhtManager::dht_settings[dht_settings_num] = { "disable", "off", "auto", "on" };
|
||||
|
||||
DhtManager::~DhtManager() {
|
||||
priority_queue_erase(&taskScheduler, &m_updateTimeout);
|
||||
priority_queue_erase(&taskScheduler, &m_stopTimeout);
|
||||
torrent::this_thread::scheduler()->erase(&m_update_timeout);
|
||||
torrent::this_thread::scheduler()->erase(&m_stop_timeout);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -66,7 +66,7 @@ DhtManager::load_dht_cache() {
|
||||
|
||||
void
|
||||
DhtManager::start_dht() {
|
||||
priority_queue_erase(&taskScheduler, &m_stopTimeout);
|
||||
torrent::this_thread::scheduler()->erase(&m_stop_timeout);
|
||||
|
||||
if (!torrent::dht_controller()->is_valid()) {
|
||||
LT_LOG_THIS("server start skipped, manager is uninitialized", 0);
|
||||
@@ -94,8 +94,9 @@ DhtManager::start_dht() {
|
||||
|
||||
torrent::dht_controller()->reset_statistics();
|
||||
|
||||
m_updateTimeout.slot() = std::bind(&DhtManager::update, this);
|
||||
priority_queue_insert(&taskScheduler, &m_updateTimeout, (cachedTime + rak::timer::from_seconds(60)).round_seconds());
|
||||
m_update_timeout.slot() = std::bind(&DhtManager::update, this);
|
||||
|
||||
torrent::this_thread::scheduler()->wait_for_ceil_seconds(&m_update_timeout, 60s);
|
||||
|
||||
m_dhtPrevCycle = 0;
|
||||
m_dhtPrevQueriesSent = 0;
|
||||
@@ -107,8 +108,8 @@ DhtManager::start_dht() {
|
||||
|
||||
void
|
||||
DhtManager::stop_dht() {
|
||||
priority_queue_erase(&taskScheduler, &m_updateTimeout);
|
||||
priority_queue_erase(&taskScheduler, &m_stopTimeout);
|
||||
torrent::this_thread::scheduler()->erase(&m_update_timeout);
|
||||
torrent::this_thread::scheduler()->erase(&m_stop_timeout);
|
||||
|
||||
if (torrent::dht_controller()->is_active()) {
|
||||
LT_LOG_THIS("stopping server", 0);
|
||||
@@ -165,7 +166,7 @@ DhtManager::update() {
|
||||
if (!torrent::dht_controller()->is_active())
|
||||
throw torrent::internal_error("DhtManager::update called with DHT inactive.");
|
||||
|
||||
if (m_start == dht_auto && !m_stopTimeout.is_queued()) {
|
||||
if (m_start == dht_auto && !m_stop_timeout.is_scheduled()) {
|
||||
DownloadList::const_iterator itr, end;
|
||||
|
||||
for (itr = control->core()->download_list()->begin(), end = control->core()->download_list()->end(); itr != end; ++itr)
|
||||
@@ -173,16 +174,16 @@ DhtManager::update() {
|
||||
break;
|
||||
|
||||
if (itr == end) {
|
||||
m_stopTimeout.slot() = std::bind(&DhtManager::stop_dht, this);
|
||||
priority_queue_insert(&taskScheduler, &m_stopTimeout, (cachedTime + rak::timer::from_seconds(15 * 60)).round_seconds());
|
||||
m_stop_timeout.slot() = std::bind(&DhtManager::stop_dht, this);
|
||||
torrent::this_thread::scheduler()->wait_for_ceil_seconds(&m_stop_timeout, 15min);
|
||||
}
|
||||
}
|
||||
|
||||
// While bootstrapping (log_statistics returns true), check every minute if it completed, otherwise update every 15 minutes.
|
||||
if (log_statistics(false))
|
||||
priority_queue_insert(&taskScheduler, &m_updateTimeout, (cachedTime + rak::timer::from_seconds(60)).round_seconds());
|
||||
torrent::this_thread::scheduler()->wait_for_ceil_seconds(&m_update_timeout, 1min);
|
||||
else
|
||||
priority_queue_insert(&taskScheduler, &m_updateTimeout, (cachedTime + rak::timer::from_seconds(15 * 60)).round_seconds());
|
||||
torrent::this_thread::scheduler()->wait_for_ceil_seconds(&m_update_timeout, 15min);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
#ifndef RTORRENT_CORE_DHT_MANAGER_H
|
||||
#define RTORRENT_CORE_DHT_MANAGER_H
|
||||
|
||||
#include <rak/priority_queue_default.h>
|
||||
|
||||
#include <torrent/object.h>
|
||||
#include <torrent/utils/scheduler.h>
|
||||
|
||||
namespace core {
|
||||
|
||||
class DhtManager {
|
||||
public:
|
||||
DhtManager() : m_warned(false), m_start(dht_off) { }
|
||||
~DhtManager();
|
||||
|
||||
void load_dht_cache();
|
||||
@@ -44,11 +42,12 @@ private:
|
||||
uint64_t m_dhtPrevBytesUp;
|
||||
uint64_t m_dhtPrevBytesDown;
|
||||
|
||||
rak::priority_item m_updateTimeout;
|
||||
rak::priority_item m_stopTimeout;
|
||||
bool m_warned;
|
||||
torrent::utils::SchedulerEntry m_update_timeout;
|
||||
torrent::utils::SchedulerEntry m_stop_timeout;
|
||||
|
||||
int m_start;
|
||||
bool m_warned{};
|
||||
|
||||
int m_start{dht_off};
|
||||
std::string m_throttleName;
|
||||
};
|
||||
|
||||
|
||||
+12
-13
@@ -6,7 +6,6 @@
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/rate.h>
|
||||
#include <torrent/torrent.h>
|
||||
#include <torrent/tracker_list.h>
|
||||
#include <torrent/tracker/tracker.h>
|
||||
#include <torrent/data/file_list.h>
|
||||
|
||||
@@ -19,11 +18,7 @@
|
||||
namespace core {
|
||||
|
||||
Download::Download(download_type d) :
|
||||
m_download(d),
|
||||
m_hashFailed(false),
|
||||
|
||||
m_resumeFlags(~uint32_t()),
|
||||
m_group(0) {
|
||||
m_download(d) {
|
||||
|
||||
m_download.info()->signal_tracker_success().push_back(std::bind(&Download::receive_tracker_msg, this, ""));
|
||||
m_download.info()->signal_tracker_failed().push_back(std::bind(&Download::receive_tracker_msg, this, std::placeholders::_1));
|
||||
@@ -38,13 +33,17 @@ Download::~Download() {
|
||||
|
||||
void
|
||||
Download::enable_udp_trackers(bool state) {
|
||||
for (torrent::TrackerList::iterator itr = m_download.tracker_list()->begin(), last = m_download.tracker_list()->end(); itr != last; ++itr)
|
||||
if (itr->type() == torrent::TRACKER_UDP) {
|
||||
if (state)
|
||||
itr->enable();
|
||||
else
|
||||
itr->disable();
|
||||
}
|
||||
for (int idx = 0, end = m_download.tracker_controller().size(); idx < end; ++idx) {
|
||||
auto tracker = m_download.tracker_controller().at(idx);
|
||||
|
||||
if (tracker.type() != torrent::TRACKER_UDP)
|
||||
continue;
|
||||
|
||||
if (state)
|
||||
tracker.enable();
|
||||
else
|
||||
tracker.disable();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
||||
+5
-6
@@ -5,9 +5,9 @@
|
||||
#include <torrent/download.h>
|
||||
#include <torrent/download_info.h>
|
||||
#include <torrent/hash_string.h>
|
||||
#include <torrent/tracker_list.h>
|
||||
#include <torrent/data/file_list.h>
|
||||
#include <torrent/peer/connection_list.h>
|
||||
#include <torrent/tracker/wrappers.h>
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
@@ -62,8 +62,7 @@ public:
|
||||
torrent::Object* bencode() { return m_download.bencode(); }
|
||||
|
||||
auto tracker_controller() { return m_download.tracker_controller(); }
|
||||
tracker_list_type* tracker_list() { return m_download.tracker_list(); }
|
||||
uint32_t tracker_list_size() const { return m_download.tracker_list()->size(); }
|
||||
uint32_t tracker_list_size() const { return m_download.c_tracker_controller().size(); }
|
||||
|
||||
auto connection_list() { return m_download.connection_list(); }
|
||||
uint32_t connection_list_size() const;
|
||||
@@ -101,10 +100,10 @@ private:
|
||||
|
||||
// Store the FileList instance so we can use slots etc on it.
|
||||
download_type m_download;
|
||||
bool m_hashFailed;
|
||||
bool m_hashFailed{};
|
||||
std::string m_message;
|
||||
uint32_t m_resumeFlags;
|
||||
unsigned int m_group;
|
||||
uint32_t m_resumeFlags{~uint32_t{}};
|
||||
unsigned int m_group{};
|
||||
};
|
||||
|
||||
inline bool
|
||||
|
||||
@@ -60,20 +60,10 @@ is_magnet_uri(const std::string& uri) {
|
||||
}
|
||||
|
||||
DownloadFactory::DownloadFactory(Manager* m) :
|
||||
m_manager(m),
|
||||
m_stream(NULL),
|
||||
m_object(NULL),
|
||||
m_commited(false),
|
||||
m_loaded(false),
|
||||
m_manager(m) {
|
||||
|
||||
m_session(false),
|
||||
m_start(false),
|
||||
m_printLog(true),
|
||||
m_isFile(false),
|
||||
m_initLoad(false) {
|
||||
|
||||
m_taskLoad.slot() = std::bind(&DownloadFactory::receive_load, this);
|
||||
m_taskCommit.slot() = std::bind(&DownloadFactory::receive_commit, this);
|
||||
m_task_load.slot() = std::bind(&DownloadFactory::receive_load, this);
|
||||
m_task_commit.slot() = std::bind(&DownloadFactory::receive_commit, this);
|
||||
|
||||
// m_variables["connection_leech"] = rpc::call_command("protocol.connection.leech");
|
||||
// m_variables["connection_seed"] = rpc::call_command("protocol.connection.seed");
|
||||
@@ -84,8 +74,8 @@ DownloadFactory::DownloadFactory(Manager* m) :
|
||||
}
|
||||
|
||||
DownloadFactory::~DownloadFactory() {
|
||||
priority_queue_erase(&taskScheduler, &m_taskLoad);
|
||||
priority_queue_erase(&taskScheduler, &m_taskCommit);
|
||||
torrent::this_thread::scheduler()->erase(&m_task_load);
|
||||
torrent::this_thread::scheduler()->erase(&m_task_commit);
|
||||
|
||||
delete m_stream;
|
||||
delete m_object;
|
||||
@@ -95,7 +85,7 @@ DownloadFactory::~DownloadFactory() {
|
||||
void
|
||||
DownloadFactory::load(const std::string& uri) {
|
||||
m_uri = uri;
|
||||
priority_queue_insert(&taskScheduler, &m_taskLoad, cachedTime);
|
||||
torrent::this_thread::scheduler()->wait_for(&m_task_load, 0ms);
|
||||
}
|
||||
|
||||
// This function must be called before DownloadFactory::commit().
|
||||
@@ -110,7 +100,7 @@ DownloadFactory::load_raw_data(const std::string& input) {
|
||||
|
||||
void
|
||||
DownloadFactory::commit() {
|
||||
priority_queue_insert(&taskScheduler, &m_taskCommit, cachedTime);
|
||||
torrent::this_thread::scheduler()->wait_for(&m_task_commit, 0ms);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -225,7 +215,7 @@ DownloadFactory::receive_success() {
|
||||
torrent::Object* rtorrent = &root->insert_preserve_copy("rtorrent", torrent::Object::create_map()).first->second;
|
||||
torrent::Object& resumeObject = root->insert_preserve_copy("libtorrent_resume", torrent::Object::create_map()).first->second;
|
||||
|
||||
rtorrent->insert_key("key", download->tracker_list()->key());
|
||||
rtorrent->insert_key("key", download->tracker_controller().key());
|
||||
|
||||
initialize_rtorrent(download, rtorrent);
|
||||
|
||||
@@ -366,15 +356,17 @@ DownloadFactory::receive_failed(const std::string& msg) {
|
||||
|
||||
void
|
||||
DownloadFactory::initialize_rtorrent(Download* download, torrent::Object* rtorrent) {
|
||||
auto cached_seconds = torrent::this_thread::cached_seconds().count();
|
||||
|
||||
if (!rtorrent->has_key_value("state") || rtorrent->get_key_value("state") > 1) {
|
||||
rtorrent->insert_key("state", (int64_t)m_start);
|
||||
rtorrent->insert_key("state_changed", cachedTime.seconds());
|
||||
rtorrent->insert_key("state_changed", cached_seconds);
|
||||
rtorrent->insert_key("state_counter", int64_t());
|
||||
|
||||
} else if (!rtorrent->has_key_value("state_changed") ||
|
||||
rtorrent->get_key_value("state_changed") > cachedTime.seconds() || rtorrent->get_key_value("state_changed") == 0 ||
|
||||
rtorrent->get_key_value("state_changed") > cached_seconds || rtorrent->get_key_value("state_changed") == 0 ||
|
||||
!rtorrent->has_key_value("state_counter") || (uint64_t)rtorrent->get_key_value("state_counter") > (1 << 20)) {
|
||||
rtorrent->insert_key("state_changed", cachedTime.seconds());
|
||||
rtorrent->insert_key("state_changed", cached_seconds);
|
||||
rtorrent->insert_key("state_counter", int64_t());
|
||||
}
|
||||
|
||||
|
||||
+14
-49
@@ -1,39 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
// The DownloadFactory class assures that loading torrents can be done
|
||||
// anywhere in the code by queueing the task. The user may change
|
||||
// settings while, or even after, the torrent is loading.
|
||||
@@ -44,13 +8,14 @@
|
||||
#include <functional>
|
||||
#include <iosfwd>
|
||||
|
||||
#include <rak/priority_queue_default.h>
|
||||
#include <torrent/object.h>
|
||||
#include <torrent/utils/scheduler.h>
|
||||
|
||||
#include "http_queue.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
class Download;
|
||||
class Manager;
|
||||
|
||||
class DownloadFactory {
|
||||
@@ -98,25 +63,25 @@ private:
|
||||
void initialize_rtorrent(Download* download, torrent::Object* rtorrent);
|
||||
|
||||
Manager* m_manager;
|
||||
std::iostream* m_stream;
|
||||
torrent::Object* m_object;
|
||||
std::iostream* m_stream{};
|
||||
torrent::Object* m_object{};
|
||||
|
||||
bool m_commited;
|
||||
bool m_loaded;
|
||||
bool m_commited{};
|
||||
bool m_loaded{};
|
||||
|
||||
std::string m_uri;
|
||||
bool m_session;
|
||||
bool m_start;
|
||||
bool m_printLog;
|
||||
bool m_isFile;
|
||||
bool m_initLoad;
|
||||
bool m_session{};
|
||||
bool m_start{};
|
||||
bool m_printLog{true};
|
||||
bool m_isFile{};
|
||||
bool m_initLoad{};
|
||||
|
||||
command_list_type m_commands;
|
||||
torrent::Object::map_type m_variables;
|
||||
|
||||
slot_void m_slot_finished;
|
||||
rak::priority_item m_taskLoad;
|
||||
rak::priority_item m_taskCommit;
|
||||
slot_void m_slot_finished;
|
||||
torrent::utils::SchedulerEntry m_task_load;
|
||||
torrent::utils::SchedulerEntry m_task_commit;
|
||||
};
|
||||
|
||||
bool is_network_uri(const std::string& uri);
|
||||
|
||||
+31
-10
@@ -43,10 +43,27 @@ DownloadList::check_contains([[maybe_unused]] Download* d) {
|
||||
|
||||
void
|
||||
DownloadList::clear() {
|
||||
std::for_each(begin(), end(), [&](Download* d) { close(d); });
|
||||
std::for_each(begin(), end(), [](Download* d) { delete d; });
|
||||
int error_count = 0;
|
||||
|
||||
base_type::clear();
|
||||
while (!empty()) {
|
||||
auto download = back();
|
||||
|
||||
try {
|
||||
close(download);
|
||||
base_type::pop_back();
|
||||
|
||||
torrent::download_remove(*download->download());
|
||||
delete download;
|
||||
|
||||
} catch (torrent::internal_error& e) {
|
||||
lt_log_print(torrent::LOG_ERROR, "DownloadList::clear() failed to close or remove download: %s", e.what());
|
||||
error_count++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (error_count > 0)
|
||||
throw torrent::internal_error("DownloadList::clear() failed to close or remove " + std::to_string(error_count) + " downloads.");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -90,11 +107,11 @@ DownloadList::create(torrent::Object* obj, uint32_t tracker_key, bool printLog)
|
||||
download = torrent::download_add(obj, tracker_key);
|
||||
|
||||
} catch (torrent::local_error& e) {
|
||||
delete obj;
|
||||
|
||||
if (printLog)
|
||||
lt_log_print(torrent::LOG_TORRENT_ERROR, "Could not create download: %s", e.what());
|
||||
|
||||
delete obj;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -214,7 +231,7 @@ DownloadList::open_throw(Download* download) {
|
||||
|
||||
if (download->download()->info()->is_open())
|
||||
return;
|
||||
|
||||
|
||||
int openFlags = download->resume_flags();
|
||||
|
||||
if (rpc::call_command_value("system.file.allocate"))
|
||||
@@ -253,7 +270,7 @@ void
|
||||
DownloadList::close_quick(Download* download) {
|
||||
lt_log_print_info(torrent::LOG_TORRENT_INFO, download->info(), "download_list", "Closing download quickly.");
|
||||
close(download);
|
||||
|
||||
|
||||
// Make sure we cancel any tracker requests. This should rather be
|
||||
// handled by some parameter to the close function, or some other
|
||||
// way of giving the client more control of when STOPPED requests
|
||||
@@ -333,7 +350,9 @@ DownloadList::resume(Download* download, int flags) {
|
||||
// This will never actually do anything due to the above hash check.
|
||||
// open_throw(download);
|
||||
|
||||
rpc::call_command("d.state_changed.set", cachedTime.seconds(), rpc::make_target(download));
|
||||
auto cached_seconds = torrent::this_thread::cached_seconds().count();
|
||||
|
||||
rpc::call_command("d.state_changed.set", cached_seconds, rpc::make_target(download));
|
||||
rpc::call_command("d.state_counter.set", rpc::call_command_value("d.state_counter", rpc::make_target(download)) + 1, rpc::make_target(download));
|
||||
|
||||
if (download->is_done()) {
|
||||
@@ -415,13 +434,15 @@ DownloadList::pause(Download* download, int flags) {
|
||||
|
||||
download->download()->stop(flags);
|
||||
torrent::resume_save_progress(*download->download(), download->download()->bencode()->get_key("libtorrent_resume"));
|
||||
|
||||
|
||||
// TODO: This is actually for pause, not stop... And doesn't get
|
||||
// called when the download isn't active, but was in the 'started'
|
||||
// view.
|
||||
DL_TRIGGER_EVENT(download, "event.download.paused");
|
||||
|
||||
rpc::call_command("d.state_changed.set", cachedTime.seconds(), rpc::make_target(download));
|
||||
auto cached_seconds = torrent::this_thread::cached_seconds().count();
|
||||
|
||||
rpc::call_command("d.state_changed.set", cached_seconds, rpc::make_target(download));
|
||||
rpc::call_command("d.state_counter.set", rpc::call_command_value("d.state_counter", rpc::make_target(download)), rpc::make_target(download));
|
||||
|
||||
// If initial seeding is complete, don't try it again when restarting.
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
using base_type::empty;
|
||||
using base_type::size;
|
||||
|
||||
DownloadList() { }
|
||||
DownloadList() = default;
|
||||
|
||||
void clear();
|
||||
|
||||
|
||||
@@ -100,9 +100,10 @@ DownloadStore::write_bencode(const std::string& filename, const torrent::Object&
|
||||
#else
|
||||
fdatasync(fd);
|
||||
#endif
|
||||
::close(fd);
|
||||
}
|
||||
|
||||
::close(fd);
|
||||
|
||||
return true;
|
||||
|
||||
download_store_save_error:
|
||||
|
||||
+1
-37
@@ -1,39 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <memory>
|
||||
@@ -48,7 +12,7 @@ namespace core {
|
||||
HttpQueue::iterator
|
||||
HttpQueue::insert(const std::string& url, std::iostream* s) {
|
||||
std::unique_ptr<CurlGet> h(m_slot_factory());
|
||||
|
||||
|
||||
h->set_url(url);
|
||||
h->set_stream(s);
|
||||
h->set_timeout(5 * 60);
|
||||
|
||||
+3
-39
@@ -1,39 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_CORE_HTTP_QUEUE_H
|
||||
#define RTORRENT_CORE_HTTP_QUEUE_H
|
||||
|
||||
@@ -47,10 +11,10 @@ class CurlGet;
|
||||
|
||||
class HttpQueue : private std::list<CurlGet*> {
|
||||
public:
|
||||
typedef std::list<CurlGet*> base_type;
|
||||
typedef std::list<CurlGet*> base_type;
|
||||
typedef std::function<CurlGet* ()> slot_factory;
|
||||
typedef std::function<void (CurlGet*)> slot_curl_get;
|
||||
typedef std::list<slot_curl_get> signal_curl_get;
|
||||
typedef std::list<slot_curl_get> signal_curl_get;
|
||||
|
||||
using base_type::iterator;
|
||||
using base_type::const_iterator;
|
||||
@@ -65,7 +29,7 @@ public:
|
||||
using base_type::empty;
|
||||
using base_type::size;
|
||||
|
||||
HttpQueue() {}
|
||||
HttpQueue() = default;
|
||||
~HttpQueue() { clear(); }
|
||||
|
||||
// Note that any slots connected to the CurlGet signals must be
|
||||
|
||||
+32
-41
@@ -17,7 +17,6 @@
|
||||
#include <torrent/error.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/object_stream.h>
|
||||
#include <torrent/tracker_list.h>
|
||||
#include <torrent/throttle.h>
|
||||
#include <torrent/utils/log.h>
|
||||
|
||||
@@ -28,13 +27,13 @@
|
||||
|
||||
#include "globals.h"
|
||||
#include "curl_get.h"
|
||||
#include "curl_stack.h"
|
||||
#include "control.h"
|
||||
#include "download.h"
|
||||
#include "download_factory.h"
|
||||
#include "download_store.h"
|
||||
#include "http_queue.h"
|
||||
#include "manager.h"
|
||||
#include "poll_manager.h"
|
||||
#include "view.h"
|
||||
|
||||
namespace core {
|
||||
@@ -51,15 +50,14 @@ Manager::push_log(const char* msg) {
|
||||
}
|
||||
|
||||
Manager::Manager() :
|
||||
m_hashingView(NULL),
|
||||
m_log_important(torrent::log_open_log_buffer("important")),
|
||||
m_log_complete(torrent::log_open_log_buffer("complete"))
|
||||
{
|
||||
m_downloadStore = new DownloadStore();
|
||||
m_downloadList = new DownloadList();
|
||||
m_fileStatusCache = new FileStatusCache();
|
||||
m_httpQueue = new HttpQueue();
|
||||
m_httpStack = new CurlStack();
|
||||
m_log_important(torrent::log_open_log_buffer("important")),
|
||||
m_log_complete(torrent::log_open_log_buffer("complete")) {
|
||||
|
||||
m_download_store = std::make_unique<DownloadStore>();
|
||||
m_download_list = std::make_unique<DownloadList>();
|
||||
m_file_status_cache = std::make_unique<FileStatusCache>();
|
||||
m_http_queue = std::make_unique<HttpQueue>();
|
||||
m_http_stack = std::make_unique<CurlStack>();
|
||||
|
||||
torrent::Throttle* unthrottled = torrent::Throttle::create_throttle();
|
||||
unthrottled->set_max_rate(0);
|
||||
@@ -68,19 +66,12 @@ Manager::Manager() :
|
||||
|
||||
Manager::~Manager() {
|
||||
torrent::Throttle::destroy_throttle(m_throttles["NULL"].first);
|
||||
delete m_downloadList;
|
||||
|
||||
// TODO: Clean up logs objects.
|
||||
|
||||
delete m_downloadStore;
|
||||
delete m_httpQueue;
|
||||
delete m_fileStatusCache;
|
||||
}
|
||||
|
||||
void
|
||||
Manager::set_hashing_view(View* v) {
|
||||
if (v == NULL || m_hashingView != NULL)
|
||||
throw torrent::internal_error("Manager::set_hashing_view(...) received NULL or is already set.");
|
||||
if (v == nullptr || m_hashingView != nullptr)
|
||||
throw torrent::internal_error("Manager::set_hashing_view(...) received nullptr or is already set.");
|
||||
|
||||
m_hashingView = v;
|
||||
m_hashingView->signal_changed().push_back(std::bind(&Manager::receive_hashing_changed, this));
|
||||
@@ -89,12 +80,12 @@ Manager::set_hashing_view(View* v) {
|
||||
torrent::ThrottlePair
|
||||
Manager::get_throttle(const std::string& name) {
|
||||
ThrottleMap::const_iterator itr = m_throttles.find(name);
|
||||
torrent::ThrottlePair throttles = (itr == m_throttles.end() ? torrent::ThrottlePair(NULL, NULL) : itr->second);
|
||||
torrent::ThrottlePair throttles = (itr == m_throttles.end() ? torrent::ThrottlePair(nullptr, nullptr) : itr->second);
|
||||
|
||||
if (throttles.first == NULL)
|
||||
if (throttles.first == nullptr)
|
||||
throttles.first = torrent::up_throttle_global();
|
||||
|
||||
if (throttles.second == NULL)
|
||||
if (throttles.second == nullptr)
|
||||
throttles.second = torrent::down_throttle_global();
|
||||
|
||||
return throttles;
|
||||
@@ -108,7 +99,7 @@ Manager::set_address_throttle(uint32_t begin, uint32_t end, torrent::ThrottlePai
|
||||
|
||||
torrent::ThrottlePair
|
||||
Manager::get_address_throttle(const sockaddr* addr) {
|
||||
return m_addressThrottles.get(rak::socket_address::cast_from(addr)->sa_inet()->address_h(), torrent::ThrottlePair(NULL, NULL));
|
||||
return m_addressThrottles.get(rak::socket_address::cast_from(addr)->sa_inet()->address_h(), torrent::ThrottlePair(nullptr, nullptr));
|
||||
}
|
||||
|
||||
int64_t
|
||||
@@ -121,7 +112,7 @@ Manager::retrieve_throttle_value(const torrent::Object::string_type& name, bool
|
||||
torrent::Throttle* throttle = up ? itr->second.first : itr->second.second;
|
||||
|
||||
// check whether the actual up/down throttle exist (one of the pair can be missing)
|
||||
if (throttle == NULL)
|
||||
if (throttle == nullptr)
|
||||
return (int64_t)-1;
|
||||
|
||||
int64_t throttle_max = (int64_t)throttle->max_rate();
|
||||
@@ -143,36 +134,36 @@ Manager::retrieve_throttle_value(const torrent::Object::string_type& name, bool
|
||||
// Most of this should be possible to move out.
|
||||
void
|
||||
Manager::initialize_second() {
|
||||
torrent::Http::slot_factory() = std::bind(&CurlStack::new_object, m_httpStack);
|
||||
m_httpQueue->set_slot_factory(std::bind(&CurlStack::new_object, m_httpStack));
|
||||
torrent::Http::slot_factory() = std::bind(&CurlStack::new_object, m_http_stack.get());
|
||||
m_http_queue->set_slot_factory(std::bind(&CurlStack::new_object, m_http_stack.get()));
|
||||
|
||||
CurlStack::global_init();
|
||||
}
|
||||
|
||||
void
|
||||
Manager::cleanup() {
|
||||
m_httpStack->shutdown();
|
||||
m_http_stack->shutdown();
|
||||
|
||||
// Need to disconnect log signals? Not really since we won't receive
|
||||
// any more.
|
||||
|
||||
m_downloadList->clear();
|
||||
m_download_list->clear();
|
||||
|
||||
// When we implement asynchronous DNS lookups, we need to cancel them
|
||||
// here before the torrent::* objects are deleted.
|
||||
|
||||
torrent::cleanup();
|
||||
|
||||
delete m_httpStack;
|
||||
m_http_stack.reset();
|
||||
CurlStack::global_cleanup();
|
||||
}
|
||||
|
||||
void
|
||||
Manager::shutdown(bool force) {
|
||||
if (!force)
|
||||
std::for_each(m_downloadList->begin(), m_downloadList->end(), [this](Download* d) { m_downloadList->pause_default(d); });
|
||||
std::for_each(m_download_list->begin(), m_download_list->end(), [this](Download* d) { m_download_list->pause_default(d); });
|
||||
else
|
||||
std::for_each(m_downloadList->begin(), m_downloadList->end(), [this](Download* d) { m_downloadList->close_quick(d); });
|
||||
std::for_each(m_download_list->begin(), m_download_list->end(), [this](Download* d) { m_download_list->close_quick(d); });
|
||||
}
|
||||
|
||||
void
|
||||
@@ -226,7 +217,7 @@ Manager::set_bind_address(const std::string& addr) {
|
||||
if ((err = rak::address_info::get_address_info(addr.c_str(), PF_INET, SOCK_STREAM, &ai)) != 0 &&
|
||||
(err = rak::address_info::get_address_info(addr.c_str(), PF_INET6, SOCK_STREAM, &ai)) != 0)
|
||||
throw torrent::input_error("Could not set bind address: " + std::string(rak::address_info::strerror(err)) + ".");
|
||||
|
||||
|
||||
try {
|
||||
|
||||
if (torrent::connection_manager()->listen_port() != 0) {
|
||||
@@ -238,7 +229,7 @@ Manager::set_bind_address(const std::string& addr) {
|
||||
torrent::connection_manager()->set_bind_address(ai->address()->c_sockaddr());
|
||||
}
|
||||
|
||||
m_httpStack->set_bind_address(!ai->address()->is_address_any() ? ai->address()->address_str() : std::string());
|
||||
m_http_stack->set_bind_address(!ai->address()->is_address_any() ? ai->address()->address_str() : std::string());
|
||||
|
||||
rak::address_info::free_address_info(ai);
|
||||
|
||||
@@ -261,7 +252,7 @@ Manager::set_local_address(const std::string& addr) {
|
||||
if ((err = rak::address_info::get_address_info(addr.c_str(), PF_INET, SOCK_STREAM, &ai)) != 0 &&
|
||||
(err = rak::address_info::get_address_info(addr.c_str(), PF_INET6, SOCK_STREAM, &ai)) != 0)
|
||||
throw torrent::input_error("Could not set local address: " + std::string(rak::address_info::strerror(err)) + ".");
|
||||
|
||||
|
||||
try {
|
||||
|
||||
torrent::connection_manager()->set_local_address(ai->address()->c_sockaddr());
|
||||
@@ -283,9 +274,9 @@ Manager::set_proxy_address(const std::string& addr) {
|
||||
int port;
|
||||
rak::address_info* ai;
|
||||
|
||||
char buf[addr.length() + 1];
|
||||
std::string buf(addr.length() + 1, '\0');
|
||||
|
||||
int err = std::sscanf(addr.c_str(), "%[^:]:%i", buf, &port);
|
||||
int err = std::sscanf(addr.c_str(), "%[^:]:%i", buf.data(), &port);
|
||||
|
||||
if (err <= 0)
|
||||
throw torrent::input_error("Could not parse proxy address.");
|
||||
@@ -293,7 +284,7 @@ Manager::set_proxy_address(const std::string& addr) {
|
||||
if (err == 1)
|
||||
port = 80;
|
||||
|
||||
if ((err = rak::address_info::get_address_info(buf, PF_INET, SOCK_STREAM, &ai)) != 0)
|
||||
if ((err = rak::address_info::get_address_info(buf.data(), PF_INET, SOCK_STREAM, &ai)) != 0)
|
||||
throw torrent::input_error("Could not set proxy address: " + std::string(rak::address_info::strerror(err)) + ".");
|
||||
|
||||
try {
|
||||
@@ -477,13 +468,13 @@ void
|
||||
Manager::receive_hashing_changed() {
|
||||
bool foundHashing = std::find_if(m_hashingView->begin_visible(), m_hashingView->end_visible(),
|
||||
std::mem_fn(&Download::is_hash_checking)) != m_hashingView->end_visible();
|
||||
|
||||
|
||||
// Try quick hashing all those with hashing == initial, set them to
|
||||
// something else when failed.
|
||||
for (View::iterator itr = m_hashingView->begin_visible(), last = m_hashingView->end_visible(); itr != last; ++itr) {
|
||||
if ((*itr)->is_hash_checked())
|
||||
throw torrent::internal_error("core::Manager::receive_hashing_changed() (*itr)->is_hash_checked().");
|
||||
|
||||
|
||||
if ((*itr)->is_hash_checking() || (*itr)->is_hash_failed())
|
||||
continue;
|
||||
|
||||
@@ -495,7 +486,7 @@ Manager::receive_hashing_changed() {
|
||||
continue;
|
||||
|
||||
try {
|
||||
m_downloadList->open_throw(*itr);
|
||||
m_download_list->open_throw(*itr);
|
||||
|
||||
// Since the bitfield is allocated on loading of resume load or
|
||||
// hash start, and unallocated on close, we know that if it it
|
||||
|
||||
+12
-16
@@ -4,13 +4,11 @@
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <torrent/utils/log_buffer.h>
|
||||
#include <torrent/connection_manager.h>
|
||||
#include <torrent/object.h>
|
||||
|
||||
#include "download_list.h"
|
||||
#include "poll_manager.h"
|
||||
#include "range_map.h"
|
||||
|
||||
namespace torrent {
|
||||
@@ -23,6 +21,7 @@ class FileStatusCache;
|
||||
|
||||
namespace core {
|
||||
|
||||
class CurlStack;
|
||||
class DownloadStore;
|
||||
class HttpQueue;
|
||||
|
||||
@@ -35,18 +34,15 @@ public:
|
||||
typedef DownloadList::iterator DListItr;
|
||||
typedef utils::FileStatusCache FileStatusCache;
|
||||
|
||||
// typedef std::function<void (DownloadList::iterator)> slot_ready;
|
||||
// typedef std::function<void ()> slot_void;
|
||||
|
||||
Manager();
|
||||
~Manager();
|
||||
|
||||
DownloadList* download_list() { return m_downloadList; }
|
||||
DownloadStore* download_store() { return m_downloadStore; }
|
||||
FileStatusCache* file_status_cache() { return m_fileStatusCache; }
|
||||
DownloadList* download_list() { return m_download_list.get(); }
|
||||
DownloadStore* download_store() { return m_download_store.get(); }
|
||||
FileStatusCache* file_status_cache() { return m_file_status_cache.get(); }
|
||||
|
||||
HttpQueue* http_queue() { return m_httpQueue; }
|
||||
CurlStack* http_stack() { return m_httpStack; }
|
||||
HttpQueue* http_queue() { return m_http_queue.get(); }
|
||||
CurlStack* http_stack() { return m_http_stack.get(); }
|
||||
|
||||
View* hashing_view() { return m_hashingView; }
|
||||
void set_hashing_view(View* v);
|
||||
@@ -109,13 +105,13 @@ private:
|
||||
void receive_http_failed(std::string msg);
|
||||
void receive_hashing_changed();
|
||||
|
||||
DownloadList* m_downloadList;
|
||||
DownloadStore* m_downloadStore;
|
||||
FileStatusCache* m_fileStatusCache;
|
||||
HttpQueue* m_httpQueue;
|
||||
CurlStack* m_httpStack;
|
||||
std::unique_ptr<DownloadList> m_download_list;
|
||||
std::unique_ptr<DownloadStore> m_download_store;
|
||||
std::unique_ptr<FileStatusCache> m_file_status_cache;
|
||||
std::unique_ptr<HttpQueue> m_http_queue;
|
||||
std::unique_ptr<CurlStack> m_http_stack;
|
||||
|
||||
View* m_hashingView;
|
||||
View* m_hashingView{};
|
||||
|
||||
ThrottleMap m_throttles;
|
||||
AddressThrottleMap m_addressThrottles;
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <unistd.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/poll_epoll.h>
|
||||
#include <torrent/poll_kqueue.h>
|
||||
#include <torrent/poll_select.h>
|
||||
|
||||
#include "globals.h"
|
||||
#include "control.h"
|
||||
#include "manager.h"
|
||||
#include "poll_manager.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
torrent::Poll*
|
||||
create_poll() {
|
||||
const char* poll_name = getenv("RTORRENT_POLL");
|
||||
|
||||
int maxOpen = sysconf(_SC_OPEN_MAX);
|
||||
|
||||
torrent::Poll* poll = NULL;
|
||||
|
||||
if (poll_name != NULL) {
|
||||
if (!strcmp(poll_name, "epoll"))
|
||||
poll = torrent::PollEPoll::create(maxOpen);
|
||||
else if (!strcmp(poll_name, "kqueue"))
|
||||
poll = torrent::PollKQueue::create(maxOpen);
|
||||
else if (!strcmp(poll_name, "select"))
|
||||
poll = torrent::PollSelect::create(maxOpen);
|
||||
|
||||
if (poll == NULL)
|
||||
control->core()->push_log_std(std::string("Cannot enable '") + poll_name + "' based polling.");
|
||||
}
|
||||
|
||||
if (poll != NULL)
|
||||
control->core()->push_log_std(std::string("Using '") + poll_name + "' based polling.");
|
||||
|
||||
else if ((poll = torrent::PollEPoll::create(maxOpen)) != NULL)
|
||||
control->core()->push_log_std("Using 'epoll' based polling.");
|
||||
|
||||
else if ((poll = torrent::PollKQueue::create(maxOpen)) != NULL)
|
||||
control->core()->push_log_std("Using 'kqueue' based polling.");
|
||||
|
||||
else if ((poll = torrent::PollSelect::create(maxOpen)) != NULL)
|
||||
control->core()->push_log_std("Using 'select' based polling.");
|
||||
|
||||
else
|
||||
throw torrent::internal_error("Could not create any Poll object.");
|
||||
|
||||
return poll;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_CORE_POLL_MANAGER_H
|
||||
#define RTORRENT_CORE_POLL_MANAGER_H
|
||||
|
||||
#include "curl_stack.h"
|
||||
|
||||
namespace torrent {
|
||||
class Poll;
|
||||
}
|
||||
|
||||
namespace core {
|
||||
|
||||
torrent::Poll* create_poll();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#ifndef RTORRENT_CORE_RANGE_MAP_H
|
||||
#define RTORRENT_CORE_RANGE_MAP_H
|
||||
@@ -57,7 +55,7 @@ class RangeMap : private std::map<Key, std::pair<Key, T>, Compare,
|
||||
//std::allocator_traits<Alloc>::template rebind_alloc<std::pair<const Key, std::pair<Key, T>>>
|
||||
|
||||
public:
|
||||
RangeMap() {}
|
||||
RangeMap() = default;
|
||||
RangeMap(const Compare& c) : base_type(c) {}
|
||||
|
||||
typedef typename base_type::iterator iterator;
|
||||
|
||||
+3
-4
@@ -113,7 +113,7 @@ struct view_downloads_filter : std::function<bool (Download*)> {
|
||||
|
||||
void
|
||||
View::emit_changed() {
|
||||
priority_queue_update(&taskScheduler, &m_delayChanged, cachedTime);
|
||||
torrent::this_thread::scheduler()->update_wait_for(&m_delay_changed, 0ms);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -127,7 +127,7 @@ View::~View() {
|
||||
return;
|
||||
|
||||
clear_filter_on();
|
||||
priority_queue_erase(&taskScheduler, &m_delayChanged);
|
||||
torrent::this_thread::scheduler()->erase(&m_delay_changed);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -148,8 +148,7 @@ View::initialize(const std::string& name) {
|
||||
m_size = base_type::size();
|
||||
m_focus = 0;
|
||||
|
||||
set_last_changed(rak::timer());
|
||||
m_delayChanged.slot() = std::bind(&View::emit_changed_now, this);
|
||||
m_delay_changed.slot() = [this]() { emit_changed_now(); };
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+8
-8
@@ -14,11 +14,11 @@
|
||||
#define RTORRENT_CORE_VIEW_DOWNLOADS_H
|
||||
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <rak/timer.h>
|
||||
#include <torrent/object.h>
|
||||
#include <torrent/utils/scheduler.h>
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
|
||||
using base_type::size_type;
|
||||
|
||||
View() {}
|
||||
View() = default;
|
||||
~View();
|
||||
|
||||
void initialize(const std::string& name);
|
||||
@@ -113,8 +113,8 @@ public:
|
||||
//
|
||||
// Currently initialized to rak::timer(), though perhaps we should
|
||||
// use cachedTimer.
|
||||
rak::timer last_changed() const { return m_lastChanged; }
|
||||
void set_last_changed(const rak::timer& t = ::cachedTime) { m_lastChanged = t; }
|
||||
auto last_changed() const { return m_last_changed; }
|
||||
void set_last_changed(std::chrono::microseconds t = torrent::this_thread::cached_time()) { m_last_changed = t; }
|
||||
|
||||
// Don't connect any slots until after initialize else it get's
|
||||
// triggered when adding the Download's in DownloadList.
|
||||
@@ -151,10 +151,10 @@ private:
|
||||
torrent::Object m_event_added;
|
||||
torrent::Object m_event_removed;
|
||||
|
||||
rak::timer m_lastChanged;
|
||||
std::chrono::microseconds m_last_changed{};
|
||||
|
||||
signal_void m_signal_changed;
|
||||
rak::priority_item m_delayChanged;
|
||||
signal_void m_signal_changed;
|
||||
torrent::utils::SchedulerEntry m_delay_changed;
|
||||
};
|
||||
|
||||
} // namespace core
|
||||
|
||||
@@ -1,39 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -92,7 +56,7 @@ void
|
||||
ViewManager::sort(const std::string& name, uint32_t timeout) {
|
||||
iterator viewItr = find_throw(name);
|
||||
|
||||
if ((*viewItr)->last_changed() + rak::timer::from_seconds(timeout) > cachedTime)
|
||||
if ((*viewItr)->last_changed() + std::chrono::seconds(timeout) > torrent::this_thread::cached_time())
|
||||
return;
|
||||
|
||||
// Should we rename sort, or add a seperate function?
|
||||
|
||||
+3
-39
@@ -1,39 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_CORE_VIEW_MANAGER_H
|
||||
#define RTORRENT_CORE_VIEW_MANAGER_H
|
||||
|
||||
@@ -48,12 +12,12 @@ class ViewManager : public rak::unordered_vector<View*> {
|
||||
public:
|
||||
typedef rak::unordered_vector<View*> base_type;
|
||||
typedef std::list<std::string> filter_args;
|
||||
|
||||
|
||||
using base_type::iterator;
|
||||
using base_type::const_iterator;
|
||||
using base_type::reverse_iterator;
|
||||
using base_type::const_reverse_iterator;
|
||||
|
||||
|
||||
using base_type::size_type;
|
||||
|
||||
using base_type::begin;
|
||||
@@ -64,7 +28,7 @@ public:
|
||||
using base_type::empty;
|
||||
using base_type::size;
|
||||
|
||||
ViewManager() {}
|
||||
ViewManager() = default;
|
||||
~ViewManager() { clear(); }
|
||||
|
||||
// Ffff... Just throwing together an interface, need to think some
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
static const int color_invalid = ~int();
|
||||
static const int color_default = 0;
|
||||
|
||||
Attributes() {}
|
||||
Attributes() = default;
|
||||
Attributes(const char* pos, int attr, int col) :
|
||||
m_position(pos), m_attributes(attr), m_colors(col) {}
|
||||
Attributes(const char* pos, const Attributes& old) :
|
||||
|
||||
@@ -106,7 +106,7 @@ Canvas::build_colors() {
|
||||
return;
|
||||
|
||||
// basic color names, index maps to ncurses COLOR_*
|
||||
static const char* color_names[] = {
|
||||
static constexpr std::array color_names{
|
||||
"black", "red", "green", "yellow", "blue", "magenta", "cyan", "white"};
|
||||
|
||||
// Those hold the background colors of "odd" and "even"
|
||||
@@ -170,7 +170,7 @@ Canvas::build_colors() {
|
||||
// Check that fg & bg color index is valid
|
||||
if ((color[0] != -1 && color[0] >= get_colors()) || (color[1] != -1 && color[1] >= get_colors())) {
|
||||
char buf[33];
|
||||
sprintf(buf, "%d", get_colors());
|
||||
snprintf(buf, 33, "%d", get_colors());
|
||||
Canvas::cleanup();
|
||||
throw torrent::input_error(color_def + ": your terminal only supports " + buf + " colors.");
|
||||
}
|
||||
|
||||
@@ -136,7 +136,8 @@ Canvas::resize_term(std::pair<int, int> dim) {
|
||||
|
||||
inline unsigned int
|
||||
Canvas::get_x() {
|
||||
int x, __UNUSED y;
|
||||
int x;
|
||||
[[maybe_unused]] int y;
|
||||
if (!m_isDaemon) {
|
||||
getyx(m_window, y, x);
|
||||
} else {
|
||||
@@ -158,7 +159,8 @@ Canvas::get_y() {
|
||||
|
||||
inline unsigned int
|
||||
Canvas::width() {
|
||||
int x, __UNUSED y;
|
||||
int x;
|
||||
[[maybe_unused]] int y;
|
||||
if (!m_isDaemon) {
|
||||
getmaxyx(m_window, y, x);
|
||||
} else {
|
||||
@@ -259,7 +261,8 @@ Canvas::set_default_attributes(int attr) {
|
||||
|
||||
inline int
|
||||
Canvas::get_screen_width() {
|
||||
int x, __UNUSED y;
|
||||
int x;
|
||||
[[maybe_unused]] int y;
|
||||
if (!m_isDaemon) {
|
||||
getmaxyx(stdscr, y, x);
|
||||
} else {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef RTORRENT_DISPLAY_COLOR_MAP_H
|
||||
#define RTORRENT_DISPLAY_COLOR_MAP_H
|
||||
|
||||
#include <array>
|
||||
#include <map>
|
||||
|
||||
#include <curses.h>
|
||||
@@ -26,8 +27,8 @@ enum ColorKind {
|
||||
RCOLOR_MAX,
|
||||
};
|
||||
|
||||
static const char* color_vars[RCOLOR_MAX] = {
|
||||
0,
|
||||
static const std::array<const char*, RCOLOR_MAX> color_vars{
|
||||
nullptr,
|
||||
"ui.color.title",
|
||||
"ui.color.footer",
|
||||
"ui.color.focus",
|
||||
|
||||
+2
-13
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
@@ -47,15 +45,6 @@
|
||||
|
||||
namespace display {
|
||||
|
||||
Frame::Frame() :
|
||||
m_type(TYPE_NONE),
|
||||
|
||||
m_positionX(0),
|
||||
m_positionY(0),
|
||||
m_width(0),
|
||||
m_height(0) {
|
||||
}
|
||||
|
||||
bool
|
||||
Frame::is_width_dynamic() const {
|
||||
switch (m_type) {
|
||||
|
||||
+8
-12
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#ifndef RTORRENT_DISPLAY_FRAME_H
|
||||
#define RTORRENT_DISPLAY_FRAME_H
|
||||
@@ -56,7 +54,7 @@ public:
|
||||
};
|
||||
|
||||
struct bounds_type {
|
||||
bounds_type() {}
|
||||
bounds_type() = default;
|
||||
bounds_type(extent_type minW, extent_type minH, extent_type maxW, extent_type maxH) :
|
||||
minWidth(minW), minHeight(minH), maxWidth(maxW), maxHeight(maxH) {}
|
||||
|
||||
@@ -74,8 +72,6 @@ public:
|
||||
|
||||
static const size_type max_size = 5;
|
||||
|
||||
Frame();
|
||||
|
||||
bool is_width_dynamic() const;
|
||||
bool is_height_dynamic() const;
|
||||
|
||||
@@ -116,12 +112,12 @@ private:
|
||||
inline void balance_row(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
||||
inline void balance_column(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
||||
|
||||
Type m_type;
|
||||
Type m_type{TYPE_NONE};
|
||||
|
||||
uint32_t m_positionX;
|
||||
uint32_t m_positionY;
|
||||
uint32_t m_width;
|
||||
uint32_t m_height;
|
||||
uint32_t m_positionX{};
|
||||
uint32_t m_positionY{};
|
||||
uint32_t m_width{};
|
||||
uint32_t m_height{};
|
||||
|
||||
union {
|
||||
Window* m_window;
|
||||
|
||||
+29
-60
@@ -1,39 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdexcept>
|
||||
@@ -46,74 +10,79 @@
|
||||
|
||||
namespace display {
|
||||
|
||||
Manager::Manager() :
|
||||
m_forceRedraw(false) {
|
||||
Manager::Manager() {
|
||||
m_scheduler.external_set_thread_id(std::this_thread::get_id());
|
||||
|
||||
m_taskUpdate.slot() = std::bind(&Manager::receive_update, this);
|
||||
m_task_update.slot() = std::bind(&Manager::receive_update, this);
|
||||
}
|
||||
|
||||
Manager::~Manager() {
|
||||
priority_queue_erase(&taskScheduler, &m_taskUpdate);
|
||||
torrent::this_thread::scheduler()->erase(&m_task_update);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::force_redraw() {
|
||||
m_forceRedraw = true;
|
||||
m_force_redraw = true;
|
||||
}
|
||||
|
||||
void
|
||||
Manager::schedule(Window* w, rak::timer t) {
|
||||
rak::priority_queue_update(&m_scheduler, w->task_update(), t);
|
||||
schedule_update(50000);
|
||||
Manager::schedule(Window* w, std::chrono::microseconds t) {
|
||||
m_scheduler.external_set_cached_time(torrent::this_thread::cached_time());
|
||||
m_scheduler.update_wait_until(w->task_update(), t);
|
||||
|
||||
schedule_update(50ms);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::unschedule(Window* w) {
|
||||
rak::priority_queue_erase(&m_scheduler, w->task_update());
|
||||
schedule_update(50000);
|
||||
m_scheduler.external_set_cached_time(torrent::this_thread::cached_time());
|
||||
m_scheduler.erase(w->task_update());
|
||||
|
||||
schedule_update(50ms);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::adjust_layout() {
|
||||
Canvas::redraw_std();
|
||||
m_rootFrame.balance(0, 0, Canvas::get_screen_width(), Canvas::get_screen_height());
|
||||
m_root_frame.balance(0, 0, Canvas::get_screen_width(), Canvas::get_screen_height());
|
||||
|
||||
schedule_update(0);
|
||||
schedule_update(0ms);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::receive_update() {
|
||||
if (m_forceRedraw) {
|
||||
m_forceRedraw = false;
|
||||
if (m_force_redraw) {
|
||||
m_force_redraw = false;
|
||||
|
||||
display::Canvas::resize_term(display::Canvas::term_size());
|
||||
Canvas::redraw_std();
|
||||
|
||||
adjust_layout();
|
||||
m_rootFrame.redraw();
|
||||
m_root_frame.redraw();
|
||||
}
|
||||
|
||||
Canvas::refresh_std();
|
||||
|
||||
rak::priority_queue_perform(&m_scheduler, cachedTime);
|
||||
m_rootFrame.refresh();
|
||||
m_scheduler.external_perform(torrent::this_thread::cached_time());
|
||||
m_root_frame.refresh();
|
||||
|
||||
Canvas::do_update();
|
||||
|
||||
m_timeLastUpdate = cachedTime;
|
||||
schedule_update(50000);
|
||||
m_time_last_update = torrent::this_thread::cached_time();
|
||||
schedule_update(50ms);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::schedule_update(uint32_t minInterval) {
|
||||
Manager::schedule_update(std::chrono::microseconds min_interval) {
|
||||
if (m_scheduler.empty()) {
|
||||
rak::priority_queue_erase(&taskScheduler, &m_taskUpdate);
|
||||
torrent::this_thread::scheduler()->erase(&m_task_update);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_taskUpdate.is_queued() || m_taskUpdate.time() > m_scheduler.top()->time()) {
|
||||
rak::priority_queue_update(&taskScheduler, &m_taskUpdate, std::max(m_scheduler.top()->time(), m_timeLastUpdate + minInterval));
|
||||
}
|
||||
if (m_task_update.is_scheduled() && m_task_update.time() <= m_scheduler.front()->time())
|
||||
return;
|
||||
|
||||
torrent::this_thread::scheduler()->update_wait_until(&m_task_update, std::max(m_scheduler.front()->time(), m_time_last_update + min_interval));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
-48
@@ -1,44 +1,7 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_DISPLAY_MANAGER_H
|
||||
#define RTORRENT_DISPLAY_MANAGER_H
|
||||
|
||||
#include <list>
|
||||
#include <rak/priority_queue_default.h>
|
||||
#include <torrent/utils/scheduler.h>
|
||||
|
||||
#include "frame.h"
|
||||
|
||||
@@ -53,26 +16,24 @@ public:
|
||||
|
||||
void force_redraw();
|
||||
|
||||
void schedule(Window* w, rak::timer t);
|
||||
void schedule(Window* w, std::chrono::microseconds t);
|
||||
void unschedule(Window* w);
|
||||
|
||||
void adjust_layout();
|
||||
void receive_update();
|
||||
|
||||
// New interface.
|
||||
Frame* root_frame() { return &m_rootFrame; }
|
||||
Frame* root_frame() { return &m_root_frame; }
|
||||
|
||||
private:
|
||||
void schedule_update(uint32_t minInterval);
|
||||
void schedule_update(std::chrono::microseconds min_interval);
|
||||
|
||||
bool m_forceRedraw;
|
||||
rak::timer m_timeLastUpdate;
|
||||
bool m_force_redraw{false};
|
||||
Frame m_root_frame;
|
||||
|
||||
rak::priority_queue_default m_scheduler;
|
||||
rak::priority_item m_taskUpdate;
|
||||
|
||||
// New interface.
|
||||
Frame m_rootFrame;
|
||||
std::chrono::microseconds m_time_last_update{};
|
||||
torrent::utils::ExternalScheduler m_scheduler;
|
||||
torrent::utils::SchedulerEntry m_task_update;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#ifndef RTORRENT_DISPLAY_TEXT_ELEMENT_H
|
||||
#define RTORRENT_DISPLAY_TEXT_ELEMENT_H
|
||||
@@ -51,8 +49,8 @@ public:
|
||||
|
||||
static const extent_type extent_full = ~extent_type();
|
||||
|
||||
TextElement() {}
|
||||
virtual ~TextElement() {}
|
||||
TextElement() = default;
|
||||
virtual ~TextElement() = default;
|
||||
|
||||
// The last element must point to a valid memory location into which
|
||||
// the caller must write a '\0' to terminate the c string. The
|
||||
|
||||
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#ifndef RTORRENT_DISPLAY_TEXT_ELEMENT_LIST_H
|
||||
#define RTORRENT_DISPLAY_TEXT_ELEMENT_LIST_H
|
||||
@@ -61,7 +59,6 @@ public:
|
||||
|
||||
using base_type::push_back;
|
||||
|
||||
TextElementList() : m_column(0), m_columnWidth(0) {}
|
||||
virtual ~TextElementList() { clear(); }
|
||||
|
||||
void clear();
|
||||
@@ -74,8 +71,8 @@ public:
|
||||
virtual extent_type max_length();
|
||||
|
||||
private:
|
||||
unsigned int m_column;
|
||||
extent_type* m_columnWidth;
|
||||
unsigned int m_column{};
|
||||
extent_type* m_columnWidth{};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
@@ -29,10 +29,8 @@
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#ifndef RTORRENT_DISPLAY_TEXT_ELEMENT_STRING_H
|
||||
#define RTORRENT_DISPLAY_TEXT_ELEMENT_STRING_H
|
||||
|
||||
@@ -1,45 +1,10 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "display/text_element_value.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include "globals.h"
|
||||
#include "text_element_value.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
@@ -47,7 +12,7 @@ namespace display {
|
||||
void
|
||||
TextElement::push_attribute(Canvas::attributes_list* attributes, Attributes value) {
|
||||
Attributes base = attributes->back();
|
||||
|
||||
|
||||
if (value.colors() == Attributes::color_invalid)
|
||||
value.set_colors(base.colors());
|
||||
|
||||
@@ -69,12 +34,12 @@ TextElementValueBase::print(char* first, char* last, Canvas::attributes_list* at
|
||||
|
||||
// Transform the value if needed.
|
||||
if (m_flags & flag_elapsed)
|
||||
val = cachedTime.seconds() - val;
|
||||
val = torrent::this_thread::cached_seconds().count() - val;
|
||||
else if (m_flags & flag_remaining)
|
||||
val = val - cachedTime.seconds();
|
||||
val = val - torrent::this_thread::cached_seconds().count();
|
||||
|
||||
if (m_flags & flag_usec)
|
||||
val = rak::timer(val).seconds();
|
||||
val = torrent::utils::cast_seconds(std::chrono::microseconds(val)).count();
|
||||
|
||||
// Print the value.
|
||||
if (first == last) {
|
||||
@@ -108,7 +73,7 @@ TextElementValueBase::print(char* first, char* last, Canvas::attributes_list* at
|
||||
} else if (m_flags & flag_date) {
|
||||
time_t t = val;
|
||||
std::tm *u = std::gmtime(&t);
|
||||
|
||||
|
||||
if (u == NULL)
|
||||
return first;
|
||||
|
||||
@@ -117,7 +82,7 @@ TextElementValueBase::print(char* first, char* last, Canvas::attributes_list* at
|
||||
} else if (m_flags & flag_time) {
|
||||
time_t t = val;
|
||||
std::tm *u = std::gmtime(&t);
|
||||
|
||||
|
||||
if (u == NULL)
|
||||
return first;
|
||||
|
||||
|
||||
@@ -1,39 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_DISPLAY_TEXT_ELEMENT_VALUE_H
|
||||
#define RTORRENT_DISPLAY_TEXT_ELEMENT_VALUE_H
|
||||
|
||||
@@ -86,7 +50,7 @@ public:
|
||||
virtual extent_type max_length() { return 12; }
|
||||
|
||||
private:
|
||||
virtual int64_t value(void* object) { return m_value; }
|
||||
virtual int64_t value([[maybe_unused]] void* object) { return m_value; }
|
||||
|
||||
int64_t m_value;
|
||||
};
|
||||
@@ -104,7 +68,7 @@ public:
|
||||
virtual extent_type max_length() { return 12; }
|
||||
|
||||
private:
|
||||
virtual int64_t value(void* object) { return m_slot(); }
|
||||
virtual int64_t value([[maybe_unused]] void* object) { return m_slot(); }
|
||||
|
||||
slot_type m_slot;
|
||||
};
|
||||
|
||||
+20
-15
@@ -5,19 +5,18 @@
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <rak/socket_address.h>
|
||||
#include <rak/timer.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/connection_manager.h>
|
||||
#include <torrent/rate.h>
|
||||
#include <torrent/throttle.h>
|
||||
#include <torrent/torrent.h>
|
||||
#include <torrent/tracker_list.h>
|
||||
#include <torrent/tracker/tracker.h>
|
||||
#include <torrent/data/file_list.h>
|
||||
#include <torrent/data/file_manager.h>
|
||||
#include <torrent/download/resource_manager.h>
|
||||
#include <torrent/peer/client_info.h>
|
||||
|
||||
#include "core/curl_stack.h"
|
||||
#include "core/download.h"
|
||||
#include "core/manager.h"
|
||||
#include "rpc/parse_commands.h"
|
||||
@@ -160,14 +159,18 @@ print_download_status(char* first, char* last, core::Download* d) {
|
||||
first = print_buffer(first, last, "Checking hash [%2i%%]",
|
||||
(d->download()->chunks_hashed() * 100) / d->download()->file_list()->size_chunks());
|
||||
|
||||
} else if (d->tracker_list()->has_active_not_scrape()) {
|
||||
torrent::TrackerList::iterator itr =
|
||||
std::find_if(d->tracker_list()->begin(), d->tracker_list()->end(),
|
||||
std::mem_fn(&torrent::tracker::Tracker::is_busy_not_scrape));
|
||||
auto status = itr->status();
|
||||
} else if (d->tracker_controller().has_active_trackers_not_scrape()) {
|
||||
auto tracker = d->tracker_controller().find_if([](const auto& t) {
|
||||
return t.is_busy_not_scrape();
|
||||
});
|
||||
|
||||
first = print_buffer(first, last, "Tracker[%i:%i]: Connecting to %s %s",
|
||||
itr->group(), std::distance(d->tracker_list()->begin(), itr), itr->url().c_str(), status.c_str());
|
||||
if (tracker.is_valid()) {
|
||||
auto status = tracker.status();
|
||||
|
||||
first = print_buffer(first, last, "Tracker[%i]: Connecting to %s %s", tracker.group(), tracker.url().c_str(), status.c_str());
|
||||
} else {
|
||||
first = print_buffer(first, last, "Tracker: Connecting ...");
|
||||
}
|
||||
|
||||
} else if (!d->message().empty()) {
|
||||
first = print_buffer(first, last, "%s", d->message().c_str());
|
||||
@@ -185,7 +188,7 @@ print_download_status(char* first, char* last, core::Download* d) {
|
||||
char*
|
||||
print_download_column_compact(char* first, char* last) {
|
||||
first = print_buffer(first, last, " %-64.64s", "Name");
|
||||
first = print_buffer(first, last, "| Status | Downloaded | Size | Done | Up Rate | Down Rate | Uploaded | ETA | Ratio| Misc ");
|
||||
first = print_buffer(first, last, "| Status | Downloaded | Size | Done | Up Rate | Down Rate | Uploaded | ETA | Ratio | Misc ");
|
||||
|
||||
if (first > last)
|
||||
throw torrent::internal_error("print_download_column_compact(...) wrote past end of the buffer.");
|
||||
@@ -201,7 +204,7 @@ print_download_info_compact(char* first, char* last, core::Download* d) {
|
||||
if (!d->download()->info()->is_open())
|
||||
first = print_buffer(first, last, " CLOSED ");
|
||||
else if (!d->download()->info()->is_active())
|
||||
first = print_buffer(first, last, " OPEN ");
|
||||
first = print_buffer(first, last, " OPEN ");
|
||||
else
|
||||
first = print_buffer(first, last, " ");
|
||||
|
||||
@@ -221,12 +224,14 @@ print_download_info_compact(char* first, char* last, core::Download* d) {
|
||||
first = print_buffer(first, last, "| %7.1f MB ", (double)d->info()->up_rate()->total() / (1 << 20));
|
||||
first = print_buffer(first, last, "| ");
|
||||
|
||||
if (d->download()->info()->is_active() && !d->is_done())
|
||||
if (d->download()->info()->is_active() && !d->is_done()) {
|
||||
first = print_download_time_left(first, last, d);
|
||||
else
|
||||
first = print_buffer(first, last, " ");
|
||||
first = print_buffer(first, last, " ");
|
||||
} else {
|
||||
first = print_buffer(first, last, " ");
|
||||
}
|
||||
|
||||
first = print_buffer(first, last, "| %4.2f ", (double)rpc::call_command_value("d.ratio", rpc::make_target(d)) / 1000.0);
|
||||
first = print_buffer(first, last, "| %5.2f ", (double)rpc::call_command_value("d.ratio", rpc::make_target(d)) / 1000.0);
|
||||
first = print_buffer(first, last, "| %c%c",
|
||||
rpc::call_command_string("d.tied_to_file", rpc::make_target(d)).empty() ? ' ' : 'T',
|
||||
rpc::call_command_value("d.ignore_commands", rpc::make_target(d)) == 0 ? ' ' : 'I',
|
||||
|
||||
+23
-49
@@ -1,70 +1,34 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "window.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace display {
|
||||
|
||||
Window::SlotTimer Window::m_slotSchedule;
|
||||
Window::SlotWindow Window::m_slotUnschedule;
|
||||
Window::Slot Window::m_slotAdjust;
|
||||
Window::SlotTimer Window::m_slot_schedule;
|
||||
Window::SlotWindow Window::m_slot_unschedule;
|
||||
Window::Slot Window::m_slot_adjust;
|
||||
|
||||
// When constructing the window we set flag_offscreen so that redraw
|
||||
// doesn't get triggered until after a successful Frame::balance call.
|
||||
|
||||
Window::Window(Canvas* canvas, int flags, extent_type minWidth, extent_type minHeight, extent_type maxWidth, extent_type maxHeight) :
|
||||
Window::Window(Canvas* canvas, int flags, extent_type min_width, extent_type min_height, extent_type max_width, extent_type max_height) :
|
||||
m_canvas(canvas),
|
||||
m_flags(flags | flag_offscreen),
|
||||
|
||||
m_minWidth(minWidth),
|
||||
m_minHeight(minHeight),
|
||||
m_min_width(min_width),
|
||||
m_min_height(min_height),
|
||||
|
||||
m_maxWidth(maxWidth),
|
||||
m_maxHeight(maxHeight) {
|
||||
m_max_width(max_width),
|
||||
m_max_height(max_height) {
|
||||
|
||||
m_taskUpdate.slot() = std::bind(&Window::redraw, this);
|
||||
m_task_update.slot() = [this] { redraw(); };
|
||||
}
|
||||
|
||||
Window::~Window() {
|
||||
if (is_active())
|
||||
m_slotUnschedule(this);
|
||||
m_slot_unschedule(this);
|
||||
|
||||
delete m_canvas;
|
||||
}
|
||||
@@ -82,7 +46,7 @@ Window::set_active(bool state) {
|
||||
|
||||
} else {
|
||||
m_flags &= ~flag_active;
|
||||
m_slotUnschedule(this);
|
||||
m_slot_unschedule(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,4 +61,14 @@ Window::resize(int x, int y, int w, int h) {
|
||||
m_canvas->resize(x, y, w, h);
|
||||
}
|
||||
|
||||
void
|
||||
Window::schedule_update(unsigned int wait_seconds) {
|
||||
if (wait_seconds == 0) {
|
||||
m_slot_schedule(this, torrent::utils::ceil_seconds(torrent::this_thread::cached_time() + 100ms));
|
||||
return;
|
||||
}
|
||||
|
||||
m_slot_schedule(this, torrent::utils::ceil_seconds(torrent::this_thread::cached_time() + 1s*wait_seconds));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+27
-60
@@ -1,44 +1,9 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_WINDOW_BASE_H
|
||||
#define RTORRENT_WINDOW_BASE_H
|
||||
|
||||
#include <rak/timer.h>
|
||||
#include <functional>
|
||||
#include <torrent/utils/scheduler.h>
|
||||
#include <torrent/utils/thread.h>
|
||||
|
||||
#include "canvas.h"
|
||||
#include "globals.h"
|
||||
@@ -51,9 +16,9 @@ class Window {
|
||||
public:
|
||||
typedef uint32_t extent_type;
|
||||
|
||||
typedef std::function<void()> Slot;
|
||||
typedef std::function<void(Window*)> SlotWindow;
|
||||
typedef std::function<void(Window*, rak::timer)> SlotTimer;
|
||||
typedef std::function<void()> Slot;
|
||||
typedef std::function<void(Window*)> SlotWindow;
|
||||
typedef std::function<void(Window*, std::chrono::microseconds)> SlotTimer;
|
||||
|
||||
static const int flag_active = (1 << 0);
|
||||
static const int flag_offscreen = (1 << 1);
|
||||
@@ -85,19 +50,19 @@ public:
|
||||
bool is_bottom() const { return m_flags & flag_bottom; }
|
||||
void set_bottom(bool state) { if (state) m_flags |= flag_bottom; else m_flags &= ~flag_bottom; }
|
||||
|
||||
bool is_width_dynamic() const { return m_maxWidth > m_minWidth; }
|
||||
bool is_height_dynamic() const { return m_maxHeight > m_minHeight; }
|
||||
bool is_width_dynamic() const { return m_max_width > m_min_width; }
|
||||
bool is_height_dynamic() const { return m_max_height > m_min_height; }
|
||||
|
||||
// Do not call mark_dirty() from withing redraw() as it may cause
|
||||
// infinite looping in the display scheduler.
|
||||
bool is_dirty() { return m_taskUpdate.is_queued(); }
|
||||
void mark_dirty() { if (!is_active()) return; m_slotSchedule(this, cachedTime); }
|
||||
bool is_dirty() { return m_task_update.is_scheduled(); }
|
||||
void mark_dirty() { if (!is_active()) return; m_slot_schedule(this, torrent::this_thread::cached_time()); }
|
||||
|
||||
extent_type min_width() const { return m_minWidth; }
|
||||
extent_type min_height() const { return m_minHeight; }
|
||||
extent_type min_width() const { return m_min_width; }
|
||||
extent_type min_height() const { return m_min_height; }
|
||||
|
||||
extent_type max_width() const { return std::max(m_maxWidth, m_minWidth); }
|
||||
extent_type max_height() const { return std::max(m_maxHeight, m_minHeight); }
|
||||
extent_type max_width() const { return std::max(m_max_width, m_min_width); }
|
||||
extent_type max_height() const { return std::max(m_max_height, m_min_height); }
|
||||
|
||||
extent_type width() const { return m_canvas->width(); }
|
||||
extent_type height() const { return m_canvas->height(); }
|
||||
@@ -107,32 +72,34 @@ public:
|
||||
|
||||
virtual void redraw() = 0;
|
||||
|
||||
rak::priority_item* task_update() { return &m_taskUpdate; }
|
||||
auto task_update() { return &m_task_update; }
|
||||
|
||||
// Slot for adjust and refresh.
|
||||
static void slot_schedule(SlotTimer s) { m_slotSchedule = s; }
|
||||
static void slot_unschedule(SlotWindow s) { m_slotUnschedule = s; }
|
||||
static void slot_adjust(Slot s) { m_slotAdjust = s; }
|
||||
static void slot_schedule(SlotTimer s) { m_slot_schedule = s; }
|
||||
static void slot_unschedule(SlotWindow s) { m_slot_unschedule = s; }
|
||||
static void slot_adjust(Slot s) { m_slot_adjust = s; }
|
||||
|
||||
protected:
|
||||
Window(const Window&);
|
||||
void operator = (const Window&);
|
||||
|
||||
static SlotTimer m_slotSchedule;
|
||||
static SlotWindow m_slotUnschedule;
|
||||
static Slot m_slotAdjust;
|
||||
void schedule_update(unsigned int wait_seconds = 0);
|
||||
|
||||
static SlotTimer m_slot_schedule;
|
||||
static SlotWindow m_slot_unschedule;
|
||||
static Slot m_slot_adjust;
|
||||
|
||||
Canvas* m_canvas;
|
||||
|
||||
int m_flags;
|
||||
|
||||
extent_type m_minWidth;
|
||||
extent_type m_minHeight;
|
||||
extent_type m_min_width;
|
||||
extent_type m_min_height;
|
||||
|
||||
extent_type m_maxWidth;
|
||||
extent_type m_maxHeight;
|
||||
extent_type m_max_width;
|
||||
extent_type m_max_height;
|
||||
|
||||
rak::priority_item m_taskUpdate;
|
||||
torrent::utils::SchedulerEntry m_task_update;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,39 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cmath>
|
||||
@@ -59,7 +23,7 @@ WindowDownloadChunksSeen::WindowDownloadChunksSeen(core::Download* d, unsigned i
|
||||
void
|
||||
WindowDownloadChunksSeen::redraw() {
|
||||
// TODO: Make this depend on tracker signal.
|
||||
m_slotSchedule(this, (cachedTime + rak::timer::from_seconds(10)).round_seconds());
|
||||
schedule_update(10);
|
||||
m_canvas->erase();
|
||||
|
||||
if (m_canvas->height() < 3 || m_canvas->width() < 18)
|
||||
@@ -77,7 +41,7 @@ WindowDownloadChunksSeen::redraw() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_download->is_done()) {
|
||||
if (!m_download->is_done()) {
|
||||
m_canvas->print(36, 0, "X downloaded missing queued downloading");
|
||||
m_canvas->print_char(50, 0, 'X' | A_BOLD);
|
||||
m_canvas->print_char(61, 0, 'X' | A_BOLD | A_UNDERLINE);
|
||||
|
||||
@@ -1,39 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_DISPLAY_WINDOW_DOWNLOAD_CHUNKS_SEEN_H
|
||||
#define RTORRENT_DISPLAY_WINDOW_DOWNLOAD_CHUNKS_SEEN_H
|
||||
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
namespace display {
|
||||
|
||||
WindowDownloadList::WindowDownloadList() :
|
||||
Window(new Canvas, 0, 120, 1, extent_full, extent_full),
|
||||
m_view(NULL) {
|
||||
Window(new Canvas, 0, 120, 1, extent_full, extent_full) {
|
||||
}
|
||||
|
||||
WindowDownloadList::~WindowDownloadList() {
|
||||
@@ -78,7 +77,7 @@ WindowDownloadList::redraw() {
|
||||
if (m_canvas->daemon())
|
||||
return;
|
||||
|
||||
m_slotSchedule(this, (cachedTime + rak::timer::from_seconds(1)).round_seconds());
|
||||
schedule_update();
|
||||
|
||||
m_canvas->erase();
|
||||
|
||||
@@ -117,15 +116,15 @@ WindowDownloadList::redraw() {
|
||||
++range.second;
|
||||
|
||||
int pos = 1;
|
||||
char buffer[m_canvas->width() + 1];
|
||||
char* last = buffer + m_canvas->width() - 2 + 1;
|
||||
std::string buffer(m_canvas->width() + 1, ' ');
|
||||
char* last = buffer.data() + m_canvas->width() - 2 + 1;
|
||||
|
||||
// Add a proper 'column info' method.
|
||||
if (layout_name == "compact") {
|
||||
print_download_column_compact(buffer, last);
|
||||
print_download_column_compact(buffer.data(), last);
|
||||
|
||||
m_canvas->set_default_attributes(A_BOLD);
|
||||
m_canvas->print(0, pos++, " %s", buffer);
|
||||
m_canvas->print(0, pos++, " %s", buffer.data());
|
||||
}
|
||||
|
||||
if (layout_name == "full") {
|
||||
@@ -135,16 +134,16 @@ WindowDownloadList::redraw() {
|
||||
ColorKind focus_color = is_focused ? RCOLOR_FOCUS : RCOLOR_LABEL;
|
||||
auto attr_color = get_attr_color(range.first);
|
||||
|
||||
print_download_title(buffer, last, *range.first);
|
||||
m_canvas->print(0, pos, "%c %s", focus_char, buffer);
|
||||
print_download_title(buffer.data(), last, *range.first);
|
||||
m_canvas->print(0, pos, "%c %s", focus_char, buffer.data());
|
||||
m_canvas->set_attr(2, pos++, -1, attr_color.first, attr_color.second);
|
||||
|
||||
print_download_info_full(buffer, last, *range.first);
|
||||
m_canvas->print(0, pos, "%c %s", focus_char, buffer);
|
||||
print_download_info_full(buffer.data(), last, *range.first);
|
||||
m_canvas->print(0, pos, "%c %s", focus_char, buffer.data());
|
||||
m_canvas->set_attr(2, pos++, -1, focus_color);
|
||||
|
||||
print_download_status(buffer, last, *range.first);
|
||||
m_canvas->print(0, pos, "%c %s", focus_char, buffer);
|
||||
print_download_status(buffer.data(), last, *range.first);
|
||||
m_canvas->print(0, pos, "%c %s", focus_char, buffer.data());
|
||||
m_canvas->set_attr(2, pos++, -1, focus_color);
|
||||
|
||||
range.first++;
|
||||
@@ -155,8 +154,8 @@ WindowDownloadList::redraw() {
|
||||
char focus_char = range.first == m_view->focus() ? '*' : ' ';
|
||||
auto attr_color = get_attr_color(range.first);
|
||||
|
||||
print_download_info_compact(buffer, last, *range.first);
|
||||
m_canvas->print(0, pos, "%c %s", focus_char, buffer);
|
||||
print_download_info_compact(buffer.data(), last, *range.first);
|
||||
m_canvas->print(0, pos, "%c %s", focus_char, buffer.data());
|
||||
m_canvas->set_attr(2, pos++, -1, attr_color.first, attr_color.second);
|
||||
|
||||
range.first++;
|
||||
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
int page_size();
|
||||
|
||||
private:
|
||||
core::View* m_view;
|
||||
core::View* m_view{};
|
||||
|
||||
std::pair<int, int> get_attr_color(core::View::iterator selected);
|
||||
signal_void_itr m_changed_itr;
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "window_download_statusbar.h"
|
||||
|
||||
#include <torrent/rate.h>
|
||||
#include <torrent/data/transfer_list.h>
|
||||
#include <torrent/tracker_controller.h>
|
||||
#include <torrent/tracker_list.h>
|
||||
#include <torrent/peer/connection_list.h>
|
||||
#include <torrent/peer/peer_list.h>
|
||||
|
||||
#include "canvas.h"
|
||||
#include "globals.h"
|
||||
#include "utils.h"
|
||||
#include "window_download_statusbar.h"
|
||||
|
||||
#include "core/download.h"
|
||||
|
||||
namespace display {
|
||||
@@ -26,17 +24,17 @@ WindowDownloadStatusbar::redraw() {
|
||||
if (m_canvas->daemon())
|
||||
return;
|
||||
|
||||
m_slotSchedule(this, (cachedTime + rak::timer::from_seconds(1)).round_seconds());
|
||||
schedule_update();
|
||||
|
||||
m_canvas->erase();
|
||||
|
||||
char buffer[m_canvas->width()];
|
||||
char* last = buffer + m_canvas->width() - 2;
|
||||
std::string buffer(m_canvas->width(), ' ');
|
||||
char* last = buffer.data() + m_canvas->width() - 2;
|
||||
|
||||
print_download_info_full(buffer, last, m_download);
|
||||
m_canvas->print(0, 0, "%s", buffer);
|
||||
print_download_info_full(buffer.data(), last, m_download);
|
||||
m_canvas->print(0, 0, "%s", buffer.data());
|
||||
|
||||
snprintf(buffer, last - buffer, "Peers: %i(%i) Min/Max: %i/%i Slots: U:%i/%i D:%i/%i U/I/C/A: %i/%i/%i/%i Unchoked: %u/%u Failed: %i",
|
||||
snprintf(buffer.data(), last - buffer.data(), "Peers: %i(%i) Min/Max: %i/%i Slots: U:%i/%i D:%i/%i U/I/C/A: %i/%i/%i/%i Unchoked: %u/%u Failed: %i",
|
||||
(int)m_download->download()->connection_list()->size(),
|
||||
(int)m_download->download()->peer_list()->available_list_size(),
|
||||
(int)m_download->download()->connection_list()->min_size(),
|
||||
@@ -53,13 +51,13 @@ WindowDownloadStatusbar::redraw() {
|
||||
(int)m_download->info()->download_unchoked(),
|
||||
(int)m_download->download()->transfer_list()->failed_count());
|
||||
|
||||
m_canvas->print(0, 1, "%s", buffer);
|
||||
m_canvas->print(0, 1, "%s", buffer.data());
|
||||
|
||||
print_download_status(buffer, last, m_download);
|
||||
print_download_status(buffer.data(), last, m_download);
|
||||
m_canvas->print(0, 2, "[%c:%i] %s",
|
||||
m_download->tracker_list()->has_active() ? 'C' : ' ',
|
||||
m_download->tracker_controller().has_active_trackers() ? 'C' : ' ',
|
||||
(int)(m_download->download()->tracker_controller().seconds_to_next_timeout()),
|
||||
buffer);
|
||||
buffer.data());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,39 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_WINDOW_DOWNLOAD_STATUSBAR_H
|
||||
#define RTORRENT_WINDOW_DOWNLOAD_STATUSBAR_H
|
||||
|
||||
|
||||
@@ -1,39 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cmath>
|
||||
@@ -48,7 +12,7 @@
|
||||
|
||||
namespace display {
|
||||
|
||||
WindowDownloadTransferList::WindowDownloadTransferList(core::Download* d, unsigned int *focus) :
|
||||
WindowDownloadTransferList::WindowDownloadTransferList(core::Download* d, [[maybe_unused]] unsigned int *focus) :
|
||||
Window(new Canvas, 0, 0, 0, extent_full, extent_full),
|
||||
m_download(d) {
|
||||
}
|
||||
@@ -56,7 +20,7 @@ WindowDownloadTransferList::WindowDownloadTransferList(core::Download* d, unsign
|
||||
void
|
||||
WindowDownloadTransferList::redraw() {
|
||||
// TODO: Make this depend on tracker signal.
|
||||
m_slotSchedule(this, (cachedTime + rak::timer::from_seconds(1)).round_seconds());
|
||||
schedule_update();
|
||||
m_canvas->erase();
|
||||
|
||||
if (m_canvas->height() < 3 || m_canvas->width() < 18)
|
||||
@@ -90,7 +54,7 @@ WindowDownloadTransferList::redraw() {
|
||||
if (bItr->is_finished()) {
|
||||
attr = A_REVERSE;
|
||||
id = key_id(bItr->leader()->const_peer_info());
|
||||
|
||||
|
||||
} else if (bItr->is_transfering()) {
|
||||
attr = A_BOLD;
|
||||
id = key_id(bItr->leader()->const_peer_info());
|
||||
@@ -121,22 +85,24 @@ WindowDownloadTransferList::rows() const {
|
||||
|
||||
char
|
||||
WindowDownloadTransferList::key_id(torrent::BlockTransfer::key_type key) {
|
||||
uint32_t oldestTime = cachedTime.seconds();
|
||||
uint32_t current_time = torrent::this_thread::cached_seconds().count();
|
||||
uint32_t oldest_time = current_time;
|
||||
|
||||
assigned_vector::iterator oldestItr = m_assigned.begin();
|
||||
|
||||
for (assigned_vector::iterator itr = m_assigned.begin(), last = m_assigned.end(); itr != last; ++itr) {
|
||||
if (itr->m_key == key) {
|
||||
itr->m_last = cachedTime.seconds();
|
||||
itr->m_last = torrent::this_thread::cached_seconds().count();
|
||||
return itr->m_id;
|
||||
}
|
||||
|
||||
if (itr->m_last < oldestTime) {
|
||||
oldestTime = itr->m_last;
|
||||
if (itr->m_last < oldest_time) {
|
||||
oldest_time = itr->m_last;
|
||||
oldestItr = itr;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldestItr == m_assigned.end() || cachedTime.seconds() - oldestTime <= 60) {
|
||||
if (oldestItr == m_assigned.end() || current_time - oldest_time <= 60) {
|
||||
// We didn't find any previously used id's to take over.
|
||||
|
||||
// Return 'f' when we run out of characters.
|
||||
@@ -145,7 +111,7 @@ WindowDownloadTransferList::key_id(torrent::BlockTransfer::key_type key) {
|
||||
|
||||
char id = 'A' + m_assigned.size();
|
||||
|
||||
m_assigned.push_back(assigned_type(key, cachedTime.seconds(), id));
|
||||
m_assigned.push_back(assigned_type(key, current_time, id));
|
||||
return id;
|
||||
|
||||
} else {
|
||||
|
||||
@@ -1,39 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_DISPLAY_WINDOW_DOWNLOAD_TRANSFER_LIST_H
|
||||
#define RTORRENT_DISPLAY_WINDOW_DOWNLOAD_TRANSFER_LIST_H
|
||||
|
||||
@@ -52,8 +16,8 @@ class WindowDownloadTransferList : public Window {
|
||||
public:
|
||||
struct assigned_type {
|
||||
assigned_type(torrent::BlockTransfer::key_type key, uint32_t last, char id) : m_key(key), m_last(last), m_id(id) { }
|
||||
|
||||
torrent::BlockTransfer::key_type m_key;
|
||||
|
||||
torrent::BlockTransfer::key_type m_key;
|
||||
uint32_t m_last;
|
||||
char m_id;
|
||||
};
|
||||
|
||||
@@ -25,15 +25,15 @@ WindowFileList::WindowFileList(const ui::ElementFileList* element) :
|
||||
// Convert std::string to std::wstring of given width (in screen positions),
|
||||
// taking into account that some characters may be occupying two screen positions.
|
||||
std::wstring
|
||||
wstring_width(const std::string& i_str, int width) {
|
||||
wchar_t result[width + 1];
|
||||
size_t length = std::mbstowcs(result, i_str.c_str(), width);
|
||||
wstring_width(const std::string& i_str, [[maybe_unused]] int width) {
|
||||
std::wstring result(width + 1, L' ');
|
||||
size_t length = std::mbstowcs(result.data(), i_str.c_str(), width);
|
||||
|
||||
// If not valid UTF-8 encoding, at least copy the printable characters.
|
||||
if (length == (size_t)-1) {
|
||||
wchar_t* out = result;
|
||||
wchar_t* out = result.data();
|
||||
|
||||
for (std::string::const_iterator itr = i_str.begin(); out != result + width && itr != i_str.end(); ++itr)
|
||||
for (std::string::const_iterator itr = i_str.begin(); out != result.data() + width && itr != i_str.end(); ++itr)
|
||||
if (!std::isprint(*itr, std::locale::classic()))
|
||||
*out++ = '?';
|
||||
else
|
||||
@@ -42,23 +42,23 @@ wstring_width(const std::string& i_str, int width) {
|
||||
*out = 0;
|
||||
}
|
||||
|
||||
int swidth = wcswidth(result, width);
|
||||
int swidth = wcswidth(result.data(), width);
|
||||
|
||||
// Limit to width if it's too wide already.
|
||||
if (swidth == -1 || swidth > width) {
|
||||
length = swidth = 0;
|
||||
|
||||
while (result[length]) {
|
||||
int next = ::wcwidth(result[length]);
|
||||
while (result.data()[length]) {
|
||||
int next = ::wcwidth(result.data()[length]);
|
||||
|
||||
// Unprintable character?
|
||||
if (next == -1) {
|
||||
result[length] = '?';
|
||||
result.data()[length] = '?';
|
||||
next = 1;
|
||||
}
|
||||
|
||||
if (swidth + next > width) {
|
||||
result[length] = 0;
|
||||
result.data()[length] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -69,18 +69,18 @@ wstring_width(const std::string& i_str, int width) {
|
||||
|
||||
// Pad with spaces to given width.
|
||||
while (swidth < width && length <= (unsigned int)width) {
|
||||
result[length++] = ' ';
|
||||
result.data()[length++] = ' ';
|
||||
swidth++;
|
||||
}
|
||||
|
||||
result[length] = 0;
|
||||
result.data()[length] = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
WindowFileList::redraw() {
|
||||
m_slotSchedule(this, (cachedTime + rak::timer::from_seconds(10)).round_seconds());
|
||||
schedule_update(10);
|
||||
m_canvas->erase();
|
||||
|
||||
torrent::FileList* fl = m_element->download()->download()->file_list();
|
||||
|
||||
@@ -1,39 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_DISPLAY_FILE_LIST_H
|
||||
#define RTORRENT_DISPLAY_FILE_LIST_H
|
||||
|
||||
|
||||
@@ -1,78 +1,52 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "display/window_http_queue.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "core/curl_get.h"
|
||||
#include "core/http_queue.h"
|
||||
|
||||
#include "canvas.h"
|
||||
#include "window_http_queue.h"
|
||||
#include "display/canvas.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
// TODO: Large downloads result in rtorrent not quiting on ^Q.
|
||||
|
||||
WindowHttpQueue::WindowHttpQueue(core::HttpQueue* q) :
|
||||
Window(new Canvas, 0, 0, 1, extent_full, 1),
|
||||
m_queue(q) {
|
||||
|
||||
|
||||
set_active(false);
|
||||
m_connInsert = m_queue->signal_insert().insert(m_queue->signal_insert().end(),
|
||||
std::bind(&WindowHttpQueue::receive_insert,
|
||||
this,
|
||||
std::placeholders::_1));
|
||||
m_connErase = m_queue->signal_erase().insert(m_queue->signal_insert().end(),
|
||||
std::bind(&WindowHttpQueue::receive_erase,
|
||||
this,
|
||||
std::placeholders::_1));
|
||||
m_conn_insert = m_queue->signal_insert().insert(m_queue->signal_insert().end(), [this](auto* h) { receive_insert(h); });
|
||||
m_conn_erase = m_queue->signal_erase().insert(m_queue->signal_insert().end(), [this](auto* h) { receive_erase(h); });
|
||||
|
||||
m_task_deactivate.slot() = [this] {
|
||||
if (!m_container.empty())
|
||||
return;
|
||||
|
||||
set_active(false);
|
||||
m_slot_adjust();
|
||||
|
||||
mark_dirty();
|
||||
};
|
||||
}
|
||||
|
||||
WindowHttpQueue::~WindowHttpQueue() {
|
||||
m_queue->signal_insert().erase(m_conn_insert);
|
||||
m_queue->signal_erase().erase(m_conn_erase);
|
||||
|
||||
torrent::this_thread::scheduler()->erase(&m_task_deactivate);
|
||||
}
|
||||
|
||||
void
|
||||
WindowHttpQueue::redraw() {
|
||||
m_slotSchedule(this, (cachedTime + rak::timer::from_seconds(1)).round_seconds());
|
||||
bool is_empty = m_container.empty();
|
||||
|
||||
schedule_update();
|
||||
cleanup_list();
|
||||
|
||||
if (m_container.empty()) {
|
||||
set_active(false);
|
||||
m_slotAdjust();
|
||||
|
||||
return;
|
||||
}
|
||||
if (!is_empty && m_container.empty())
|
||||
torrent::this_thread::scheduler()->update_wait_for(&m_task_deactivate, 5s);
|
||||
|
||||
m_canvas->erase();
|
||||
m_canvas->print(0, 0, "Http [%i]", m_queue->size());
|
||||
@@ -80,15 +54,15 @@ WindowHttpQueue::redraw() {
|
||||
unsigned int pos = 10;
|
||||
Container::iterator itr = m_container.begin();
|
||||
|
||||
while (itr != m_container.end() && pos + 20 < m_canvas->width()) {
|
||||
while (itr != m_container.end() && pos + 10 < m_canvas->width()) {
|
||||
if (itr->m_http == NULL)
|
||||
m_canvas->print(pos, 0, "%s done", itr->m_name.c_str());
|
||||
m_canvas->print(pos, 0, "[%s done]", itr->m_name.c_str());
|
||||
|
||||
else if (itr->m_http->size_total() == 0)
|
||||
m_canvas->print(pos, 0, "%s ---%%", itr->m_name.c_str());
|
||||
m_canvas->print(pos, 0, "[%s ---%%]", itr->m_name.c_str());
|
||||
|
||||
else
|
||||
m_canvas->print(pos, 0, "%s %3i%%", itr->m_name.c_str(), (int)(100.0 * itr->m_http->size_done() / itr->m_http->size_total()));
|
||||
m_canvas->print(pos, 0, "[%s %3i%%]", itr->m_name.c_str(), (int)(100.0 * itr->m_http->size_done() / itr->m_http->size_total()));
|
||||
|
||||
pos += itr->m_name.size() + 6;
|
||||
++itr;
|
||||
@@ -97,14 +71,14 @@ WindowHttpQueue::redraw() {
|
||||
|
||||
void
|
||||
WindowHttpQueue::cleanup_list() {
|
||||
for (Container::iterator itr = m_container.begin(); itr != m_container.end();)
|
||||
if (itr->m_http == NULL && itr->m_timer < cachedTime)
|
||||
for (Container::iterator itr = m_container.begin(); itr != m_container.end(); ) {
|
||||
if (itr->m_http == nullptr && itr->m_timer < torrent::this_thread::cached_time()) {
|
||||
itr = m_container.erase(itr);
|
||||
else
|
||||
++itr;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Bad, can't have this here as it is called from redraw().
|
||||
// mark_dirty();
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
@@ -124,8 +98,8 @@ WindowHttpQueue::create_name(core::CurlGet* h) {
|
||||
n.substr(n.size() - 8) == ".TORRENT"))
|
||||
n = n.substr(0, n.size() - 8);
|
||||
|
||||
if (n.size() > 30)
|
||||
n = n.substr(0, 30);
|
||||
if (n.size() > 20)
|
||||
n = n.substr(0, 20);
|
||||
|
||||
return n;
|
||||
}
|
||||
@@ -136,21 +110,21 @@ WindowHttpQueue::receive_insert(core::CurlGet* h) {
|
||||
|
||||
if (!is_active()) {
|
||||
set_active(true);
|
||||
m_slotAdjust();
|
||||
m_slot_adjust();
|
||||
}
|
||||
|
||||
|
||||
mark_dirty();
|
||||
}
|
||||
|
||||
void
|
||||
WindowHttpQueue::receive_erase(core::CurlGet* h) {
|
||||
Container::iterator itr = std::find_if(m_container.begin(), m_container.end(), [h](Node n) { return h == n.get_http(); });
|
||||
Container::iterator itr = std::find_if(m_container.begin(), m_container.end(), [h](Node& n) { return h == n.m_http; });
|
||||
|
||||
if (itr == m_container.end())
|
||||
throw std::logic_error("WindowHttpQueue::receive_erase(...) tried to remove an object we don't have");
|
||||
|
||||
itr->m_http = NULL;
|
||||
itr->m_timer = cachedTime + rak::timer::from_seconds(1);
|
||||
itr->m_http = nullptr;
|
||||
itr->m_timer = torrent::this_thread::cached_time() + 4s;
|
||||
|
||||
mark_dirty();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user