Changeset 800

Show
Ignore:
Timestamp:
11/04/06 11:05:28 (5 years ago)
Author:
rakshasa
Message:

* Properly nul-terminate the info hash and client id in the tracker
request.

* Implemented options for read-ahead of
chunks. 'preload_min_pipelined', 'preload_min_size' and
'preload_required_rate' are used to decide when to read-ahead a chunk.

Location:
trunk
Files:
12 modified

Legend:

Unmodified
Added
Removed
  • trunk/libtorrent/rak/error_number.h

    r743 r800  
    5454  static const int e_nomem       = ENOMEM; 
    5555  static const int e_notdir      = ENOTDIR; 
     56  static const int e_isdir       = EISDIR; 
    5657   
    5758  static const int e_intr        = EINTR; 
     
    7475  static error_number current()                    { return errno; } 
    7576  static void         clear_global()               { errno = 0; } 
     77  static void         set_global(error_number err) { errno = err.m_errno; } 
    7678 
    7779  bool operator == (const error_number& e) const   { return m_errno == e.m_errno; } 
  • trunk/libtorrent/src/data/chunk_list.cc

    r786 r800  
    184184 
    185185  } else { 
    186     handle->object()->dec_references(); 
    187  
    188     if (handle->object()->references() == 0) { 
     186    if (handle->object()->dec_references() == 0) { 
    189187      if (is_queued(handle->object())) 
    190188        throw internal_error("ChunkList::release(...) tried to unmap a queued chunk."); 
  • trunk/libtorrent/src/data/chunk_list_node.h

    r691 r800  
    7171  void                set_chunk(Chunk* c)            { m_chunk = c; } 
    7272 
    73   const rak::timer&   time_modified() const           { return m_timeModified; } 
    74   void                set_time_modified(rak::timer t) { m_timeModified = t; } 
     73  const rak::timer&   time_modified() const            { return m_timeModified; } 
     74  void                set_time_modified(rak::timer t)  { m_timeModified = t; } 
     75 
     76  const rak::timer&   time_preloaded() const           { return m_timePreloaded; } 
     77  void                set_time_preloaded(rak::timer t) { m_timePreloaded = t; } 
    7578 
    7679  bool                sync_triggered() const         { return m_asyncTriggered; } 
     
    7881 
    7982  int                 references() const             { return m_references; } 
    80   void                dec_references()               { m_references--; } 
    81   void                inc_references()               { m_references++; } 
     83  int                 dec_references()               { return --m_references; } 
     84  int                 inc_references()               { return ++m_references; } 
    8285 
    8386  int                 writable() const               { return m_writable; } 
    84   void                dec_writable()                 { m_writable--; } 
    85   void                inc_writable()                 { m_writable++; } 
     87  int                 dec_writable()                 { return --m_writable; } 
     88  int                 inc_writable()                 { return ++m_writable; } 
    8689 
    8790  void                inc_rw()                       { inc_writable(); inc_references(); } 
     
    9598  int                 m_writable; 
    9699 
     100  bool                m_asyncTriggered; 
     101 
    97102  rak::timer          m_timeModified; 
    98   bool                m_asyncTriggered; 
     103  rak::timer          m_timePreloaded; 
    99104}; 
    100105 
  • trunk/libtorrent/src/data/entry_list.cc

    r777 r800  
    9898 
    9999  try { 
    100     if (::mkdir(m_rootDir.c_str(), 0777) && errno != EEXIST) 
     100    if (::mkdir(m_rootDir.c_str(), 0777) != 0 && errno != EEXIST) 
    101101      throw storage_error("Could not create directory '" + m_rootDir + "': " + strerror(errno)); 
    102102   
     
    205205      break; 
    206206 
    207     if (::mkdir(path.c_str(), 0777) && errno != EEXIST) 
     207    if (::mkdir(path.c_str(), 0777) != 0 && errno != EEXIST) 
    208208      throw storage_error("Could not create directory '" + path + "': " + strerror(errno)); 
    209209  } 
     
    223223  } 
    224224 
     225  rak::error_number::clear_global(); 
     226 
    225227  make_directory(path->begin(), path->end(), firstMismatch); 
    226228 
     
    229231  if (path->back().empty()) 
    230232    return node->size() == 0; 
     233 
     234  rak::file_stat fileStat; 
     235 
     236  if (fileStat.update(node->file_meta()->get_path()) && 
     237      !fileStat.is_regular() && !fileStat.is_link()) { 
     238    // Might also bork on other kinds of file types, but there's no 
     239    // suitable errno for all cases. 
     240    rak::error_number::set_global(rak::error_number::e_isdir); 
     241    return false; 
     242  } 
    231243 
    232244  return 
  • trunk/libtorrent/src/protocol/handshake.cc

    r799 r800  
    418418      // Have the download from the encrypted handshake, make sure it 
    419419      // matches the BT handshake. 
    420       if (m_download->info()->hash() != (char*)m_readBuffer.position()) 
     420      if (m_download->info()->hash().not_equal_to((char*)m_readBuffer.position())) 
    421421        throw handshake_error(ConnectionManager::handshake_failed, EH_InvalidValue); 
    422422 
     
    429429 
    430430  } else { 
    431     if (m_download->info()->hash() != (char*)m_readBuffer.position()) 
     431    if (m_download->info()->hash().not_equal_to((char*)m_readBuffer.position())) 
    432432      throw handshake_error(ConnectionManager::handshake_failed, EH_InvalidValue); 
    433433  } 
  • trunk/libtorrent/src/protocol/peer_connection_base.cc

    r799 r800  
    4242#include "torrent/exceptions.h" 
    4343#include "torrent/block.h" 
     44#include "torrent/chunk_manager.h" 
    4445#include "data/chunk_iterator.h" 
    4546#include "data/chunk_list.h" 
     
    182183  } 
    183184 
    184   // Make sure we preload the next step once we get past the length 
    185   // here. This is just some testing, don't include this with the 
    186   // release. (Yet) 
    187 //   if (m_peerChunks.upload_throttle()->rate()->rate() >= 10 << 10) 
    188 //     m_upChunk.chunk()->preload(m_upPiece.offset(), m_upChunk.chunk()->size()); 
    189 //   m_upChunk.chunk()->preload(m_upPiece.offset(), std::min(128u << 10, m_peerChunks.upload_throttle()->rate()->rate() * 10)); 
     185  // Also check if we've already preloaded in the recent past, even 
     186  // past unmaps. 
     187  ChunkManager* cm = manager->chunk_manager(); 
     188 
     189  if (cm->preload_min_pipelined() == 0 || 
     190      m_upChunk.object()->time_preloaded() >= cachedTime - rak::timer::from_seconds(60)) 
     191    return; 
     192 
     193  uint32_t preloadSize = m_upPiece.offset() < cm->preload_min_size(); 
     194 
     195  if (preloadSize < cm->preload_min_size() || 
     196      m_peerChunks.upload_throttle()->rate()->rate() < cm->preload_required_rate() * (preloadSize + (2 << 20) - 1) / (2 << 20)) 
     197    return; 
     198 
     199  m_upChunk.chunk()->preload(m_upPiece.offset(), m_upChunk.chunk()->chunk_size()); 
    190200} 
    191201 
  • trunk/libtorrent/src/torrent/chunk_manager.cc

    r772 r800  
    5555  m_timeoutSync(600), 
    5656  m_timeoutSafeSync(900), 
     57 
     58  m_preloadMinPipelined(0), 
     59  m_preloadMinSize(256 << 10), 
     60  m_preloadRequiredRate(10), 
    5761 
    5862  m_timerStarved(0), 
  • trunk/libtorrent/src/torrent/chunk_manager.h

    r798 r800  
    6161  // usage to a resonable value. This should be based on the arch, 
    6262  // ulimit and errors encountered when mmap'ing. 
    63   bool                auto_memory() const                     { return m_autoMemory; } 
    64   void                set_auto_memory(bool state)             { m_autoMemory = state; } 
     63  bool                auto_memory() const                       { return m_autoMemory; } 
     64  void                set_auto_memory(bool state)               { m_autoMemory = state; } 
    6565 
    66   uint64_t            memory_usage() const                    { return m_memoryUsage; } 
     66  uint64_t            memory_usage() const                      { return m_memoryUsage; } 
    6767 
    6868  // Should we allow the client to reserve some memory? 
    6969 
    7070  // The client should set this automatically if ulimit is set. 
    71   uint64_t            max_memory_usage() const                { return m_maxMemoryUsage; } 
    72   void                set_max_memory_usage(uint64_t bytes)    { m_maxMemoryUsage = bytes; } 
     71  uint64_t            max_memory_usage() const                  { return m_maxMemoryUsage; } 
     72  void                set_max_memory_usage(uint64_t bytes)      { m_maxMemoryUsage = bytes; } 
    7373 
    7474  // Estimate the max memory usage possible, capped at 1GB. 
     
    7777  uint64_t            safe_free_diskspace() const; 
    7878 
    79   bool                safe_sync() const                       { return m_safeSync; } 
    80   void                set_safe_sync(uint32_t state)           { m_safeSync = state; } 
     79  bool                safe_sync() const                         { return m_safeSync; } 
     80  void                set_safe_sync(uint32_t state)             { m_safeSync = state; } 
    8181 
    8282  // Set the interval to wait after the last write to a chunk before 
    8383  // trying to sync it. By not forcing a sync too early it should give 
    8484  // the kernel an oppertunity to sync at its convenience. 
    85   uint32_t            timeout_sync() const                    { return m_timeoutSync; } 
    86   void                set_timeout_sync(uint32_t seconds)      { m_timeoutSync = seconds; } 
     85  uint32_t            timeout_sync() const                      { return m_timeoutSync; } 
     86  void                set_timeout_sync(uint32_t seconds)        { m_timeoutSync = seconds; } 
    8787 
    88   uint32_t            timeout_safe_sync() const               { return m_timeoutSafeSync; } 
    89   void                set_timeout_safe_sync(uint32_t seconds) { m_timeoutSafeSync = seconds; } 
     88  uint32_t            timeout_safe_sync() const                 { return m_timeoutSafeSync; } 
     89  void                set_timeout_safe_sync(uint32_t seconds)   { m_timeoutSafeSync = seconds; } 
     90 
     91  // Set to 0 to disable preloading. 
     92  // 
     93  // How the value is used is yet to be determined, but it won't be 
     94  // able to use actual requests in the request queue as we can easily 
     95  // stay ahead of it causing preloading to fail. 
     96  uint32_t            preload_min_pipelined() const             { return m_preloadMinPipelined; } 
     97  void                set_preload_min_pipelined(uint32_t size)  { m_preloadMinPipelined = size; } 
     98 
     99  uint32_t            preload_min_size() const                  { return m_preloadMinSize; } 
     100  void                set_preload_min_size(uint32_t bytes)      { m_preloadMinSize = bytes; } 
     101 
     102  // Required rate before attempting to preload chunk, per whole 
     103  // megabyte of chunk size. 
     104  uint32_t            preload_required_rate() const             { return m_preloadRequiredRate; } 
     105  void                set_preload_required_rate(uint32_t bytes) { m_preloadRequiredRate = bytes; } 
    90106 
    91107  void                insert(ChunkList* chunkList); 
     
    119135  uint32_t            m_timeoutSafeSync; 
    120136 
     137  uint32_t            m_preloadMinPipelined; 
     138  uint32_t            m_preloadMinSize; 
     139  uint32_t            m_preloadRequiredRate; 
     140 
    121141  int32_t             m_timerStarved; 
    122142  size_type           m_lastFreed; 
  • trunk/libtorrent/src/torrent/hash_string.h

    r799 r800  
    8686  void                assign(const value_type* src)     { std::memcpy(data(), src, size()); } 
    8787 
    88   bool                compare(const char* hash)         { return std::memcmp(m_data, hash, size()); } 
     88  bool                equal_to(const char* hash) const     { return std::memcmp(m_data, hash, size()) == 0; } 
     89  bool                not_equal_to(const char* hash) const { return std::memcmp(m_data, hash, size()) == 1; } 
    8990 
    9091private: 
     
    107108} 
    108109 
    109 inline bool 
    110 operator == (const HashString& one, const char* two) { 
    111   return std::memcmp(one.begin(), two, HashString::size_data) == 0; 
    112 } 
    113  
    114 inline bool 
    115 operator != (const HashString& one, const char* two) { 
    116   return std::memcmp(one.begin(), two, HashString::size_data) != 0; 
    117 } 
    118  
    119 inline bool 
    120 operator == (const char* one, const HashString& two) { 
    121   return std::memcmp(one, two.begin(), HashString::size_data) == 0; 
    122 } 
    123  
    124 inline bool 
    125 operator != (const char* one, const HashString& two) { 
    126   return std::memcmp(one, two.begin(), HashString::size_data) != 0; 
    127 } 
    128  
    129110} 
    130111 
  • trunk/libtorrent/src/tracker/tracker_http.cc

    r799 r800  
    9191  s.imbue(std::locale::classic()); 
    9292 
    93   char hash[60]; 
    94   char localId[60]; 
    95  
    96   rak::copy_escape_html(m_info->hash().begin(), m_info->hash().end(), hash); 
    97   rak::copy_escape_html(m_info->local_id().begin(), m_info->local_id().end(), localId); 
     93  char hash[61]; 
     94  char localId[61]; 
     95 
     96  *rak::copy_escape_html(m_info->hash().begin(), m_info->hash().end(), hash) = '\0'; 
     97  *rak::copy_escape_html(m_info->local_id().begin(), m_info->local_id().end(), localId) = '\0'; 
    9898 
    9999  s << m_url 
  • trunk/rtorrent/rak/error_number.h

    r743 r800  
    5454  static const int e_nomem       = ENOMEM; 
    5555  static const int e_notdir      = ENOTDIR; 
     56  static const int e_isdir       = EISDIR; 
    5657   
    5758  static const int e_intr        = EINTR; 
     
    7475  static error_number current()                    { return errno; } 
    7576  static void         clear_global()               { errno = 0; } 
     77  static void         set_global(error_number err) { errno = err.m_errno; } 
    7678 
    7779  bool operator == (const error_number& e) const   { return m_errno == e.m_errno; } 
  • trunk/rtorrent/src/option_handler_rules.cc

    r797 r800  
    515515                                                                          rak::mem_fn(torrent::chunk_manager(), &torrent::ChunkManager::set_timeout_safe_sync))); 
    516516 
     517  variables->insert("preload_min_pipelined", new utils::VariableValueSlot(rak::mem_fn(torrent::chunk_manager(), &torrent::ChunkManager::preload_min_pipelined), 
     518                                                                          rak::mem_fn(torrent::chunk_manager(), &torrent::ChunkManager::set_preload_min_pipelined))); 
     519 
     520  variables->insert("preload_min_size",      new utils::VariableValueSlot(rak::mem_fn(torrent::chunk_manager(), &torrent::ChunkManager::preload_min_size), 
     521                                                                          rak::mem_fn(torrent::chunk_manager(), &torrent::ChunkManager::set_preload_min_size))); 
     522 
     523  variables->insert("preload_required_rate", new utils::VariableValueSlot(rak::mem_fn(torrent::chunk_manager(), &torrent::ChunkManager::preload_required_rate), 
     524                                                                          rak::mem_fn(torrent::chunk_manager(), &torrent::ChunkManager::set_preload_required_rate))); 
     525 
    517526  variables->insert("port_range",            new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_port_range, c))); 
    518527