mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-06 10:12:30 +00:00
* Rewrote 'select' based polling in the client and finished the
'epoll' code. The client selects whichever is available on the current platform. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@510 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
@@ -22,7 +22,11 @@ libsub_core_a_SOURCES = \
|
||||
log.h \
|
||||
manager.cc \
|
||||
manager.h \
|
||||
poll.cc \
|
||||
poll.h
|
||||
poll_manager.cc \
|
||||
poll_manager.h \
|
||||
poll_manager_epoll.cc \
|
||||
poll_manager_epoll.h \
|
||||
poll_manager_select.cc \
|
||||
poll_manager_select.h
|
||||
|
||||
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
|
||||
|
||||
+17
-6
@@ -37,7 +37,9 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <curl/multi.h>
|
||||
#include <sigc++/bind.h>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
#include "rak/functional.h"
|
||||
@@ -89,10 +91,14 @@ CurlStack::perform() {
|
||||
} while (code == CURLM_CALL_MULTI_PERFORM);
|
||||
}
|
||||
|
||||
void
|
||||
CurlStack::fdset(fd_set* readfds, fd_set* writefds, fd_set* exceptfds, int* maxFd) {
|
||||
if (curl_multi_fdset((CURLM*)m_handle, readfds, writefds, exceptfds, maxFd) > 0)
|
||||
throw torrent::local_error("Error calling curl_multi_fdset");
|
||||
unsigned int
|
||||
CurlStack::fdset(fd_set* readfds, fd_set* writefds, fd_set* exceptfds) {
|
||||
int maxFd = 0;
|
||||
|
||||
if (curl_multi_fdset((CURLM*)m_handle, readfds, writefds, exceptfds, &maxFd) != 0)
|
||||
throw std::runtime_error("Error calling curl_multi_fdset");
|
||||
|
||||
return std::max(maxFd, 0);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -121,13 +127,18 @@ CurlStack::remove_get(CurlGet* get) {
|
||||
}
|
||||
|
||||
void
|
||||
CurlStack::init() {
|
||||
CurlStack::global_init() {
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
}
|
||||
|
||||
void
|
||||
CurlStack::cleanup() {
|
||||
CurlStack::global_cleanup() {
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
CurlStack::SlotFactory
|
||||
CurlStack::get_http_factory() {
|
||||
return sigc::bind(sigc::ptr_fun(&CurlGet::new_object), this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+16
-12
@@ -38,6 +38,7 @@
|
||||
#define RTORRENT_CORE_CURL_STACK_H
|
||||
|
||||
#include <list>
|
||||
#include <sigc++/slot.h>
|
||||
|
||||
namespace core {
|
||||
|
||||
@@ -47,34 +48,37 @@ class CurlStack {
|
||||
public:
|
||||
friend class CurlGet;
|
||||
|
||||
typedef std::list<CurlGet*> CurlGetList;
|
||||
typedef std::list<CurlGet*> CurlGetList;
|
||||
typedef sigc::slot0<CurlGet*> SlotFactory;
|
||||
|
||||
CurlStack();
|
||||
~CurlStack();
|
||||
|
||||
int get_size() const { return m_size; }
|
||||
bool is_busy() const { return !m_getList.empty(); }
|
||||
int get_size() const { return m_size; }
|
||||
bool is_busy() const { return !m_getList.empty(); }
|
||||
|
||||
void perform();
|
||||
void perform();
|
||||
|
||||
// TODO: Set fd_set's only once?
|
||||
void fdset(fd_set* readfds, fd_set* writefds, fd_set* exceptfds, int* maxFd);
|
||||
unsigned int fdset(fd_set* readfds, fd_set* writefds, fd_set* exceptfds);
|
||||
|
||||
static void init();
|
||||
static void cleanup();
|
||||
SlotFactory get_http_factory();
|
||||
|
||||
static void global_init();
|
||||
static void global_cleanup();
|
||||
|
||||
protected:
|
||||
void add_get(CurlGet* get);
|
||||
void remove_get(CurlGet* get);
|
||||
void add_get(CurlGet* get);
|
||||
void remove_get(CurlGet* get);
|
||||
|
||||
private:
|
||||
CurlStack(const CurlStack&);
|
||||
void operator = (const CurlStack&);
|
||||
|
||||
void* m_handle;
|
||||
void* m_handle;
|
||||
|
||||
int m_size;
|
||||
CurlGetList m_getList;
|
||||
int m_size;
|
||||
CurlGetList m_getList;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+16
-5
@@ -48,9 +48,11 @@
|
||||
#include <torrent/bencode.h>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
#include "curl_get.h"
|
||||
#include "download.h"
|
||||
#include "manager.h"
|
||||
#include "curl_get.h"
|
||||
#include "poll_manager_epoll.h"
|
||||
#include "poll_manager_select.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
@@ -69,17 +71,26 @@ Manager::Manager() :
|
||||
m_portFirst(6890),
|
||||
m_portLast(6999),
|
||||
m_checkHash(true) {
|
||||
|
||||
// Consider doing this somewhere else.
|
||||
if ((m_pollManager = PollManagerEPoll::create(sysconf(_SC_OPEN_MAX))) != NULL)
|
||||
m_logImportant.push_front("Using 'epoll' based polling");
|
||||
else if ((m_pollManager = PollManagerSelect::create(sysconf(_SC_OPEN_MAX))) != NULL)
|
||||
m_logImportant.push_front("Using 'select' based polling");
|
||||
else
|
||||
throw std::runtime_error("Could not create any PollManager");
|
||||
}
|
||||
|
||||
Manager::~Manager() {
|
||||
delete m_pollManager;
|
||||
}
|
||||
|
||||
void
|
||||
Manager::initialize() {
|
||||
torrent::Http::set_factory(m_poll.get_http_factory());
|
||||
m_httpQueue.slot_factory(m_poll.get_http_factory());
|
||||
torrent::Http::set_factory(m_pollManager->get_http_stack()->get_http_factory());
|
||||
m_httpQueue.slot_factory(m_pollManager->get_http_stack()->get_http_factory());
|
||||
|
||||
CurlStack::init();
|
||||
CurlStack::global_init();
|
||||
listen_open();
|
||||
|
||||
if (torrent::get_max_open_files() + torrent::get_max_open_sockets() + 32 > FD_SETSIZE) {
|
||||
@@ -125,7 +136,7 @@ Manager::cleanup() {
|
||||
// any more.
|
||||
|
||||
torrent::cleanup();
|
||||
CurlStack::cleanup();
|
||||
CurlStack::global_cleanup();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+3
-3
@@ -43,7 +43,7 @@
|
||||
#include "download_store.h"
|
||||
#include "hash_queue.h"
|
||||
#include "http_queue.h"
|
||||
#include "poll.h"
|
||||
#include "poll_manager.h"
|
||||
#include "log.h"
|
||||
|
||||
namespace torrent {
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
HashQueue& get_hash_queue() { return m_hashQueue; }
|
||||
HttpQueue& get_http_queue() { return m_httpQueue; }
|
||||
|
||||
Poll& get_poll() { return m_poll; }
|
||||
PollManager* get_poll_manager() { return m_pollManager; }
|
||||
Log& get_log_important() { return m_logImportant; }
|
||||
Log& get_log_complete() { return m_logComplete; }
|
||||
|
||||
@@ -108,7 +108,7 @@ private:
|
||||
HashQueue m_hashQueue;
|
||||
HttpQueue m_httpQueue;
|
||||
|
||||
Poll m_poll;
|
||||
PollManager* m_pollManager;
|
||||
Log m_logImportant;
|
||||
Log m_logComplete;
|
||||
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005, 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 <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <ncurses.h>
|
||||
#include <sigc++/bind.h>
|
||||
#include <torrent/torrent.h>
|
||||
#include <torrent/poll_select.h>
|
||||
#include <torrent/poll_epoll.h>
|
||||
|
||||
#include "poll.h"
|
||||
#include "curl_get.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
Poll::Poll() :
|
||||
m_readSet(new fd_set),
|
||||
m_writeSet(new fd_set),
|
||||
m_exceptSet(new fd_set),
|
||||
// m_torrentPoll(new torrent::PollSelect)
|
||||
m_torrentPoll(torrent::PollEPoll::create())
|
||||
{
|
||||
if (m_torrentPoll == NULL)
|
||||
throw std::runtime_error("Could not initialize torrent::PollEPoll");
|
||||
}
|
||||
|
||||
Poll::~Poll() {
|
||||
delete m_readSet;
|
||||
delete m_writeSet;
|
||||
delete m_exceptSet;
|
||||
delete m_torrentPoll;
|
||||
}
|
||||
|
||||
void
|
||||
Poll::poll(utils::Timer timeout) {
|
||||
// Do we want to clear m_maxFd in torrent::mark?
|
||||
//m_maxFd = 0;
|
||||
|
||||
FD_ZERO(m_readSet);
|
||||
FD_ZERO(m_writeSet);
|
||||
FD_ZERO(m_exceptSet);
|
||||
|
||||
FD_SET(0, m_readSet);
|
||||
|
||||
FD_SET(m_torrentPoll->get_fd(), m_readSet);
|
||||
m_maxFd = m_torrentPoll->get_fd();
|
||||
// m_maxFd = m_torrentPoll->mark(m_readSet, m_writeSet, m_exceptSet);
|
||||
|
||||
if (m_curlStack.is_busy()) {
|
||||
int n = 0;
|
||||
|
||||
m_curlStack.fdset(m_readSet, m_writeSet, m_exceptSet, &n);
|
||||
m_maxFd = std::max(m_maxFd, n);
|
||||
}
|
||||
|
||||
timeval t = std::min(timeout, utils::Timer(torrent::get_next_timeout())).tval();
|
||||
|
||||
if (m_maxFd >= FD_SETSIZE)
|
||||
throw std::runtime_error("Poll::work(): max fd >= FD_SETSIZE");
|
||||
|
||||
errno = 0;
|
||||
m_maxFd = select(m_maxFd + 1, m_readSet, m_writeSet, m_exceptSet, &t);
|
||||
|
||||
if (m_maxFd >= 0)
|
||||
return work();
|
||||
|
||||
if (errno == EINTR) {
|
||||
m_slotSelectInterrupted();
|
||||
return work_input();
|
||||
}
|
||||
|
||||
throw std::runtime_error("Poll::work(): select error");
|
||||
}
|
||||
|
||||
void
|
||||
Poll::work() {
|
||||
if (FD_ISSET(0, m_readSet))
|
||||
work_input();
|
||||
|
||||
if (m_curlStack.is_busy())
|
||||
m_curlStack.perform();
|
||||
|
||||
torrent::perform();
|
||||
if (FD_ISSET(m_torrentPoll->get_fd(), m_readSet)) {
|
||||
// m_torrentPoll->work(m_readSet, m_writeSet, m_exceptSet);
|
||||
m_torrentPoll->wait(0);
|
||||
m_torrentPoll->work();
|
||||
torrent::perform();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Poll::work_input() {
|
||||
int key;
|
||||
|
||||
while ((key = getch()) != ERR)
|
||||
m_slotReadStdin(key);
|
||||
}
|
||||
|
||||
Poll::SlotFactory
|
||||
Poll::get_http_factory() {
|
||||
return sigc::bind(sigc::ptr_fun(&core::CurlGet::new_object), &m_curlStack);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005, 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 <cerrno>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "poll_manager.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
PollManager::PollManager(int maxOpenSockets) {
|
||||
// Add a hack here to create larger fd_set's, depending on a USE
|
||||
// flag.
|
||||
|
||||
m_maxOpenSockets = maxOpenSockets;
|
||||
m_readSet = new fd_set;
|
||||
m_writeSet = new fd_set;
|
||||
m_errorSet = new fd_set;
|
||||
}
|
||||
|
||||
PollManager::~PollManager() {
|
||||
delete m_readSet;
|
||||
delete m_writeSet;
|
||||
delete m_errorSet;
|
||||
}
|
||||
|
||||
void
|
||||
PollManager::check_error() {
|
||||
if (errno != EINTR)
|
||||
throw std::runtime_error("Poll::work(): select error");
|
||||
|
||||
m_signalInterrupted.emit();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,59 +34,55 @@
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_CORE_POLL_H
|
||||
#define RTORRENT_CORE_POLL_H
|
||||
#ifndef RTORRENT_CORE_POLL_MANAGER_H
|
||||
#define RTORRENT_CORE_POLL_MANAGER_H
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <sigc++/slot.h>
|
||||
#include <sigc++/signal.h>
|
||||
|
||||
#include "utils/timer.h"
|
||||
#include "curl_stack.h"
|
||||
#include "utils/timer.h"
|
||||
|
||||
namespace torrent {
|
||||
class PollSelect;
|
||||
class PollEPoll;
|
||||
class Poll;
|
||||
}
|
||||
|
||||
namespace core {
|
||||
|
||||
class CurlGet;
|
||||
// CurlStack really should be somewhere else, but that won't happen
|
||||
// until they add an epoll friendly API.
|
||||
|
||||
class Poll {
|
||||
class PollManager {
|
||||
public:
|
||||
typedef sigc::slot0<void> Slot;
|
||||
typedef sigc::slot1<void, int> SlotInt;
|
||||
typedef sigc::slot0<CurlGet*> SlotFactory;
|
||||
typedef sigc::signal0<void> Signal;
|
||||
|
||||
Poll();
|
||||
~Poll();
|
||||
PollManager(int maxOpenSockets);
|
||||
virtual ~PollManager();
|
||||
|
||||
void poll(utils::Timer t);
|
||||
unsigned int get_max_open_sockets() const { return m_maxOpenSockets; }
|
||||
CurlStack* get_http_stack() { return &m_httpStack; }
|
||||
|
||||
SlotFactory get_http_factory();
|
||||
torrent::Poll* get_torrent_poll() { return reinterpret_cast<torrent::Poll*>(m_torrentPoll); }
|
||||
virtual torrent::Poll* get_torrent_poll() = 0;
|
||||
|
||||
void slot_read_stdin(SlotInt s) { m_slotReadStdin = s; }
|
||||
void slot_select_interrupted(Slot s) { m_slotSelectInterrupted = s; }
|
||||
virtual void poll(utils::Timer timeout) = 0;
|
||||
|
||||
private:
|
||||
Poll(const Poll&);
|
||||
void operator = (const Poll&);
|
||||
// Use a signal, connect checking for input and updating the display.
|
||||
Signal& signal_interrupted() { return m_signalInterrupted; }
|
||||
|
||||
void work();
|
||||
void work_input();
|
||||
protected:
|
||||
PollManager(const PollManager&);
|
||||
void operator = (const PollManager&);
|
||||
|
||||
SlotInt m_slotReadStdin;
|
||||
Slot m_slotSelectInterrupted;
|
||||
void check_error();
|
||||
|
||||
unsigned int m_maxOpenSockets;
|
||||
CurlStack m_httpStack;
|
||||
|
||||
int m_maxFd;
|
||||
fd_set* m_readSet;
|
||||
fd_set* m_writeSet;
|
||||
fd_set* m_exceptSet;
|
||||
fd_set* m_errorSet;
|
||||
|
||||
CurlStack m_curlStack;
|
||||
// torrent::PollSelect* m_torrentPoll;
|
||||
torrent::PollEPoll* m_torrentPoll;
|
||||
Signal m_signalInterrupted;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005, 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 <torrent/poll_epoll.h>
|
||||
#include <torrent/torrent.h>
|
||||
|
||||
#include "poll_manager_epoll.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
PollManagerEPoll*
|
||||
PollManagerEPoll::create(int maxOpenSockets) {
|
||||
torrent::PollEPoll* p = torrent::PollEPoll::create(maxOpenSockets);
|
||||
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
PollManagerEPoll* manager = new PollManagerEPoll(maxOpenSockets);
|
||||
manager->m_poll = p;
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
PollManagerEPoll::~PollManagerEPoll() {
|
||||
delete m_poll;
|
||||
}
|
||||
|
||||
torrent::Poll*
|
||||
PollManagerEPoll::get_torrent_poll() {
|
||||
return m_poll;
|
||||
}
|
||||
|
||||
void
|
||||
PollManagerEPoll::poll(utils::Timer timeout) {
|
||||
timeout = std::min(timeout, utils::Timer(torrent::get_next_timeout()));
|
||||
|
||||
if (m_httpStack.is_busy()) {
|
||||
// When we're using libcurl we need to use select, but as this is
|
||||
// inefficient we try avoiding it whenever possible.
|
||||
FD_ZERO(m_readSet);
|
||||
FD_ZERO(m_writeSet);
|
||||
FD_ZERO(m_errorSet);
|
||||
FD_SET(m_poll->get_fd(), m_readSet);
|
||||
|
||||
unsigned int maxFd = std::max((unsigned int)m_poll->get_fd(),
|
||||
m_httpStack.fdset(m_readSet, m_writeSet, m_errorSet));
|
||||
|
||||
if (maxFd >= m_maxOpenSockets)
|
||||
throw std::runtime_error("Error polling, maxFd >= m_maxOpenSockets");
|
||||
|
||||
timeval t = timeout.tval();
|
||||
|
||||
if (select(maxFd + 1, m_readSet, m_writeSet, m_errorSet, &t) == -1)
|
||||
return check_error();
|
||||
|
||||
m_httpStack.perform();
|
||||
|
||||
if (!FD_ISSET(m_poll->get_fd(), m_readSet))
|
||||
return;
|
||||
|
||||
// Clear the timeout since we've already used it in the select call.
|
||||
timeout = utils::Timer();
|
||||
}
|
||||
|
||||
// Yes, below is how much code really *should* have been in this
|
||||
// function. ;)
|
||||
torrent::perform();
|
||||
|
||||
if (m_poll->poll(timeout.usec() / 1000) == -1)
|
||||
return check_error();
|
||||
|
||||
m_poll->perform();
|
||||
torrent::perform();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005, 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_EPOLL_H
|
||||
#define RTORRENT_CORE_POLL_MANAGER_EPOLL_H
|
||||
|
||||
#include "poll_manager.h"
|
||||
|
||||
namespace torrent {
|
||||
class PollEPoll;
|
||||
}
|
||||
|
||||
namespace core {
|
||||
|
||||
class PollManagerEPoll : public PollManager {
|
||||
public:
|
||||
static PollManagerEPoll* create(int maxOpenSockets);
|
||||
~PollManagerEPoll();
|
||||
|
||||
torrent::Poll* get_torrent_poll();
|
||||
|
||||
void poll(utils::Timer timeout);
|
||||
|
||||
private:
|
||||
PollManagerEPoll(int maxOpenSockets) : PollManager(maxOpenSockets) {}
|
||||
|
||||
torrent::PollEPoll* m_poll;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,98 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005, 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 <torrent/poll_select.h>
|
||||
#include <torrent/torrent.h>
|
||||
|
||||
#include "poll_manager_select.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
PollManagerSelect*
|
||||
PollManagerSelect::create(int maxOpenSockets) {
|
||||
torrent::PollSelect* p = torrent::PollSelect::create(maxOpenSockets);
|
||||
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
PollManagerSelect* manager = new PollManagerSelect(maxOpenSockets);
|
||||
manager->m_poll = p;
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
PollManagerSelect::~PollManagerSelect() {
|
||||
delete m_poll;
|
||||
}
|
||||
|
||||
torrent::Poll*
|
||||
PollManagerSelect::get_torrent_poll() {
|
||||
return m_poll;
|
||||
}
|
||||
|
||||
void
|
||||
PollManagerSelect::poll(utils::Timer timeout) {
|
||||
timeout = std::min(timeout, utils::Timer(torrent::get_next_timeout()));
|
||||
|
||||
FD_ZERO(m_readSet);
|
||||
FD_ZERO(m_writeSet);
|
||||
FD_ZERO(m_errorSet);
|
||||
|
||||
unsigned int maxFd = m_poll->fdset(m_readSet, m_writeSet, m_errorSet);
|
||||
|
||||
if (m_httpStack.is_busy())
|
||||
maxFd = std::max(maxFd, m_httpStack.fdset(m_readSet, m_writeSet, m_errorSet));
|
||||
|
||||
if (maxFd >= m_maxOpenSockets)
|
||||
throw std::runtime_error("Error polling, maxFd >= m_maxOpenSockets");
|
||||
|
||||
timeval t = timeout.tval();
|
||||
|
||||
if (select(maxFd + 1, m_readSet, m_writeSet, m_errorSet, &t) == -1)
|
||||
return check_error();
|
||||
|
||||
if (m_httpStack.is_busy())
|
||||
m_httpStack.perform();
|
||||
|
||||
torrent::perform();
|
||||
m_poll->perform(m_readSet, m_writeSet, m_errorSet);
|
||||
torrent::perform();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005, 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_SELECT_H
|
||||
#define RTORRENT_CORE_POLL_MANAGER_SELECT_H
|
||||
|
||||
#include "poll_manager.h"
|
||||
|
||||
namespace torrent {
|
||||
class PollSelect;
|
||||
}
|
||||
|
||||
namespace core {
|
||||
|
||||
class PollManagerSelect : public PollManager {
|
||||
public:
|
||||
static PollManagerSelect* create(int maxOpenSockets);
|
||||
~PollManagerSelect();
|
||||
|
||||
torrent::Poll* get_torrent_poll();
|
||||
|
||||
void poll(utils::Timer timeout);
|
||||
|
||||
private:
|
||||
PollManagerSelect(int maxOpenSockets) : PollManager(maxOpenSockets) {}
|
||||
|
||||
torrent::PollSelect* m_poll;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -3,6 +3,8 @@ noinst_LIBRARIES = libsub_input.a
|
||||
libsub_input_a_SOURCES = \
|
||||
bindings.cc \
|
||||
bindings.h \
|
||||
input_event.cc \
|
||||
input_event.h \
|
||||
manager.cc \
|
||||
manager.h \
|
||||
path_input.cc \
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005, 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 <ncurses.h>
|
||||
|
||||
#include "input_event.h"
|
||||
|
||||
namespace input {
|
||||
|
||||
void
|
||||
InputEvent::insert(torrent::Poll* p) {
|
||||
p->open(this);
|
||||
p->insert_read(this);
|
||||
}
|
||||
|
||||
void
|
||||
InputEvent::remove(torrent::Poll* p) {
|
||||
p->remove_read(this);
|
||||
p->close(this);
|
||||
}
|
||||
|
||||
void
|
||||
InputEvent::event_read() {
|
||||
int c = getch();
|
||||
|
||||
if (c != ERR)
|
||||
m_slotPressed(c);
|
||||
}
|
||||
|
||||
void
|
||||
InputEvent::event_write() {
|
||||
}
|
||||
|
||||
void
|
||||
InputEvent::event_error() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005, 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_INPUT_INPUT_EVENT_H
|
||||
#define RTORRENT_INPUT_INPUT_EVENT_H
|
||||
|
||||
#include <sigc++/slot.h>
|
||||
#include <torrent/event.h>
|
||||
#include <torrent/poll.h>
|
||||
|
||||
namespace input {
|
||||
|
||||
class InputEvent : public torrent::Event {
|
||||
public:
|
||||
typedef sigc::slot<void, int> SlotInt;
|
||||
|
||||
InputEvent(int fd) { m_fileDesc = fd; }
|
||||
|
||||
void insert(torrent::Poll* p);
|
||||
void remove(torrent::Poll* p);
|
||||
|
||||
void event_read();
|
||||
void event_write();
|
||||
void event_error();
|
||||
|
||||
void slot_pressed(SlotInt s) { m_slotPressed = s; }
|
||||
|
||||
private:
|
||||
SlotInt m_slotPressed;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
+10
-6
@@ -196,8 +196,8 @@ initialize_display(ui::Control* c) {
|
||||
|
||||
void
|
||||
initialize_core(ui::Control* c) {
|
||||
c->get_core().get_poll().slot_read_stdin(sigc::mem_fun(c->get_input(), &input::Manager::pressed));
|
||||
c->get_core().get_poll().slot_select_interrupted(sigc::ptr_fun(display::Canvas::do_update));
|
||||
c->get_core().get_poll_manager()->signal_interrupted().connect(sigc::mem_fun(c->get_input_stdin(), &input::InputEvent::event_read));
|
||||
c->get_core().get_poll_manager()->signal_interrupted().connect(sigc::ptr_fun(display::Canvas::do_update));
|
||||
|
||||
c->get_core().initialize();
|
||||
}
|
||||
@@ -223,7 +223,7 @@ main(int argc, char** argv) {
|
||||
SignalHandler::set_handler(SIGFPE, sigc::bind(sigc::ptr_fun(&do_panic), SIGFPE));
|
||||
|
||||
// Need to initialize this before parseing options.
|
||||
torrent::initialize(uiControl.get_core().get_poll().get_torrent_poll());
|
||||
torrent::initialize(uiControl.get_core().get_poll_manager()->get_torrent_poll());
|
||||
|
||||
if (getenv("HOME"))
|
||||
load_option_file(getenv("HOME") + std::string("/.rtorrent.rc"), &optionHandler);
|
||||
@@ -235,6 +235,8 @@ main(int argc, char** argv) {
|
||||
|
||||
uiControl.get_ui().init(&uiControl);
|
||||
|
||||
uiControl.initialize();
|
||||
|
||||
load_session_torrents(&uiControl);
|
||||
load_arg_torrents(&uiControl, argv + firstArg, argv + argc);
|
||||
|
||||
@@ -251,11 +253,13 @@ main(int argc, char** argv) {
|
||||
uiControl.get_display().do_update();
|
||||
|
||||
// Do shutdown check before poll, not after.
|
||||
uiControl.get_core().get_poll().poll(!utils::taskScheduler.empty() ?
|
||||
utils::taskScheduler.get_next_timeout() - utils::Timer::cache() :
|
||||
60 * 1000000);
|
||||
uiControl.get_core().get_poll_manager()->poll(!utils::taskScheduler.empty() ?
|
||||
utils::taskScheduler.get_next_timeout() - utils::Timer::cache() :
|
||||
60 * 1000000);
|
||||
}
|
||||
|
||||
uiControl.cleanup();
|
||||
|
||||
uiControl.get_ui().cleanup();
|
||||
uiControl.get_core().cleanup();
|
||||
|
||||
|
||||
@@ -36,10 +36,33 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "control.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
Control::Control() :
|
||||
m_shutdownReceived(false) {
|
||||
|
||||
m_inputStdin = new input::InputEvent(STDIN_FILENO);
|
||||
m_inputStdin->slot_pressed(sigc::mem_fun(m_input, &input::Manager::pressed));
|
||||
}
|
||||
|
||||
Control::~Control() {
|
||||
delete m_inputStdin;
|
||||
}
|
||||
|
||||
void
|
||||
Control::initialize() {
|
||||
m_inputStdin->insert(m_core.get_poll_manager()->get_torrent_poll());
|
||||
}
|
||||
|
||||
void
|
||||
Control::cleanup() {
|
||||
m_inputStdin->remove(m_core.get_poll_manager()->get_torrent_poll());
|
||||
}
|
||||
|
||||
// I think it should be safe to initiate the shutdown from anywhere,
|
||||
// but if it isn't, use a delay task.
|
||||
void
|
||||
|
||||
+8
-1
@@ -42,6 +42,7 @@
|
||||
#include "core/manager.h"
|
||||
#include "display/manager.h"
|
||||
#include "input/manager.h"
|
||||
#include "input/input_event.h"
|
||||
|
||||
#include "root.h"
|
||||
|
||||
@@ -49,7 +50,8 @@ namespace ui {
|
||||
|
||||
class Control {
|
||||
public:
|
||||
Control() : m_shutdownReceived(false) {}
|
||||
Control();
|
||||
~Control();
|
||||
|
||||
bool is_shutdown_completed() { return m_shutdownReceived && torrent::is_inactive(); }
|
||||
bool is_shutdown_received() { return m_shutdownReceived; }
|
||||
@@ -58,6 +60,10 @@ public:
|
||||
core::Manager& get_core() { return m_core; }
|
||||
display::Manager& get_display() { return m_display; }
|
||||
input::Manager& get_input() { return m_input; }
|
||||
input::InputEvent* get_input_stdin() { return m_inputStdin; }
|
||||
|
||||
void initialize();
|
||||
void cleanup();
|
||||
|
||||
void receive_shutdown();
|
||||
|
||||
@@ -71,6 +77,7 @@ private:
|
||||
core::Manager m_core;
|
||||
display::Manager m_display;
|
||||
input::Manager m_input;
|
||||
input::InputEvent* m_inputStdin;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user