Changeset 8
- Timestamp:
- 07/25/04 14:19:33 (8 years ago)
- Location:
- trunk/libtorrent
- Files:
-
- 25 modified
-
ChangeLog (modified) (1 diff)
-
TODO (modified) (2 diffs)
-
client/README (modified) (1 diff)
-
client/display.cc (modified) (2 diffs)
-
client/display.h (modified) (1 diff)
-
client/rtorrent.cc (modified) (7 diffs)
-
torrent/download.cc (modified) (2 diffs)
-
torrent/download_state.cc (modified) (6 diffs)
-
torrent/general.h (modified) (1 diff)
-
torrent/peer_connection.cc (modified) (7 diffs)
-
torrent/peer_connection.h (modified) (4 diffs)
-
torrent/peer_connection_extra.cc (modified) (1 diff)
-
torrent/peer_connection_sub.h (modified) (2 diffs)
-
torrent/settings.cc (modified) (1 diff)
-
torrent/settings.h (modified) (1 diff)
-
torrent/socket_base.cc (modified) (2 diffs)
-
torrent/storage.h (modified) (1 diff)
-
torrent/throttle.cc (modified) (8 diffs)
-
torrent/throttle.h (modified) (1 diff)
-
torrent/throttle_control.cc (modified) (1 diff)
-
torrent/throttle_control.h (modified) (2 diffs)
-
torrent/timer.h (modified) (1 diff)
-
torrent/torrent.cc (modified) (6 diffs)
-
torrent/torrent.h (modified) (1 diff)
-
torrent/tracker_query.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtorrent/ChangeLog
r6 r8 1 2004-07-25 <jaris@ifi.uio.no> 2 3 * torrent: Fixed bug that made it skip sending the stop message to the tracker when quiting. 4 5 * torrent: Changed stdint.h to inttypes.h and made it easy to disable execinfo.h in client. 6 7 * torrent: Added throttle with tree structure. Bandwidth delegation needs work. 8 1 9 2004-07-20 <jaris@ifi.uio.no> 2 10 -
trunk/libtorrent/TODO
r5 r8 33 33 Make configure do the peer id thingie automagically 34 34 35 add unroll loops optimizing(?)36 37 35 Add config for how often we unchoke unknown peers vs good uploaders 38 36 … … 40 38 41 39 fix socketBase setAsync 40 41 We're counting bytes we haven't downloaded, fixme. 42 43 Recursively update the up/down rates in throttle. -
trunk/libtorrent/client/README
r5 r8 1 1 This is the test client for libtorrent. Dog food. Note that decreasing 2 max peers does not yet disconnect. Most of the stuff is in KiB. 2 max peers does not yet disconnect them. 3 4 This client is just something i've been throwing togheter as i 5 finished implementing stuff in the library. When i'm finished with the 6 important parts of the library the API will be rewritten to something 7 more usable. I will also do a complete rewrite of the client. 8 9 If your system doesn't have "execinfo.h", uncomment "#define 10 USE_EXECINFO" in rtorrent.cc. This will be handled by an autoconf 11 script later. 3 12 4 13 Main: -
trunk/libtorrent/client/display.cc
r5 r8 1 1 #include "display.h" 2 2 #include <ncurses.h> 3 4 int loops = 0; 3 5 4 6 Display::Display() { … … 74 76 } 75 77 76 mvprintw(maxY - 1, 0, "Port: %i Handshakes: %i ",78 mvprintw(maxY - 1, 0, "Port: %i Handshakes: %i Loops: %i", 77 79 (int)torrent::get(torrent::LISTEN_PORT), 78 (int)torrent::get(torrent::HANDSHAKES_TOTAL)); 80 (int)torrent::get(torrent::HANDSHAKES_TOTAL), 81 loops); 79 82 80 83 refresh(); -
trunk/libtorrent/client/display.h
r5 r8 3 3 4 4 #include <torrent/torrent.h> 5 6 extern int loops; 5 7 6 8 class Display { -
trunk/libtorrent/client/rtorrent.cc
r5 r8 2 2 #include <fstream> 3 3 #include <signal.h> 4 #include <execinfo.h>5 4 #include <ncurses.h> 6 #include <sys/select.h>7 5 #include <torrent/torrent.h> 8 6 #include <torrent/exceptions.h> 9 7 8 #include <unistd.h> 9 //#include <sys/select.h> 10 10 11 #include "display.h" 11 12 #include "download.h" 13 14 // Uncomment this if your system doesn't have execinfo.h 15 #define USE_EXECINFO 16 17 #ifdef USE_EXECINFO 18 #include <execinfo.h> 19 #endif 12 20 13 21 std::list<std::string> log_entries; … … 31 39 switch (signum) { 32 40 case SIGINT: 33 std::cout << "Shuting down" << std::endl; 41 if (shutdown) { 42 torrent::cleanup(); 43 exit(0); 44 } 34 45 35 46 shutdown = true; … … 46 57 called = true; 47 58 59 std::cout << "Signal SEGFAULT recived, dumping stack:" << std::endl; 60 61 #ifdef USE_EXECINFO 48 62 // Print the stack and exit. 49 63 stackSize = backtrace(stackPtrs, 50); … … 54 68 display = NULL; 55 69 56 std::cout << "Signal SEGFAULT recived, dumping stack:" << std::endl;57 58 70 for (int i = 0; i < stackSize; ++i) 59 71 std::cout << i << ' ' << stackStrings[i] << std::endl; 72 #endif 60 73 61 74 exit(-1); … … 71 84 struct timeval timeout; 72 85 86 display = new Display(); 87 73 88 signal(SIGINT, signal_handler); 74 89 signal(SIGSEGV, signal_handler); … … 79 94 torrent::DList::const_iterator curDownload = torrent::downloads().end(); 80 95 81 display = new Display();82 96 Download download(curDownload); 83 97 … … 100 114 int maxY, maxX; 101 115 102 while (!shutdown) { 116 while (!shutdown || !torrent::get(torrent::SHUTDOWN_DONE)) { 117 loops++; 118 103 119 if (lastDraw + 1000000 < torrent::get(torrent::TIME_CURRENT)) { 104 120 lastDraw = torrent::get(torrent::TIME_CURRENT); -
trunk/libtorrent/torrent/download.cc
r5 r8 132 132 (*itr)->lastChoked() + state().settings().chokeGracePeriod < Timer::cache() && 133 133 134 (g = (*itr)-> down().c_rate().rate() * 16 + (*itr)->up().c_rate().rate()) <= f) {134 (g = (*itr)->throttle().down().rate() * 16 + (*itr)->throttle().up().rate()) <= f) { 135 135 f = g; 136 136 p1 = *itr; … … 149 149 (*itr)->down().c_interested() && 150 150 151 (g = (*itr)-> down().c_rate().rate()) >= f) {151 (g = (*itr)->throttle().down().rate()) >= f) { 152 152 f = g; 153 153 p2 = *itr; -
trunk/libtorrent/torrent/download_state.cc
r5 r8 7 7 #include "peer_connection.h" 8 8 #include "peer_handshake.h" 9 #include "throttle_control.h" 9 10 #include <algo/algo.h> 10 11 … … 25 26 26 27 m_files.closeAll(); 27 }28 29 void DownloadState::removeConnection(PeerConnection* p) {30 Connections::iterator itr = std::find(m_connections.begin(), m_connections.end(), p);31 32 if (itr == m_connections.end())33 throw internal_error("Tried to remove peer connection from download that doesn't exist");34 35 delete *itr;36 m_connections.erase(itr);37 38 // TODO: Remove this when we're stable39 if (std::find(m_connections.begin(), m_connections.end(), p) != m_connections.end())40 throw internal_error("Duplicate PeerConnections in Download");41 42 chokeBalance();43 connectPeers();44 28 } 45 29 … … 75 59 // TODO: Optimize, do a single pass with a 's' sized list of (un)chokings. 76 60 if (s > 0) { 77 // while (s && itr != m_connections.end()) { 78 // if ( 79 80 m_connections.sort(gt(call_member(call_member(&PeerConnection::down), 81 &PeerConnection::Sub::c_rate), 82 call_member(call_member(&PeerConnection::down), 83 &PeerConnection::Sub::c_rate))); 61 m_connections.sort(gt(call_member(call_member(&PeerConnection::throttle), 62 &Throttle::down), 63 call_member(call_member(&PeerConnection::throttle), 64 &Throttle::down))); 84 65 85 66 // unchoke peers. … … 97 78 // Sort so we choke slow uploaders first. 98 79 // TODO: Should we sort by unchoked too? 99 m_connections.sort(lt(call_member(call_member(&PeerConnection:: down),100 & PeerConnection::Sub::c_rate),101 call_member(call_member(&PeerConnection:: down),102 & PeerConnection::Sub::c_rate)));80 m_connections.sort(lt(call_member(call_member(&PeerConnection::throttle), 81 &Throttle::down), 82 call_member(call_member(&PeerConnection::throttle), 83 &Throttle::down))); 103 84 104 85 for (Connections::iterator itr = m_connections.begin(); … … 156 137 157 138 c->set(fd, p, this); 139 140 c->throttle().set_parent(&ThrottleControl::global().root()); 141 c->throttle().set_settings(ThrottleControl::global().settings(ThrottleControl::SETTINGS_PEER)); 142 c->throttle().set_socket(c); 143 158 144 m_connections.push_back(c); 159 145 … … 162 148 if (itr != m_availablePeers.end()) 163 149 m_availablePeers.erase(itr); 150 } 151 152 void DownloadState::removeConnection(PeerConnection* p) { 153 Connections::iterator itr = std::find(m_connections.begin(), m_connections.end(), p); 154 155 if (itr == m_connections.end()) 156 throw internal_error("Tried to remove peer connection from download that doesn't exist"); 157 158 delete *itr; 159 m_connections.erase(itr); 160 161 // TODO: Remove this when we're stable 162 if (std::find(m_connections.begin(), m_connections.end(), p) != m_connections.end()) 163 throw internal_error("Duplicate PeerConnections in Download"); 164 165 chokeBalance(); 166 connectPeers(); 164 167 } 165 168 -
trunk/libtorrent/torrent/general.h
r2 r8 3 3 4 4 #include <string> 5 #include <stdint.h>6 5 #include <vector> 7 6 -
trunk/libtorrent/torrent/peer_connection.cc
r7 r8 269 269 s = readChunk(); 270 270 271 m_ down.rate.add(m_down.pos - previous);271 m_throttle.down().add(m_down.pos - previous); 272 272 m_download->rateDown().add(m_down.pos - previous); 273 273 … … 304 304 m_down.pos); 305 305 306 m_ down.rate.add(m_down.pos - previous);306 m_throttle.down().add(m_down.pos - previous); 307 307 308 308 if (!s) … … 342 342 void PeerConnection::write() { 343 343 bool s; 344 int previous ;344 int previous, maxBytes; 345 345 346 346 m_lastMsg = Timer::cache(); … … 410 410 411 411 previous = m_up.pos; 412 s = writeChunk(); 413 414 m_up.rate.add(m_up.pos - previous); 412 maxBytes = m_throttle.left(); 413 414 if (maxBytes == 0) { 415 removeWrite(); 416 return; 417 } 418 419 if (maxBytes < 0) 420 throw internal_error("PeerConnection::write() got maxBytes <= 0"); 421 422 s = writeChunk(maxBytes); 423 424 m_throttle.up().add(m_up.pos - previous); 425 m_throttle.spent(m_up.pos - previous); 426 415 427 m_download->rateUp().add(m_up.pos - previous); 416 428 … … 513 525 m_up.list.push_back(Piece(index, offset, length)); 514 526 insertWrite(); 527 528 m_throttle.activate(); 515 529 516 530 } else if (rItr != m_up.list.end()) { … … 554 568 m_sendChoked = false; 555 569 570 if (m_up.choked) { 571 // Clear the request queue and mmaped chunk. 572 m_up.list.clear(); 573 m_up.data = Chunk(); 574 575 m_throttle.idle(); 576 } 577 556 578 if ((Timer::cache() - m_lastChoked).seconds() < 10) { 557 579 // Wait with the choke message. … … 564 586 565 587 m_lastChoked = Timer::cache(); 566 567 if (m_up.choked) {568 // Clear the request queue and mmaped chunk.569 m_up.list.clear();570 m_up.data = Chunk();571 }572 588 } 573 589 } -
trunk/libtorrent/torrent/peer_connection.h
r7 r8 9 9 #include "piece.h" 10 10 #include "rate.h" 11 #include "throttle.h" 11 12 12 13 #include <vector> … … 70 71 Sub& down() { return m_down; } 71 72 73 Throttle& throttle() { return m_throttle; } 74 72 75 virtual void read(); 73 76 virtual void write(); … … 86 89 }; 87 90 88 bool writeChunk( );91 bool writeChunk(int maxBytes); 89 92 bool readChunk(); 90 93 … … 119 122 Sub m_up; 120 123 Sub m_down; 124 125 Throttle m_throttle; 121 126 }; 122 127 -
trunk/libtorrent/torrent/peer_connection_extra.cc
r7 r8 52 52 } 53 53 54 bool PeerConnection::writeChunk( ) {54 bool PeerConnection::writeChunk(int maxBytes) { 55 55 Chunk::Part& part = m_up.data.get(m_up.list.front().offset() + m_up.pos); 56 56 57 // Length between piece start and the end of the current part of the piece. 58 unsigned int length = std::min(part.first + part.second.length() - m_up.list.front().offset(), 59 m_up.list.front().length()); 60 57 61 // TODO: Make this a while loop so we spit out as much of the piece as we can this work cycle. 58 if (!writeBuf(part.second.data() + m_up.list.front().offset() + m_up.pos - part.first, 59 std::min(part.first + part.second.length() - m_up.list.front().offset(), 60 m_up.list.front().length()), 61 m_up.pos)) 62 return false; 62 writeBuf(part.second.data() + m_up.list.front().offset() + m_up.pos - part.first, 63 std::min(length, m_up.pos + maxBytes), 64 m_up.pos); 63 65 64 66 return m_up.pos == m_up.list.front().length(); -
trunk/libtorrent/torrent/peer_connection_sub.h
r2 r8 17 17 bool c_interested() const { return interested; } 18 18 19 Rate& c_rate() { return rate; }20 21 19 PieceList& c_list() { return list; } 22 20 … … 35 33 Chunk data; 36 34 PieceList list; 37 38 Rate rate;39 35 }; -
trunk/libtorrent/torrent/settings.cc
r7 r8 29 29 30 30 int ThrottleSettings::minPeriod = 500000; 31 int ThrottleSettings::wakeupPoint = 512;31 int ThrottleSettings::wakeupPoint = 2048; 32 32 int ThrottleSettings::minChunk = 512; 33 33 34 34 ThrottleSettings::ThrottleSettings() : 35 unlimited(true), 36 constantRate(0) 35 constantRate(-1) 37 36 {} 38 37 -
trunk/libtorrent/torrent/settings.h
r7 r8 42 42 ThrottleSettings(); 43 43 44 bool unlimited;45 46 44 int constantRate; 47 45 -
trunk/libtorrent/torrent/socket_base.cc
r6 r8 7 7 #include <arpa/inet.h> 8 8 #include <netinet/ip.h> 9 #include <errno.h>10 9 #include <unistd.h> 11 10 #include <sstream> 12 11 #include <iostream> 12 #include <cerrno> 13 13 #include <cstring> 14 14 … … 67 67 void SocketBase::setSocketAsync(int fd) { 68 68 // Set Reuseaddr. 69 int opt = 1;69 //int opt = 1; 70 70 71 71 // TODO: this doesn't belong here 72 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)))73 throw local_error("Error setting socket to SO_REUSEADDR");72 //if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) 73 // throw local_error("Error setting socket to SO_REUSEADDR"); 74 74 75 75 // Set async. -
trunk/libtorrent/torrent/storage.h
r2 r8 5 5 #include <vector> 6 6 #include <string> 7 #include < stdint.h>7 #include <inttypes.h> 8 8 #include <sys/stat.h> 9 9 -
trunk/libtorrent/torrent/throttle.cc
r7 r8 7 7 #include "socket_base.h" 8 8 #include "throttle.h" 9 #include <numeric> 9 10 #include <algo/algo.h> 10 11 … … 22 23 23 24 Throttle::~Throttle() { 24 idle();25 set_parent(NULL); 25 26 26 27 while (!m_active.empty()) 27 m_active.front()-> idle();28 m_active.front()->set_parent(NULL); 28 29 } 29 30 30 31 // Include in the calculation when parent delegates bandwidth. 32 33 // TODO: active should allocate a resonable amount of bytes for immidiate download. 34 // We can't do that in active, as it will be called regulary. 31 35 void Throttle::activate() { 32 36 if (m_parent == NULL || m_activeItr != m_parent->m_active.end()) … … 46 50 47 51 m_activeItr = m_parent->m_active.end(); 52 53 m_left = 0; 54 } 55 56 int Throttle::left() { 57 if (m_left == UNLIMITED) 58 return std::numeric_limits<int>::max() / 2; 59 60 // TODO: Give chunks. 61 return m_left; 48 62 } 49 63 50 64 void Throttle::spent(unsigned int bytes) { 51 if (m_left < 0)65 if (m_left == UNLIMITED) 52 66 return; 53 67 … … 62 76 void Throttle::update(float period, int bytes) { 63 77 // Find out how much we are allowed. Int max if unlimited. 64 if (m_settings-> unlimited)78 if (m_settings->constantRate == UNLIMITED) 65 79 m_left = bytes; 66 80 67 81 else 68 m_left = std::min <unsigned int>(bytes,69 // TODO: Adjust quickly if we are behind70 (unsigned int)(m_settings->constantRate * period));82 m_left = std::min((unsigned int)bytes, 83 // TODO: Adjust quickly if we are behind 84 (unsigned int)(m_settings->constantRate * period)); 71 85 72 86 // Not needed unless i fscked up something here. … … 81 95 82 96 // Divide the bandwidth amongst children if present. 83 for (Children::iterator itr = m_active.begin(); ++itr != m_active.end(); ++itr) {97 for (Children::iterator itr = m_active.begin(); itr != m_active.end(); ++itr) { 84 98 (*itr)->update(period, 85 99 m_left == UNLIMITED ? UNLIMITED : m_left / m_activeSize); … … 89 103 void Throttle::set_parent(Throttle* parent) { 90 104 if (m_parent) { 105 idle(); 106 91 107 m_parent->m_children.erase(m_childrenItr); 92 108 m_parent->m_childrenSize--; … … 96 112 97 113 if (parent) { 114 m_parent->m_childrenSize++; 115 98 116 m_childrenItr = m_parent->m_children.insert(m_parent->m_children.end(), this); 99 m_ parent->m_childrenSize++;117 m_activeItr = m_parent->m_active.end(); 100 118 } 101 119 } … … 105 123 } 106 124 125 void Throttle::set_socket(SocketBase* socket) { 126 m_socket = socket; 107 127 } 128 129 } -
trunk/libtorrent/torrent/throttle.h
r7 r8 29 29 Rate& down() { return m_down; } 30 30 31 int left() { return m_left; }31 int left(); 32 32 33 33 void spent(unsigned int bytes); -
trunk/libtorrent/torrent/throttle_control.cc
r7 r8 3 3 #endif 4 4 5 #include "exceptions.h" 5 6 #include "throttle_control.h" 6 7 7 8 namespace torrent { 8 9 10 ThrottleControl ThrottleControl::m_global; 11 9 12 ThrottleControl::ThrottleControl() : 10 m_settings( 1) {13 m_settings(2) { 11 14 12 15 m_root.set_settings(&m_settings[SETTINGS_ROOT]); 13 16 14 m_settings[SETTINGS_ROOT].unlimited = false; 15 m_settings[SETTINGS_ROOT].constantRate = 5000; 17 m_settings[SETTINGS_ROOT].constantRate = Throttle::UNLIMITED; 18 19 m_settings[SETTINGS_PEER].constantRate = Throttle::UNLIMITED; 16 20 } 17 21 18 22 void ThrottleControl::service(int type) { 19 m_root.update(ThrottleSettings::minPeriod, Throttle::UNLIMITED); 23 m_root.update(ThrottleSettings::minPeriod / 1000000.0f, Throttle::UNLIMITED); 24 25 // TODO: Remove this later 26 if (inService(0)) 27 throw internal_error("Duplicate ThrottleService in service"); 20 28 21 29 // TODO: we lose some time, adjust. -
trunk/libtorrent/torrent/throttle_control.h
r7 r8 12 12 public: 13 13 typedef enum { 14 SETTINGS_ROOT 14 SETTINGS_ROOT, 15 SETTINGS_PEER 15 16 } SettingsType; 16 17 … … 25 26 void service(int type); 26 27 28 static ThrottleControl& global() { return m_global; } 29 27 30 private: 31 static ThrottleControl m_global; 32 28 33 Throttle m_root; 29 34 -
trunk/libtorrent/torrent/timer.h
r2 r8 2 2 #define LIBTORRENT_TIMER_H 3 3 4 #include < stdint.h>4 #include <inttypes.h> 5 5 #include <sys/time.h> 6 6 -
trunk/libtorrent/torrent/torrent.cc
r7 r8 27 27 std::list<std::string> caughtExceptions; 28 28 29 ThrottleControl throttleControl;30 31 29 struct add_socket { 32 30 add_socket(fd_set* s) : fd(0), fds(s) {} … … 63 61 Listen::open(beginPort, endPort); 64 62 65 throttleControl.insertService(Timer::current(), 0);63 ThrottleControl::global().insertService(Timer::current(), 0); 66 64 } 67 65 … … 79 77 Listen::close(); 80 78 81 throttleControl.removeService();79 ThrottleControl::global().removeService(); 82 80 83 81 for_each<true>(Download::downloads().begin(), Download::downloads().end(), … … 208 206 case SHUTDOWN_DONE: 209 207 return std::find_if(Download::downloads().begin(), Download::downloads().end(), 210 call_member(&Download::isStopped))208 bool_not(call_member(&Download::isStopped))) 211 209 == Download::downloads().end(); 212 210 … … 262 260 263 261 int64_t get(DList::const_iterator d, DValue t) { 264 // if (d == Download::downloads().end())265 // throw internal_error("torrent::get(DList::const_iterator, DValue) called on an invalid iterator");266 262 Timer::update(); 267 263 uint64_t a; … … 380 376 381 377 case PEER_RATE_DOWN: 382 return (*p)-> down().c_rate().rate(true);378 return (*p)->throttle().down().rate(true); 383 379 384 380 case PEER_RATE_UP: 385 return (*p)-> up().c_rate().rate(true);381 return (*p)->throttle().up().rate(true); 386 382 387 383 case PEER_PORT: -
trunk/libtorrent/torrent/torrent.h
r2 r8 4 4 #include <list> 5 5 #include <string> 6 #include < stdint.h>6 #include <inttypes.h> 7 7 #include <sys/types.h> 8 8 -
trunk/libtorrent/torrent/tracker_query.h
r2 r8 4 4 #include <map> 5 5 #include <iosfwd> 6 #include < stdint.h>6 #include <inttypes.h> 7 7 #include "peer.h" 8 8 #include "socket_base.h"
