* 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:
rakshasa
2005-07-27 18:39:57 +00:00
parent 91f4f022a9
commit 3df7567ddf
18 changed files with 677 additions and 208 deletions
+6 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
-143
View File
@@ -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);
}
}
+70
View File
@@ -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();
}
}
+26 -30
View File
@@ -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;
};
}
+112
View File
@@ -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();
}
}
+65
View File
@@ -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
+98
View File
@@ -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();
}
}
+65
View File
@@ -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
+2
View File
@@ -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 \
+73
View File
@@ -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() {
}
}
+67
View File
@@ -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
View File
@@ -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();
+23
View File
@@ -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
View File
@@ -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;
};
}