2008-07-23 18:01:59 -04:00
/*
* libretroshare / src / ft : ftcontroller . cc
*
* File Transfer for RetroShare .
*
* Copyright 2008 by Robert Fernie .
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation .
*
* This library 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
* Library General Public License for more details .
*
* You should have received a copy of the GNU Library General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307
* USA .
*
* Please report all bugs and problems to " retroshare@lunamutt.com " .
*
*/
2009-06-11 17:41:42 -04:00
/*
2008-07-23 18:01:59 -04:00
* ftController
*
* Top level download controller .
*
* inherits configuration ( save downloading files )
* inherits pqiMonitor ( knows which peers are online ) .
* inherits CacheTransfer ( transfers cache files too )
* inherits RsThread ( to control transfers )
*
*/
2010-05-16 19:26:45 -04:00
# ifdef WINDOWS_SYS
2011-10-01 09:12:28 -04:00
# include "util/rsstring.h"
2010-05-16 19:26:45 -04:00
# endif
2010-05-21 16:49:48 -04:00
# include "util/rsdiscspace.h"
2016-01-12 21:10:11 -05:00
# include "util/rsmemory.h"
2010-05-16 19:26:45 -04:00
2008-08-09 13:03:24 -04:00
# include "ft/ftcontroller.h"
# include "ft/ftfilecreator.h"
# include "ft/fttransfermodule.h"
# include "ft/ftsearch.h"
# include "ft/ftdatamultiplex.h"
2008-11-09 17:17:20 -05:00
# include "ft/ftextralist.h"
2013-04-06 05:21:01 -04:00
# include "ft/ftserver.h"
2008-08-09 13:03:24 -04:00
2009-05-26 17:42:45 -04:00
# include "turtle/p3turtle.h"
2008-08-09 13:03:24 -04:00
# include "util/rsdir.h"
2014-01-07 17:51:22 -05:00
# include "rsserver/p3face.h"
2008-07-23 18:01:59 -04:00
2011-07-09 14:39:34 -04:00
# include "pqi/p3linkmgr.h"
2008-07-23 18:01:59 -04:00
2010-11-24 19:20:25 -05:00
# include "retroshare/rsiface.h"
2013-06-05 08:57:11 -04:00
# include "retroshare/rspeers.h"
2010-11-24 19:20:25 -05:00
2017-04-24 16:47:08 -04:00
# include "rsitems/rsconfigitems.h"
2009-05-11 10:30:53 -04:00
# include <stdio.h>
2012-04-12 19:29:39 -04:00
# include <unistd.h> /* for (u)sleep() */
2013-10-21 07:00:49 -04:00
# include <time.h>
2008-08-09 13:03:24 -04:00
2008-12-07 09:53:57 -05:00
/******
* # define CONTROL_DEBUG 1
2010-03-06 18:37:42 -05:00
* # define DEBUG_DWLQUEUE 1
2008-12-07 09:53:57 -05:00
* * * * */
2008-08-09 13:03:24 -04:00
2014-09-20 15:54:04 -04:00
static const int32_t SAVE_TRANSFERS_DELAY = 301 ; // save transfer progress every 301 seconds.
2012-02-17 05:03:38 -05:00
static const int32_t INACTIVE_CHUNKS_CHECK_DELAY = 240 ; // time after which an inactive chunk is released
static const int32_t MAX_TIME_INACTIVE_REQUEUED = 120 ; // time after which an inactive ftFileControl is bt-queued
2009-12-10 17:55:27 -05:00
2012-02-17 05:03:38 -05:00
static const int32_t FT_FILECONTROL_QUEUE_ADD_END = 0 ;
2017-05-08 16:00:51 -04:00
static const int32_t FT_FILECONTROL_MAX_UPLOAD_SLOTS_DEFAULT = 0 ;
2010-09-15 15:48:13 -04:00
2013-11-08 16:23:57 -05:00
const uint32_t FT_CNTRL_STANDARD_RATE = 10 * 1024 * 1024 ;
const uint32_t FT_CNTRL_SLOW_RATE = 100 * 1024 ;
2012-11-19 17:45:37 -05:00
2008-08-17 11:23:11 -04:00
ftFileControl : : ftFileControl ( )
2009-06-11 17:41:42 -04:00
: mTransfer ( NULL ) , mCreator ( NULL ) ,
2015-06-15 14:35:09 -04:00
mState ( DOWNLOADING ) , mSize ( 0 ) , mFlags ( 0 ) , mCreateTime ( 0 ) , mQueuePriority ( 0 ) , mQueuePosition ( 0 )
2008-08-17 11:23:11 -04:00
{
return ;
}
2009-06-11 17:41:42 -04:00
ftFileControl : : ftFileControl ( std : : string fname ,
std : : string tmppath , std : : string dest ,
2014-03-17 16:56:06 -04:00
uint64_t size , const RsFileHash & hash , TransferRequestFlags flags ,
2010-10-16 11:21:37 -04:00
ftFileCreator * fc , ftTransferModule * tm )
2008-10-29 16:58:23 -04:00
: mName ( fname ) , mCurrentPath ( tmppath ) , mDestination ( dest ) ,
2010-03-06 18:29:47 -05:00
mTransfer ( tm ) , mCreator ( fc ) , mState ( DOWNLOADING ) , mHash ( hash ) ,
2015-06-15 14:35:09 -04:00
mSize ( size ) , mFlags ( flags ) , mCreateTime ( 0 ) , mQueuePriority ( 0 ) , mQueuePosition ( 0 )
2008-08-17 11:23:11 -04:00
{
2016-10-29 11:59:03 -04:00
return ;
2008-08-17 11:23:11 -04:00
}
2016-07-30 15:52:42 -04:00
ftController : : ftController ( ftDataMultiplex * dm , p3ServiceControl * sc , uint32_t ftServiceId )
2017-06-26 17:35:01 -04:00
: p3Config ( ) ,
last_save_time ( 0 ) ,
last_clean_time ( 0 ) ,
mSearch ( NULL ) ,
mDataplex ( dm ) ,
mExtraList ( NULL ) ,
mTurtle ( NULL ) ,
mFtServer ( NULL ) ,
mServiceCtrl ( sc ) ,
mFtServiceType ( ftServiceId ) ,
mDefaultEncryptionPolicy ( RS_FILE_CTRL_ENCRYPTION_POLICY_PERMISSIVE ) ,
mFilePermDirectDLPolicy ( RS_FILE_PERM_DIRECT_DL_PER_USER ) ,
cnt ( 0 ) ,
ctrlMutex ( " ftController " ) ,
doneMutex ( " ftController " ) ,
mFtActive ( false ) ,
mFtPendingDone ( false ) ,
mDefaultChunkStrategy ( FileChunksInfo : : CHUNK_STRATEGY_PROGRESSIVE ) ,
_max_active_downloads ( 5 ) , // default queue size
_max_uploads_per_friend ( FT_FILECONTROL_MAX_UPLOAD_SLOTS_DEFAULT )
2008-07-23 18:01:59 -04:00
{
}
2013-04-06 05:21:01 -04:00
void ftController : : setTurtleRouter ( p3turtle * pt ) { mTurtle = pt ; }
void ftController : : setFtServer ( ftServer * ft ) { mFtServer = ft ; }
2008-11-09 17:17:20 -05:00
void ftController : : setFtSearchNExtra ( ftSearch * search , ftExtraList * list )
2008-08-09 13:03:24 -04:00
{
mSearch = search ;
2008-11-09 17:17:20 -05:00
mExtraList = list ;
2008-08-09 13:03:24 -04:00
}
2008-07-23 18:01:59 -04:00
2014-03-17 16:56:06 -04:00
bool ftController : : getFileDownloadChunksDetails ( const RsFileHash & hash , FileChunksInfo & info )
2009-11-18 18:02:37 -05:00
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator it = mDownloads . find ( hash ) ;
2009-11-18 18:02:37 -05:00
2010-02-19 15:36:47 -05:00
if ( it ! = mDownloads . end ( ) )
{
2010-03-06 18:29:47 -05:00
it - > second - > mCreator - > getChunkMap ( info ) ;
2012-11-02 09:52:29 -04:00
//info.flags = it->second->mFlags ;
2009-11-18 18:02:37 -05:00
2010-02-19 15:36:47 -05:00
return true ;
}
2009-11-18 18:02:37 -05:00
2010-02-19 15:36:47 -05:00
it = mCompleted . find ( hash ) ;
if ( it ! = mCompleted . end ( ) )
{
// This should rather be done as a static method of ChunkMap.
//
2010-10-07 17:31:42 -04:00
// We do this manually, because the file creator has already been destroyed.
//
2010-03-06 18:29:47 -05:00
info . file_size = it - > second - > mSize ;
2010-10-07 17:31:42 -04:00
info . strategy = mDefaultChunkStrategy ;
2010-02-19 15:36:47 -05:00
info . chunk_size = ChunkMap : : CHUNKMAP_FIXED_CHUNK_SIZE ;
2012-11-02 09:52:29 -04:00
//info.flags = it->second->mFlags ;
2010-03-06 18:29:47 -05:00
uint32_t nb_chunks = it - > second - > mSize / ChunkMap : : CHUNKMAP_FIXED_CHUNK_SIZE ;
if ( it - > second - > mSize % ChunkMap : : CHUNKMAP_FIXED_CHUNK_SIZE ! = 0 )
2010-02-19 15:36:47 -05:00
+ + nb_chunks ;
info . chunks . resize ( nb_chunks , FileChunksInfo : : CHUNK_DONE ) ;
return true ;
}
return false ;
2009-11-18 18:02:37 -05:00
}
2014-03-17 16:56:06 -04:00
void ftController : : addFileSource ( const RsFileHash & hash , const RsPeerId & peer_id )
2009-05-26 17:42:45 -04:00
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator it = mDownloads . find ( hash ) ;
2009-05-26 17:42:45 -04:00
2015-07-09 16:55:11 -04:00
# ifdef CONTROL_DEBUG
2009-05-26 17:42:45 -04:00
std : : cerr < < " ftController: Adding source " < < peer_id < < " to current download hash= " < < hash ;
2015-07-09 16:55:11 -04:00
# endif
2013-10-15 16:39:13 -04:00
if ( it ! = mDownloads . end ( ) )
{
it - > second - > mTransfer - > addFileSource ( peer_id ) ;
2016-11-22 17:19:34 -05:00
setPeerState ( it - > second - > mTransfer , peer_id , FT_CNTRL_STANDARD_RATE , mServiceCtrl - > isPeerConnected ( mFtServiceType , peer_id ) ) ;
2009-05-26 17:42:45 -04:00
# ifdef CONTROL_DEBUG
2013-10-15 16:39:13 -04:00
std : : cerr < < " ... added. " < < std : : endl ;
2009-05-26 17:42:45 -04:00
# endif
2013-10-15 16:39:13 -04:00
return ;
}
2009-05-26 17:42:45 -04:00
# ifdef CONTROL_DEBUG
std : : cerr < < " ... not added: hash not found. " < < std : : endl ;
# endif
}
2014-03-17 16:56:06 -04:00
void ftController : : removeFileSource ( const RsFileHash & hash , const RsPeerId & peer_id )
2009-06-03 14:47:14 -04:00
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator it = mDownloads . find ( hash ) ;
2009-06-03 14:47:14 -04:00
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController: Adding source " < < peer_id < < " to current download hash= " < < hash ;
# endif
2013-10-15 16:39:13 -04:00
if ( it ! = mDownloads . end ( ) )
{
it - > second - > mTransfer - > removeFileSource ( peer_id ) ;
it - > second - > mCreator - > removeFileSource ( peer_id ) ;
2009-05-26 17:42:45 -04:00
2009-06-03 14:47:14 -04:00
# ifdef CONTROL_DEBUG
2013-10-15 16:39:13 -04:00
std : : cerr < < " ... added. " < < std : : endl ;
2009-06-03 14:47:14 -04:00
# endif
2013-10-15 16:39:13 -04:00
return ;
}
2009-06-03 14:47:14 -04:00
# ifdef CONTROL_DEBUG
std : : cerr < < " ... not added: hash not found. " < < std : : endl ;
# endif
}
2015-05-22 16:54:38 -04:00
void ftController : : data_tick ( )
2008-07-23 18:01:59 -04:00
{
2009-05-06 16:48:32 -04:00
/* check the queues */
2010-03-06 18:29:47 -05:00
2014-10-24 17:31:58 -04:00
//Waiting 1 sec before start
usleep ( 1 * 1000 * 1000 ) ; // 1 sec
2008-08-21 17:30:59 -04:00
2008-11-02 06:38:11 -05:00
# ifdef CONTROL_DEBUG
2009-05-06 16:48:32 -04:00
std : : cerr < < " ftController::run() " ;
std : : cerr < < std : : endl ;
2008-11-02 06:38:11 -05:00
# endif
2008-11-20 19:10:59 -05:00
bool doPending = false ;
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
doPending = ( mFtActive ) & & ( ! mFtPendingDone ) ;
}
2009-12-10 17:55:27 -05:00
time_t now = time ( NULL ) ;
2012-01-10 18:07:53 -05:00
if ( now > last_save_time + SAVE_TRANSFERS_DELAY )
2009-12-10 17:55:27 -05:00
{
2012-11-19 17:45:37 -05:00
searchForDirectSources ( ) ;
2010-01-26 15:40:21 -05:00
2009-12-10 17:55:27 -05:00
IndicateConfigChanged ( ) ;
last_save_time = now ;
}
2012-01-10 18:07:53 -05:00
if ( now > last_clean_time + INACTIVE_CHUNKS_CHECK_DELAY )
2010-01-21 07:31:00 -05:00
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2017-05-08 16:00:51 -04:00
for ( std : : map < RsFileHash , ftFileControl * > : : iterator it ( mDownloads . begin ( ) ) ; it ! = mDownloads . end ( ) ; + + it )
it - > second - > mCreator - > removeInactiveChunks ( ) ;
2010-01-21 07:31:00 -05:00
last_clean_time = now ;
}
2008-11-20 19:10:59 -05:00
if ( doPending )
{
if ( ! handleAPendingRequest ( ) )
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
mFtPendingDone = true ;
}
}
2008-08-17 11:23:11 -04:00
2010-01-26 15:40:21 -05:00
tickTransfers ( ) ;
2008-08-21 17:30:59 -04:00
{
2014-03-17 16:56:06 -04:00
std : : list < RsFileHash > files_to_complete ;
2008-10-29 16:58:23 -04:00
2010-11-22 16:15:21 -05:00
{
RsStackMutex stack2 ( doneMutex ) ;
files_to_complete = mDone ;
mDone . clear ( ) ;
}
2014-03-17 16:56:06 -04:00
for ( std : : list < RsFileHash > : : iterator it ( files_to_complete . begin ( ) ) ; it ! = files_to_complete . end ( ) ; + + it )
2010-01-26 15:40:21 -05:00
completeFile ( * it ) ;
}
2010-03-06 18:29:47 -05:00
if ( cnt + + % 10 = = 0 )
checkDownloadQueue ( ) ;
2010-01-26 15:40:21 -05:00
}
2012-11-19 17:45:37 -05:00
void ftController : : searchForDirectSources ( )
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2017-06-26 17:35:01 -04:00
if ( ! mSearch ) return ;
2012-11-19 17:45:37 -05:00
2017-06-26 17:35:01 -04:00
for ( std : : map < RsFileHash , ftFileControl * > : : iterator it ( mDownloads . begin ( ) ) ; it ! = mDownloads . end ( ) ; + + it )
if ( it - > second - > mState ! = ftFileControl : : QUEUED & & it - > second - > mState ! = ftFileControl : : PAUSED )
{
FileInfo info ; // Info needs to be re-allocated each time, to start with a clear list of peers (it's not cleared down there)
2012-11-20 16:42:21 -05:00
2017-06-26 17:35:01 -04:00
if ( mSearch - > search ( it - > first , RS_FILE_HINTS_REMOTE | RS_FILE_HINTS_SPEC_ONLY , info ) )
for ( std : : list < TransferInfo > : : const_iterator pit = info . peers . begin ( ) ; pit ! = info . peers . end ( ) ; + + pit )
{
bool bAllowDirectDL = false ;
2017-07-17 05:16:48 -04:00
switch ( mFilePermDirectDLPolicy ) {
2017-06-26 17:35:01 -04:00
case RS_FILE_PERM_DIRECT_DL_YES : bAllowDirectDL = true ; break ;
case RS_FILE_PERM_DIRECT_DL_NO : bAllowDirectDL = false ; break ;
default : bAllowDirectDL = ( rsPeers - > servicePermissionFlags ( pit - > peerId ) & RS_NODE_PERM_DIRECT_DL ) ; break ;
}
if ( bAllowDirectDL )
if ( it - > second - > mTransfer - > addFileSource ( pit - > peerId ) ) /* if the sources don't exist already - add in */
setPeerState ( it - > second - > mTransfer , pit - > peerId , FT_CNTRL_STANDARD_RATE , mServiceCtrl - > isPeerConnected ( mFtServiceType , pit - > peerId ) ) ;
}
}
2012-11-19 17:45:37 -05:00
}
2010-01-26 15:40:21 -05:00
void ftController : : tickTransfers ( )
{
// 1 - sort modules into arrays according to priority
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2010-03-06 18:29:47 -05:00
# ifdef CONTROL_DEBUG
2010-01-26 15:40:21 -05:00
std : : cerr < < " ticking transfers. " < < std : : endl ;
2010-03-06 18:29:47 -05:00
# endif
// Collect all non queued files.
//
2014-10-24 18:07:26 -04:00
for ( std : : map < RsFileHash , ftFileControl * > : : iterator it ( mDownloads . begin ( ) ) ; it ! = mDownloads . end ( ) ; + + it )
2010-03-15 08:57:08 -04:00
if ( it - > second - > mState ! = ftFileControl : : QUEUED & & it - > second - > mState ! = ftFileControl : : PAUSED )
2011-11-16 15:30:20 -05:00
it - > second - > mTransfer - > tick ( ) ;
2010-01-26 15:40:21 -05:00
}
2014-03-17 16:56:06 -04:00
bool ftController : : getPriority ( const RsFileHash & hash , DwlSpeed & p )
2010-01-26 15:40:21 -05:00
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator it ( mDownloads . find ( hash ) ) ;
2010-01-26 15:40:21 -05:00
if ( it ! = mDownloads . end ( ) )
{
2011-11-16 15:30:20 -05:00
p = it - > second - > mTransfer - > downloadPriority ( ) ;
2010-01-26 15:40:21 -05:00
return true ;
}
else
return false ;
}
2011-11-16 15:30:20 -05:00
2014-03-17 16:56:06 -04:00
void ftController : : setPriority ( const RsFileHash & hash , DwlSpeed p )
2010-01-26 15:40:21 -05:00
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator it ( mDownloads . find ( hash ) ) ;
2010-01-26 15:40:21 -05:00
if ( it ! = mDownloads . end ( ) )
2011-11-16 15:30:20 -05:00
it - > second - > mTransfer - > setDownloadPriority ( p ) ;
2010-01-26 15:40:21 -05:00
}
2008-07-23 18:01:59 -04:00
/* Called every 10 seconds or so */
void ftController : : checkDownloadQueue ( )
{
2010-03-06 18:29:47 -05:00
// We do multiple things here:
//
2016-11-22 17:19:34 -05:00
// 0 - make sure all transfers have a consistent value for mDownloadQueue
//
2010-03-06 18:29:47 -05:00
// 1 - are there queued files ?
2016-11-22 17:19:34 -05:00
//
2010-03-06 18:29:47 -05:00
// YES
// 1.1 - check for inactive files (see below).
// - select one inactive file
// - close it temporarily
// - remove it from turtle handling
// - move the ftFileControl to queued list
2011-01-10 10:30:37 -05:00
// - set the queue priority to 1+largest in the queue.
2016-11-22 17:19:34 -05:00
// 1.2 - pop from the queue the 1st file to come (according to availability of sources, then priority)
2010-03-06 18:29:47 -05:00
// - enable turtle router handling for this hash
// - reset counters
// - set the file as waiting
// NO
// Do nothing, because no files are waiting.
//
// 2 - in FileRequest, if the max number of downloaded files is exceeded, put the
// file in the queue list, and don't enable the turtle router handling.
//
// Implementation:
// - locate a hash in the queue
// - move hashes in the queue up/down/top/bottom
// - now the place of each ftFileControl element in the queue to activate/desactive them
//
// So:
// - change mDownloads to be a std::map<hash,ftFileControl*>
// - sort the ftFileControl* into a std::vector
// - store the queue position of each ftFileControl* into its own structure (mQueuePosition member)
//
// We don't want the turtle router to keep openning tunnels for queued files, so we only base
// the notion of inactive on the fact that no traffic happens for the file within 5 mins.
//
// How do we detect inactive files?
// For a downld file: - no traffic for 5 min.
RsStackMutex mtx ( ctrlMutex ) ;
# ifdef DEBUG_DWLQUEUE
std : : cerr < < " Checking download queue. " < < std : : endl ;
# endif
if ( mDownloads . size ( ) < = _max_active_downloads )
return ;
2016-11-22 17:19:34 -05:00
std : : vector < ftFileControl * > inactive_transfers ;
std : : vector < ftFileControl * > transfers_with_online_sources ;
std : : set < RsPeerId > online_peers ;
mServiceCtrl - > getPeersConnected ( mFtServiceType , online_peers ) ;
// Check for inactive transfers, and queued transfers with online sources.
2010-03-06 18:29:47 -05:00
//
time_t now = time ( NULL ) ;
2016-11-22 17:19:34 -05:00
for ( std : : map < RsFileHash , ftFileControl * > : : const_iterator it ( mDownloads . begin ( ) ) ; it ! = mDownloads . end ( ) ; + + it )
if ( it - > second - > mState ! = ftFileControl : : QUEUED & & ( it - > second - > mState = = ftFileControl : : PAUSED
2013-12-04 15:26:54 -05:00
| | now > it - > second - > mTransfer - > lastActvTimeStamp ( ) + ( time_t ) MAX_TIME_INACTIVE_REQUEUED ) )
2016-11-23 13:12:38 -05:00
{
inactive_transfers . push_back ( it - > second ) ;
}
2016-11-22 17:19:34 -05:00
else if ( it - > second - > mState = = ftFileControl : : QUEUED )
{
std : : list < RsPeerId > srcs ;
it - > second - > mTransfer - > getFileSources ( srcs ) ;
for ( std : : list < RsPeerId > : : const_iterator it2 ( srcs . begin ( ) ) ; it2 ! = srcs . end ( ) ; + + it2 )
if ( online_peers . find ( * it2 ) ! = online_peers . end ( ) )
{
transfers_with_online_sources . push_back ( it - > second ) ;
break ;
}
}
2010-03-21 17:07:12 -04:00
# ifdef DEBUG_DWLQUEUE
2016-11-22 17:19:34 -05:00
std : : cerr < < " Identified " < < inactive_transfers . size ( ) < < " inactive transfer, and " < < transfers_with_online_sources . size ( ) < < " queued transfers with online sources. " < < std : : endl ;
2010-03-21 17:07:12 -04:00
# endif
2016-11-22 17:19:34 -05:00
// first swap as many queued transfers with online sources with inactive transfers
uint32_t i = 0 ;
for ( ; i < inactive_transfers . size ( ) & & i < transfers_with_online_sources . size ( ) ; + + i )
{
2010-03-06 18:29:47 -05:00
# ifdef DEBUG_DWLQUEUE
2016-11-22 17:19:34 -05:00
std : : cerr < < " Exchanging queue position of inactive transfer " < < inactive_transfers [ i ] - > mName < < " at position " < < inactive_transfers [ i ] - > mQueuePosition < < " with transfer at position " < < transfers_with_online_sources [ i ] - > mQueuePosition < < " which has available sources. " < < std : : endl ;
2010-03-06 18:29:47 -05:00
# endif
2016-11-22 17:19:34 -05:00
inactive_transfers [ i ] - > mTransfer - > resetActvTimeStamp ( ) ; // very important!
transfers_with_online_sources [ i ] - > mTransfer - > resetActvTimeStamp ( ) ; // very important!
2012-01-10 18:07:53 -05:00
2016-11-22 17:19:34 -05:00
locked_swapQueue ( inactive_transfers [ i ] - > mQueuePosition , transfers_with_online_sources [ i ] - > mQueuePosition ) ;
}
2012-01-10 18:07:53 -05:00
2016-11-22 17:19:34 -05:00
// now if some inactive transfers remain, put them at the end of the queue.
2012-01-10 18:07:53 -05:00
2016-11-22 17:19:34 -05:00
for ( ; i < inactive_transfers . size ( ) ; + + i )
2012-01-10 18:07:53 -05:00
{
2016-11-22 17:19:34 -05:00
# ifdef DEBUG_DWLQUEUE
std : : cerr < < " - Inactive file " < < inactive_transfers [ i ] - > mName < < " at position " < < inactive_transfers [ i ] - > mQueuePosition < < " moved to end of the queue. mState= " < < inactive_transfers [ i ] - > mState < < " , time lapse= " < < now - it - > second - > mCreator - > lastActvTimeStamp ( ) < < std : : endl ;
# endif
locked_bottomQueue ( inactive_transfers [ i ] - > mQueuePosition ) ;
# ifdef DEBUG_DWLQUEUE
std : : cerr < < " new position: " < < inactive_transfers [ i ] - > mQueuePosition < < std : : endl ;
std : : cerr < < " new state: " < < inactive_transfers [ i ] - > mState < < std : : endl ;
# endif
inactive_transfers [ i ] - > mTransfer - > resetActvTimeStamp ( ) ; // very important!
2012-01-10 18:07:53 -05:00
}
2016-11-22 17:19:34 -05:00
// finally, do a full swab over the queue to make sure that the expected number of downloads is met.
2012-01-10 18:07:53 -05:00
2016-11-22 17:19:34 -05:00
for ( uint32_t i = 0 ; i < mDownloadQueue . size ( ) ; + + i )
locked_checkQueueElement ( i ) ;
2010-03-06 18:29:47 -05:00
}
2010-09-15 15:48:13 -04:00
void ftController : : locked_addToQueue ( ftFileControl * ftfc , int add_strategy )
2010-03-06 18:29:47 -05:00
{
# ifdef DEBUG_DWLQUEUE
std : : cerr < < " Queueing ftfileControl " < < ( void * ) ftfc < < " , name= " < < ftfc - > mName < < std : : endl ;
# endif
2010-09-15 15:48:13 -04:00
switch ( add_strategy )
{
2016-11-22 17:19:34 -05:00
default :
2012-01-10 18:07:53 -05:00
// Different strategies for files and cache files:
// - a min number of slots is reserved to user file transfer
// - cache files are always added after this slot.
//
2016-11-22 17:19:34 -05:00
case FT_FILECONTROL_QUEUE_ADD_END : mDownloadQueue . push_back ( ftfc ) ;
locked_checkQueueElement ( mDownloadQueue . size ( ) - 1 ) ;
2010-09-15 15:48:13 -04:00
break ;
}
2010-03-06 18:29:47 -05:00
}
void ftController : : locked_queueRemove ( uint32_t pos )
{
2016-11-22 17:19:34 -05:00
for ( uint32_t p = pos ; p < mDownloadQueue . size ( ) - 1 ; + + p )
2010-03-06 18:29:47 -05:00
{
2016-11-22 17:19:34 -05:00
mDownloadQueue [ p ] = mDownloadQueue [ p + 1 ] ;
2010-03-06 18:29:47 -05:00
locked_checkQueueElement ( p ) ;
}
2016-11-22 17:19:34 -05:00
mDownloadQueue . pop_back ( ) ;
2010-03-06 18:29:47 -05:00
}
2009-01-24 10:22:08 -05:00
2010-03-06 18:29:47 -05:00
void ftController : : setQueueSize ( uint32_t s )
{
RsStackMutex mtx ( ctrlMutex ) ;
2009-01-24 10:22:08 -05:00
2010-03-06 18:29:47 -05:00
if ( s > 0 )
{
uint32_t old_s = _max_active_downloads ;
_max_active_downloads = s ;
# ifdef DEBUG_DWLQUEUE
std : : cerr < < " Settign new queue size to " < < s < < std : : endl ;
# endif
for ( uint32_t p = std : : min ( s , old_s ) ; p < = std : : max ( s , old_s ) ; + + p )
2016-11-22 17:19:34 -05:00
if ( p < mDownloadQueue . size ( ) )
2010-03-21 17:07:12 -04:00
locked_checkQueueElement ( p ) ;
2010-03-06 18:29:47 -05:00
}
else
std : : cerr < < " ftController::setQueueSize(): cannot set queue to size " < < s < < std : : endl ;
}
uint32_t ftController : : getQueueSize ( )
{
RsStackMutex mtx ( ctrlMutex ) ;
return _max_active_downloads ;
}
2014-03-17 16:56:06 -04:00
void ftController : : moveInQueue ( const RsFileHash & hash , QueueMove mv )
2010-03-06 18:29:47 -05:00
{
RsStackMutex mtx ( ctrlMutex ) ;
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator it ( mDownloads . find ( hash ) ) ;
2010-03-06 18:29:47 -05:00
if ( it = = mDownloads . end ( ) )
{
std : : cerr < < " ftController::moveInQueue: can't find hash " < < hash < < " in the download list. " < < std : : endl ;
return ;
}
uint32_t pos = it - > second - > mQueuePosition ;
# ifdef DEBUG_DWLQUEUE
std : : cerr < < " Moving file " < < hash < < " , pos= " < < pos < < " to new pos. " < < std : : endl ;
# endif
switch ( mv )
{
case QUEUE_TOP : locked_topQueue ( pos ) ;
break ;
case QUEUE_BOTTOM : locked_bottomQueue ( pos ) ;
break ;
case QUEUE_UP : if ( pos > 0 )
locked_swapQueue ( pos , pos - 1 ) ;
break ;
2016-11-22 17:19:34 -05:00
case QUEUE_DOWN : if ( pos < mDownloadQueue . size ( ) - 1 )
2010-03-06 18:29:47 -05:00
locked_swapQueue ( pos , pos + 1 ) ;
break ;
default :
std : : cerr < < " ftController::moveInQueue: unknown move " < < mv < < std : : endl ;
}
}
void ftController : : locked_topQueue ( uint32_t pos )
{
2016-11-22 17:19:34 -05:00
ftFileControl * tmp = mDownloadQueue [ pos ] ;
2010-03-06 18:29:47 -05:00
for ( int p = pos ; p > 0 ; - - p )
{
2016-11-22 17:19:34 -05:00
mDownloadQueue [ p ] = mDownloadQueue [ p - 1 ] ;
2010-03-06 18:29:47 -05:00
locked_checkQueueElement ( p ) ;
}
2016-11-22 17:19:34 -05:00
mDownloadQueue [ 0 ] = tmp ;
2010-04-30 17:07:21 -04:00
2010-03-06 18:29:47 -05:00
locked_checkQueueElement ( 0 ) ;
}
void ftController : : locked_bottomQueue ( uint32_t pos )
{
2016-11-22 17:19:34 -05:00
ftFileControl * tmp = mDownloadQueue [ pos ] ;
2010-03-06 18:29:47 -05:00
2016-11-22 17:19:34 -05:00
for ( uint32_t p = pos ; p < mDownloadQueue . size ( ) - 1 ; + + p )
2010-03-06 18:29:47 -05:00
{
2016-11-22 17:19:34 -05:00
mDownloadQueue [ p ] = mDownloadQueue [ p + 1 ] ;
2010-03-06 18:29:47 -05:00
locked_checkQueueElement ( p ) ;
}
2016-11-22 17:19:34 -05:00
mDownloadQueue [ mDownloadQueue . size ( ) - 1 ] = tmp ;
locked_checkQueueElement ( mDownloadQueue . size ( ) - 1 ) ;
2010-03-06 18:29:47 -05:00
}
void ftController : : locked_swapQueue ( uint32_t pos1 , uint32_t pos2 )
{
// Swap the element at position pos with the last element of the queue
if ( pos1 = = pos2 )
return ;
2016-11-22 17:19:34 -05:00
ftFileControl * tmp = mDownloadQueue [ pos1 ] ;
mDownloadQueue [ pos1 ] = mDownloadQueue [ pos2 ] ;
mDownloadQueue [ pos2 ] = tmp ;
2010-03-06 18:29:47 -05:00
locked_checkQueueElement ( pos1 ) ;
locked_checkQueueElement ( pos2 ) ;
}
void ftController : : locked_checkQueueElement ( uint32_t pos )
{
2016-11-22 17:19:34 -05:00
mDownloadQueue [ pos ] - > mQueuePosition = pos ;
2010-03-06 18:29:47 -05:00
2016-11-22 17:19:34 -05:00
if ( pos < _max_active_downloads & & mDownloadQueue [ pos ] - > mState ! = ftFileControl : : PAUSED )
2010-03-06 18:29:47 -05:00
{
2016-11-22 17:19:34 -05:00
if ( mDownloadQueue [ pos ] - > mState = = ftFileControl : : QUEUED )
mDownloadQueue [ pos ] - > mTransfer - > resetActvTimeStamp ( ) ;
2010-04-30 17:07:21 -04:00
2016-11-22 17:19:34 -05:00
mDownloadQueue [ pos ] - > mState = ftFileControl : : DOWNLOADING ;
2010-03-12 14:39:23 -05:00
2016-11-22 17:19:34 -05:00
if ( mDownloadQueue [ pos ] - > mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING )
mFtServer - > activateTunnels ( mDownloadQueue [ pos ] - > mHash , mDefaultEncryptionPolicy , mDownloadQueue [ pos ] - > mFlags , true ) ;
2010-03-06 18:29:47 -05:00
}
2016-11-22 17:19:34 -05:00
if ( pos > = _max_active_downloads & & mDownloadQueue [ pos ] - > mState ! = ftFileControl : : QUEUED & & mDownloadQueue [ pos ] - > mState ! = ftFileControl : : PAUSED )
2010-03-06 18:29:47 -05:00
{
2016-11-22 17:19:34 -05:00
mDownloadQueue [ pos ] - > mState = ftFileControl : : QUEUED ;
mDownloadQueue [ pos ] - > mCreator - > closeFile ( ) ;
2010-03-12 14:39:23 -05:00
2016-11-22 17:19:34 -05:00
if ( mDownloadQueue [ pos ] - > mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING )
mFtServer - > activateTunnels ( mDownloadQueue [ pos ] - > mHash , mDefaultEncryptionPolicy , mDownloadQueue [ pos ] - > mFlags , false ) ;
2016-10-29 11:59:03 -04:00
}
2008-07-23 18:01:59 -04:00
}
2014-03-17 16:56:06 -04:00
bool ftController : : FlagFileComplete ( const RsFileHash & hash )
2008-07-23 18:01:59 -04:00
{
2009-06-11 17:41:42 -04:00
RsStackMutex stack2 ( doneMutex ) ;
2008-10-29 16:58:23 -04:00
mDone . push_back ( hash ) ;
2008-08-09 13:03:24 -04:00
2009-12-14 13:10:20 -05:00
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController:FlagFileComplete( " < < hash < < " ) " ;
std : : cerr < < std : : endl ;
# endif
2008-08-09 13:03:24 -04:00
2008-10-29 16:58:23 -04:00
return true ;
}
2014-03-17 16:56:06 -04:00
bool ftController : : completeFile ( const RsFileHash & hash )
2008-10-29 16:58:23 -04:00
{
2008-11-09 17:17:20 -05:00
/* variables... so we can drop mutex later */
std : : string path ;
2010-11-24 19:20:25 -05:00
std : : string name ;
2010-03-06 18:29:47 -05:00
uint64_t size = 0 ;
2016-07-30 15:52:42 -04:00
uint32_t period = 0 ;
2012-11-02 09:52:29 -04:00
TransferRequestFlags flags ;
TransferRequestFlags extraflags ;
2010-11-24 19:20:25 -05:00
uint32_t completeCount = 0 ;
2008-11-09 17:17:20 -05:00
2009-06-11 17:41:42 -04:00
{
2016-10-12 14:43:38 -04:00
RS_STACK_MUTEX ( ctrlMutex ) ;
2008-10-29 16:58:23 -04:00
2009-12-14 13:10:34 -05:00
# ifdef CONTROL_DEBUG
2010-03-06 18:29:47 -05:00
std : : cerr < < " ftController:completeFile( " < < hash < < " ) " ;
2008-10-29 16:58:23 -04:00
std : : cerr < < std : : endl ;
2009-12-14 13:10:34 -05:00
# endif
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator it ( mDownloads . find ( hash ) ) ;
2010-03-06 18:29:47 -05:00
2009-02-12 07:47:57 -05:00
if ( it = = mDownloads . end ( ) )
{
2009-12-14 13:10:34 -05:00
# ifdef CONTROL_DEBUG
2010-03-06 18:29:47 -05:00
std : : cerr < < " ftController:completeFile( " < < hash < < " ) " ;
2009-02-12 07:47:57 -05:00
std : : cerr < < " Not Found! " ;
std : : cerr < < std : : endl ;
2009-12-14 13:10:34 -05:00
# endif
2010-03-06 18:29:47 -05:00
return false ;
2009-02-12 07:47:57 -05:00
}
2008-10-29 16:58:23 -04:00
2009-02-12 07:47:57 -05:00
/* check if finished */
2010-03-06 18:29:47 -05:00
if ( ! ( it - > second ) - > mCreator - > finished ( ) )
2009-02-12 07:47:57 -05:00
{
/* not done! */
2009-12-14 13:10:34 -05:00
# ifdef CONTROL_DEBUG
2010-03-06 18:29:47 -05:00
std : : cerr < < " ftController:completeFile( " < < hash < < " ) " ;
2009-02-12 07:47:57 -05:00
std : : cerr < < " Transfer Not Done " ;
std : : cerr < < std : : endl ;
2008-10-29 16:58:23 -04:00
2009-02-12 07:47:57 -05:00
std : : cerr < < " FileSize: " ;
2010-03-06 18:29:47 -05:00
std : : cerr < < ( it - > second ) - > mCreator - > getFileSize ( ) ;
2009-02-12 07:47:57 -05:00
std : : cerr < < " and Recvd: " ;
2010-03-06 18:29:47 -05:00
std : : cerr < < ( it - > second ) - > mCreator - > getRecvd ( ) ;
2009-12-14 13:10:34 -05:00
# endif
2009-02-12 07:47:57 -05:00
return false ;
}
2008-07-23 18:01:59 -04:00
2008-10-29 16:58:23 -04:00
2010-03-06 18:29:47 -05:00
ftFileControl * fc = it - > second ;
2008-07-23 18:01:59 -04:00
2009-06-11 17:41:42 -04:00
// (csoler) I've postponed this to the end of the block because deleting the
// element from the map calls the destructor of fc->mTransfer, which
2009-02-12 07:47:57 -05:00
// makes fc to point to nothing and causes random behavior/crashes.
//
// mDataplex->removeTransferModule(fc->mTransfer->hash());
//
/* done - cleanup */
2008-10-29 16:58:23 -04:00
2009-02-12 07:47:57 -05:00
// (csoler) I'm copying this because "delete fc->mTransfer" deletes the hash string!
2014-03-17 16:56:06 -04:00
RsFileHash hash_to_suppress ( fc - > mTransfer - > hash ( ) ) ;
2008-07-23 18:01:59 -04:00
2011-09-15 15:33:58 -04:00
// This should be done that early, because once the file creator is
// deleted, it should not be accessed by the data multiplex anymore!
//
mDataplex - > removeTransferModule ( hash_to_suppress ) ;
2009-02-12 07:47:57 -05:00
if ( fc - > mTransfer )
{
delete fc - > mTransfer ;
fc - > mTransfer = NULL ;
}
2008-07-23 18:01:59 -04:00
2009-02-12 07:47:57 -05:00
if ( fc - > mCreator )
{
2010-03-17 11:34:36 -04:00
fc - > mCreator - > closeFile ( ) ;
2009-02-12 07:47:57 -05:00
delete fc - > mCreator ;
fc - > mCreator = NULL ;
}
fc - > mState = ftFileControl : : COMPLETED ;
2009-04-06 15:41:40 -04:00
// I don't know how the size can be zero, but believe me, this happens,
// and it causes an error on linux because then the file may not even exist.
//
2016-11-22 17:39:09 -05:00
if ( fc - > mSize > 0 & & RsDirUtil : : moveFile ( fc - > mCurrentPath , fc - > mDestination ) )
2009-02-12 07:47:57 -05:00
fc - > mCurrentPath = fc - > mDestination ;
else
fc - > mState = ftFileControl : : ERROR_COMPLETION ;
2008-10-29 16:58:23 -04:00
2009-02-12 07:47:57 -05:00
/* for extralist additions */
path = fc - > mDestination ;
2010-11-24 19:20:25 -05:00
name = fc - > mName ;
2009-02-12 07:47:57 -05:00
//hash = fc->mHash;
size = fc - > mSize ;
period = 30 * 24 * 3600 ; /* 30 days */
2012-11-02 09:52:29 -04:00
extraflags . clear ( ) ;
2008-11-09 17:17:20 -05:00
2009-04-06 15:41:40 -04:00
# ifdef CONTROL_DEBUG
std : : cerr < < " CompleteFile(): size = " < < size < < std : : endl ;
# endif
2010-10-16 11:21:37 -04:00
flags = fc - > mFlags ;
2010-03-06 18:29:47 -05:00
locked_queueRemove ( it - > second - > mQueuePosition ) ;
/* switch map */
2016-07-30 15:52:42 -04:00
mCompleted [ fc - > mHash ] = fc ;
completeCount = mCompleted . size ( ) ;
2010-03-06 18:29:47 -05:00
2009-02-12 07:47:57 -05:00
mDownloads . erase ( it ) ;
2009-06-14 15:34:22 -04:00
2012-11-02 09:52:29 -04:00
if ( flags & RS_FILE_REQ_ANONYMOUS_ROUTING )
2016-11-02 15:51:42 -04:00
mFtServer - > activateTunnels ( hash_to_suppress , mDefaultEncryptionPolicy , flags , false ) ;
2010-01-11 17:38:18 -05:00
2016-10-12 14:43:38 -04:00
} // UNLOCK: RS_STACK_MUTEX(ctrlMutex);
2008-11-09 17:17:20 -05:00
/******************** NO Mutex from Now ********************
* cos Callback can end up back in this class .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-10-29 16:58:23 -04:00
/* If it has a callback - do it now */
2010-10-16 11:21:37 -04:00
2016-07-30 15:52:42 -04:00
if ( flags & RS_FILE_REQ_EXTRA ) // | RS_FILE_HINTS_MEDIA))
2008-10-29 16:58:23 -04:00
{
2008-11-09 17:17:20 -05:00
# ifdef CONTROL_DEBUG
2010-10-16 11:21:37 -04:00
std : : cerr < < " ftController::completeFile() adding to ExtraList " ;
std : : cerr < < std : : endl ;
2008-11-09 17:17:20 -05:00
# endif
2017-06-26 17:35:01 -04:00
if ( mExtraList )
mExtraList - > addExtraFile ( path , hash , size , period , extraflags ) ;
2008-10-29 16:58:23 -04:00
}
2008-11-04 18:12:53 -05:00
else
{
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController::completeFile() No callback " ;
std : : cerr < < std : : endl ;
# endif
}
2009-06-11 17:41:42 -04:00
2010-11-24 19:20:25 -05:00
/* Notify GUI */
2016-07-30 15:52:42 -04:00
RsServer : : notify ( ) - > AddPopupMessage ( RS_POPUP_DOWNLOAD , hash . toStdString ( ) , name , " " ) ;
2014-01-07 17:51:22 -05:00
2016-07-30 15:52:42 -04:00
RsServer : : notify ( ) - > notifyDownloadComplete ( hash . toStdString ( ) ) ;
RsServer : : notify ( ) - > notifyDownloadCompleteCount ( completeCount ) ;
2013-02-27 05:03:54 -05:00
2016-07-30 15:52:42 -04:00
rsFiles - > ForceDirectoryCheck ( ) ;
2010-11-24 19:20:25 -05:00
2008-11-15 15:00:29 -05:00
IndicateConfigChanged ( ) ; /* completed transfer -> save */
2008-07-23 18:01:59 -04:00
return true ;
}
/***************************************************************/
/********************** Controller Access **********************/
/***************************************************************/
2008-11-20 19:10:59 -05:00
bool ftController : : activate ( )
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
mFtActive = true ;
mFtPendingDone = false ;
return true ;
}
2009-08-10 15:01:27 -04:00
bool ftController : : isActiveAndNoPending ( )
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
return ( mFtActive & & mFtPendingDone ) ;
}
2008-11-20 19:10:59 -05:00
bool ftController : : handleAPendingRequest ( )
{
ftPendingRequest req ;
2009-12-10 17:55:27 -05:00
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2008-11-20 19:10:59 -05:00
2009-12-10 17:55:27 -05:00
if ( mPendingRequests . size ( ) < 1 )
{
return false ;
}
req = mPendingRequests . front ( ) ;
mPendingRequests . pop_front ( ) ;
2008-11-20 19:10:59 -05:00
}
2010-06-29 16:51:16 -04:00
# ifdef CONTROL_DEBUG
std : : cerr < < " Requesting pending hash " < < req . mHash < < std : : endl ;
# endif
2009-12-10 17:55:27 -05:00
2013-10-06 08:56:37 -04:00
FileRequest ( req . mName , req . mHash , req . mSize , req . mDest , TransferRequestFlags ( req . mFlags ) , req . mSrcIds , req . mState ) ;
2009-12-10 17:55:27 -05:00
{
// See whether there is a pendign chunk map recorded for this hash.
//
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , RsFileTransfer * > : : iterator it ( mPendingChunkMaps . find ( req . mHash ) ) ;
2009-12-10 17:55:27 -05:00
if ( it ! = mPendingChunkMaps . end ( ) )
{
RsFileTransfer * rsft = it - > second ;
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator fit = mDownloads . find ( rsft - > file . hash ) ;
2009-12-10 17:55:27 -05:00
2010-03-06 18:29:47 -05:00
if ( ( fit = = mDownloads . end ( ) | | ( fit - > second ) - > mCreator = = NULL ) )
2009-12-10 17:55:27 -05:00
{
// This should never happen, because the last call to FileRequest must have created the fileCreator!!
//
std : : cerr < < " ftController::loadList(): Error: could not find hash " < < rsft - > file . hash < < " in mDownloads list ! " < < std : : endl ;
}
else
2010-01-11 11:00:42 -05:00
{
2010-06-29 16:51:16 -04:00
# ifdef CONTROL_DEBUG
std : : cerr < < " Hash " < < req . mHash < < " is in downloads " < < std : : endl ;
std : : cerr < < " setting chunk strategy to " < < rsft - > chunk_strategy < < std : : endl ;
# endif
2010-03-06 18:29:47 -05:00
( fit - > second ) - > mCreator - > setAvailabilityMap ( rsft - > compressed_chunk_map ) ;
( fit - > second ) - > mCreator - > setChunkStrategy ( ( FileChunksInfo : : ChunkStrategy ) ( rsft - > chunk_strategy ) ) ;
2013-10-06 08:56:37 -04:00
( fit - > second ) - > mState = rsft - > state ;
2010-01-11 11:00:42 -05:00
}
2009-12-10 17:55:27 -05:00
delete rsft ;
mPendingChunkMaps . erase ( it ) ;
}
2010-06-29 16:51:16 -04:00
# ifdef CONTROL_DEBUG
else
std : : cerr < < " No pending chunkmap for hash " < < req . mHash < < std : : endl ;
# endif
2009-12-10 17:55:27 -05:00
}
2009-12-28 16:11:00 -05:00
return true ;
2008-11-20 19:10:59 -05:00
}
2014-03-17 16:56:06 -04:00
bool ftController : : alreadyHaveFile ( const RsFileHash & hash , FileInfo & info )
2010-01-16 10:42:26 -05:00
{
// check for downloads
2010-10-05 16:39:14 -04:00
if ( FileDetails ( hash , info ) & & ( info . downloadStatus = = FT_STATE_COMPLETE ) )
2010-01-16 10:42:26 -05:00
return true ;
// check for file lists
2017-07-06 16:35:54 -04:00
if ( ! mSearch ) return false ;
2012-11-02 09:52:29 -04:00
if ( mSearch - > search ( hash , RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_SPEC_ONLY , info ) )
2010-01-16 10:42:26 -05:00
return true ;
return false ;
}
2008-11-20 19:10:59 -05:00
2014-03-17 16:56:06 -04:00
bool ftController : : FileRequest ( const std : : string & fname , const RsFileHash & hash ,
2012-11-02 09:52:29 -04:00
uint64_t size , const std : : string & dest , TransferRequestFlags flags ,
2014-03-17 16:56:06 -04:00
const std : : list < RsPeerId > & _srcIds , uint16_t state )
2008-07-23 18:01:59 -04:00
{
2014-03-17 16:56:06 -04:00
std : : list < RsPeerId > srcIds ( _srcIds ) ;
2010-07-21 19:14:10 -04:00
2010-03-17 11:34:36 -04:00
/* check if we have the file */
2010-10-05 16:39:14 -04:00
FileInfo info ;
if ( alreadyHaveFile ( hash , info ) )
2010-03-17 11:34:36 -04:00
return false ;
2016-11-01 09:13:43 -04:00
// the strategy for requesting encryption is the following:
//
// if policy is STRICT
// - disable clear, enforce encryption
// else
2017-01-23 13:13:50 -05:00
// - if not specified, use both
2016-11-01 09:13:43 -04:00
//
2016-10-29 11:59:03 -04:00
if ( mDefaultEncryptionPolicy = = RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT )
{
flags | = RS_FILE_REQ_ENCRYPTED ;
flags & = ~ RS_FILE_REQ_UNENCRYPTED ;
}
2016-11-01 09:13:43 -04:00
else if ( ! ( flags & ( RS_FILE_REQ_ENCRYPTED | RS_FILE_REQ_UNENCRYPTED ) ) )
2017-01-23 13:13:50 -05:00
{
flags | = RS_FILE_REQ_ENCRYPTED ;
flags | = RS_FILE_REQ_UNENCRYPTED ;
}
2016-10-29 11:59:03 -04:00
2010-03-06 18:29:47 -05:00
if ( size = = 0 ) // we treat this special case because
{
/* if no destpath - send to download directory */
std : : string destination ;
if ( dest = = " " )
destination = mDownloadPath + " / " + fname ;
else
destination = dest + " / " + fname ;
// create void file with the target name.
2011-04-03 19:11:38 -04:00
FILE * f = RsDirUtil : : rs_fopen ( destination . c_str ( ) , " w " ) ;
2010-03-06 18:29:47 -05:00
if ( f = = NULL )
std : : cerr < < " Could not open file " < < destination < < " for writting. " < < std : : endl ;
else
fclose ( f ) ;
return true ;
}
2010-05-17 17:05:28 -04:00
// Bugs in the cache system can cause files with arbitrary size to be
// requested, causing a division by zero in ftChunkMap when size > 1MB *
// (2^32-1). I thus conservatively check for large size values.
//
if ( size > = 1024ull * 1024ull * ( ( 1ull < < 32 ) - 1 ) )
{
std : : cerr < < " FileRequest Error: unexpected size. This is probably a bug. " < < std : : endl ;
std : : cerr < < " name = " < < fname < < std : : endl ;
std : : cerr < < " flags = " < < flags < < std : : endl ;
std : : cerr < < " dest = " < < dest < < std : : endl ;
std : : cerr < < " size = " < < size < < std : : endl ;
return false ;
}
2008-11-20 19:10:59 -05:00
/* If file transfer is not enabled ....
* save request for later . This will also
2009-06-11 17:41:42 -04:00
* mean that we will have to copy local files ,
2008-11-20 19:10:59 -05:00
* or have a callback which says : local file .
*/
2009-06-11 17:41:42 -04:00
{
2009-02-12 07:47:57 -05:00
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
if ( ! mFtActive )
{
/* store in pending queue */
2013-10-06 08:56:37 -04:00
ftPendingRequest req ( fname , hash , size , dest , flags , srcIds , state ) ;
2009-02-12 07:47:57 -05:00
mPendingRequests . push_back ( req ) ;
return true ;
}
2008-11-20 19:10:59 -05:00
}
2013-11-28 15:53:03 -05:00
// remove the sources from the list, if they don't have clearance for direct transfer. This happens only for non cache files.
//
2017-06-26 17:35:01 -04:00
for ( std : : list < RsPeerId > : : iterator it = srcIds . begin ( ) ; it ! = srcIds . end ( ) ; )
{
bool bAllowDirectDL = false ;
2017-07-17 05:16:48 -04:00
switch ( mFilePermDirectDLPolicy ) {
2017-06-26 17:35:01 -04:00
case RS_FILE_PERM_DIRECT_DL_YES : bAllowDirectDL = true ; break ;
case RS_FILE_PERM_DIRECT_DL_NO : bAllowDirectDL = false ; break ;
default : bAllowDirectDL = ( rsPeers - > servicePermissionFlags ( * it ) & RS_NODE_PERM_DIRECT_DL ) ; break ;
}
if ( ! bAllowDirectDL )
{
std : : list < RsPeerId > : : iterator tmp ( it ) ;
+ + tmp ;
srcIds . erase ( it ) ;
it = tmp ;
}
else
+ + it ;
}
std : : list < RsPeerId > : : const_iterator it ;
2010-07-21 19:14:10 -04:00
std : : list < TransferInfo > : : const_iterator pit ;
2008-07-23 18:01:59 -04:00
2008-08-17 11:23:11 -04:00
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController::FileRequest( " < < fname < < " , " ;
std : : cerr < < hash < < " , " < < size < < " , " < < dest < < " , " ;
std : : cerr < < flags < < " ,< " ;
2014-10-24 18:07:26 -04:00
for ( it = srcIds . begin ( ) ; it ! = srcIds . end ( ) ; + + it )
2008-07-23 18:01:59 -04:00
{
2008-08-17 11:23:11 -04:00
std : : cerr < < * it < < " , " ;
2008-07-23 18:01:59 -04:00
}
2008-08-17 11:23:11 -04:00
std : : cerr < < " >) " ;
std : : cerr < < std : : endl ;
# endif
2008-11-09 17:17:20 -05:00
uint32_t rate = 0 ;
2012-11-02 09:52:29 -04:00
if ( flags & RS_FILE_REQ_BACKGROUND )
2008-11-09 17:17:20 -05:00
rate = FT_CNTRL_SLOW_RATE ;
else
rate = FT_CNTRL_STANDARD_RATE ;
2009-06-11 17:41:42 -04:00
/* First check if the file is already being downloaded....
2008-11-09 17:17:20 -05:00
* This is important as some guis request duplicate files regularly .
*/
2010-01-16 10:42:26 -05:00
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2008-11-15 15:00:29 -05:00
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : const_iterator dit = mDownloads . find ( hash ) ;
2010-03-06 18:29:47 -05:00
2010-01-16 10:42:26 -05:00
if ( dit ! = mDownloads . end ( ) )
{
/* we already have it! */
2008-11-09 17:17:20 -05:00
# ifdef CONTROL_DEBUG
2010-01-16 10:42:26 -05:00
std : : cerr < < " ftController::FileRequest() Already Downloading File " ;
std : : cerr < < std : : endl ;
std : : cerr < < " \t No need to download " ;
std : : cerr < < std : : endl ;
2008-11-09 17:17:20 -05:00
# endif
2010-01-16 10:42:26 -05:00
/* but we should add this peer - if they don't exist!
* ( needed for channels ) .
*/
2008-11-09 17:17:20 -05:00
2014-10-24 18:07:26 -04:00
for ( it = srcIds . begin ( ) ; it ! = srcIds . end ( ) ; + + it )
2017-06-26 17:35:01 -04:00
{
bool bAllowDirectDL = false ;
2017-07-17 05:16:48 -04:00
switch ( mFilePermDirectDLPolicy ) {
2017-06-26 17:35:01 -04:00
case RS_FILE_PERM_DIRECT_DL_YES : bAllowDirectDL = true ; break ;
case RS_FILE_PERM_DIRECT_DL_NO : bAllowDirectDL = false ; break ;
default : bAllowDirectDL = ( rsPeers - > servicePermissionFlags ( * it ) & RS_NODE_PERM_DIRECT_DL ) ; break ;
}
if ( bAllowDirectDL )
2010-01-16 10:42:26 -05:00
{
2013-11-27 15:12:16 -05:00
uint32_t i , j ;
if ( ( dit - > second ) - > mTransfer - > getPeerState ( * it , i , j ) )
{
2008-11-09 17:17:20 -05:00
# ifdef CONTROL_DEBUG
2013-11-27 15:12:16 -05:00
std : : cerr < < " ftController::FileRequest() Peer Existing " ;
std : : cerr < < std : : endl ;
2008-11-09 17:17:20 -05:00
# endif
2013-11-27 15:12:16 -05:00
continue ; /* already added peer */
}
2008-11-09 17:17:20 -05:00
# ifdef CONTROL_DEBUG
2013-11-27 15:12:16 -05:00
std : : cerr < < " ftController::FileRequest() Adding Peer: " < < * it ;
std : : cerr < < std : : endl ;
2008-11-09 17:17:20 -05:00
# endif
2013-11-27 15:12:16 -05:00
( dit - > second ) - > mTransfer - > addFileSource ( * it ) ;
2016-11-22 17:19:34 -05:00
setPeerState ( dit - > second - > mTransfer , * it , rate , mServiceCtrl - > isPeerConnected ( mFtServiceType , * it ) ) ;
2013-11-27 15:12:16 -05:00
}
2017-06-26 17:35:01 -04:00
}
2008-11-09 17:17:20 -05:00
2014-10-21 18:33:02 -04:00
if ( srcIds . empty ( ) )
2010-01-16 10:42:26 -05:00
{
2008-11-13 18:03:46 -05:00
# ifdef CONTROL_DEBUG
2010-01-16 10:42:26 -05:00
std : : cerr < < " ftController::FileRequest() WARNING: No Src Peers " ;
std : : cerr < < std : : endl ;
2008-11-13 18:03:46 -05:00
# endif
2010-01-16 10:42:26 -05:00
}
2008-11-13 18:03:46 -05:00
2010-01-16 10:42:26 -05:00
return true ;
}
} /******* UNLOCKED ********/
2008-11-09 17:17:20 -05:00
2013-11-28 15:53:03 -05:00
2017-06-26 17:35:01 -04:00
if ( mSearch & & ! ( flags & RS_FILE_REQ_NO_SEARCH ) )
2008-07-23 18:01:59 -04:00
{
2008-08-17 11:23:11 -04:00
/* do a source search - for any extra sources */
2010-01-22 18:23:37 -05:00
// add sources only in direct mode
//
2012-11-01 06:06:12 -04:00
if ( /* (flags & RS_FILE_HINTS_BROWSABLE) && */ mSearch - > search ( hash , RS_FILE_HINTS_REMOTE | RS_FILE_HINTS_SPEC_ONLY , info ) )
2008-08-17 11:23:11 -04:00
{
/* do something with results */
2008-10-29 16:58:23 -04:00
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController::FileRequest() Found Other Sources " ;
std : : cerr < < std : : endl ;
# endif
/* if the sources don't exist already - add in */
2014-10-24 18:07:26 -04:00
for ( pit = info . peers . begin ( ) ; pit ! = info . peers . end ( ) ; + + pit )
2008-10-29 16:58:23 -04:00
{
2009-12-14 13:10:20 -05:00
# ifdef CONTROL_DEBUG
std : : cerr < < " \t Source: " < < pit - > peerId ;
2008-10-29 16:58:23 -04:00
std : : cerr < < std : : endl ;
2009-12-14 13:10:20 -05:00
# endif
2013-06-06 16:52:24 -04:00
// Because this is auto-add, we only add sources that we allow to DL from using direct transfers.
2008-10-29 16:58:23 -04:00
2017-06-26 17:35:01 -04:00
bool bAllowDirectDL = false ;
2017-07-17 05:16:48 -04:00
switch ( mFilePermDirectDLPolicy ) {
2017-06-26 17:35:01 -04:00
case RS_FILE_PERM_DIRECT_DL_YES : bAllowDirectDL = true ; break ;
case RS_FILE_PERM_DIRECT_DL_NO : bAllowDirectDL = false ; break ;
default : bAllowDirectDL = ( rsPeers - > servicePermissionFlags ( pit - > peerId ) & RS_NODE_PERM_DIRECT_DL ) ; break ;
}
if ( ( srcIds . end ( ) = = std : : find ( srcIds . begin ( ) , srcIds . end ( ) , pit - > peerId ) ) & & bAllowDirectDL )
2008-10-29 16:58:23 -04:00
{
2008-11-02 06:38:11 -05:00
srcIds . push_back ( pit - > peerId ) ;
2008-10-29 16:58:23 -04:00
2009-12-14 13:10:20 -05:00
# ifdef CONTROL_DEBUG
2013-06-06 16:52:24 -04:00
std : : cerr < < " \t Adding in: " < < pit - > peerId ;
2008-10-29 16:58:23 -04:00
std : : cerr < < std : : endl ;
2009-12-14 13:10:20 -05:00
# endif
2013-06-06 16:52:24 -04:00
}
2009-06-11 17:41:42 -04:00
}
2008-10-29 16:58:23 -04:00
}
2008-07-23 18:01:59 -04:00
}
/* add in new item for download */
2008-11-15 15:00:29 -05:00
std : : string savepath ;
std : : string destination ;
2010-01-16 10:42:26 -05:00
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2008-11-15 15:00:29 -05:00
2014-03-17 16:56:06 -04:00
savepath = mPartialsPath + " / " + hash . toStdString ( ) ;
2010-01-16 10:42:26 -05:00
destination = dest + " / " + fname ;
2008-10-29 16:58:23 -04:00
2010-01-16 10:42:26 -05:00
/* if no destpath - send to download directory */
if ( dest = = " " )
destination = mDownloadPath + " / " + fname ;
} /******* UNLOCKED ********/
2009-06-11 17:41:42 -04:00
2010-11-10 17:05:34 -05:00
// We check that flags are consistent.
2010-01-11 17:38:18 -05:00
2012-11-02 09:52:29 -04:00
if ( flags & RS_FILE_REQ_ANONYMOUS_ROUTING )
2016-11-02 15:51:42 -04:00
mFtServer - > activateTunnels ( hash , mDefaultEncryptionPolicy , flags , true ) ;
2010-01-11 17:38:18 -05:00
2016-07-30 15:52:42 -04:00
bool assume_availability = false ;
2010-11-22 15:57:53 -05:00
ftFileCreator * fc = new ftFileCreator ( savepath , size , hash , assume_availability ) ;
2008-09-08 10:04:10 -04:00
ftTransferModule * tm = new ftTransferModule ( fc , mDataplex , this ) ;
2008-07-23 18:01:59 -04:00
2010-04-30 17:07:21 -04:00
# ifdef CONTROL_DEBUG
std : : cerr < < " Note: setting chunk strategy to " < < mDefaultChunkStrategy < < std : : endl ;
# endif
2010-03-21 17:07:12 -04:00
fc - > setChunkStrategy ( mDefaultChunkStrategy ) ;
2008-07-23 18:01:59 -04:00
/* add into maps */
2010-10-16 11:21:37 -04:00
ftFileControl * ftfc = new ftFileControl ( fname , savepath , destination , size , hash , flags , fc , tm ) ;
2010-03-06 18:29:47 -05:00
ftfc - > mCreateTime = time ( NULL ) ;
2008-07-23 18:01:59 -04:00
/* now add source peers (and their current state) */
tm - > setFileSources ( srcIds ) ;
/* get current state for transfer module */
2014-10-24 18:07:26 -04:00
for ( it = srcIds . begin ( ) ; it ! = srcIds . end ( ) ; + + it )
2008-07-23 18:01:59 -04:00
{
2008-08-21 17:30:59 -04:00
# ifdef CONTROL_DEBUG
2008-11-13 18:03:46 -05:00
std : : cerr < < " ftController::FileRequest() adding peer: " < < * it ;
std : : cerr < < std : : endl ;
2008-08-17 11:23:11 -04:00
# endif
2016-11-22 17:19:34 -05:00
setPeerState ( tm , * it , rate , mServiceCtrl - > isPeerConnected ( mFtServiceType , * it ) ) ;
2008-07-23 18:01:59 -04:00
}
2010-05-16 17:21:41 -04:00
/* add structures into the accessible data. Needs to be locked */
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2012-02-12 15:00:22 -05:00
locked_addToQueue ( ftfc , FT_FILECONTROL_QUEUE_ADD_END ) ;
2010-05-16 17:21:41 -04:00
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController::FileRequest() Created ftFileCreator @: " < < fc ;
std : : cerr < < std : : endl ;
std : : cerr < < " ftController::FileRequest() Created ftTransModule @: " < < tm ;
std : : cerr < < std : : endl ;
std : : cerr < < " ftController::FileRequest() Created ftFileControl. " ;
std : : cerr < < std : : endl ;
# endif
2008-11-15 15:00:29 -05:00
2010-05-16 17:21:41 -04:00
/* add to ClientModule */
mDataplex - > addTransferModule ( tm , fc ) ;
mDownloads [ hash ] = ftfc ;
}
2008-11-15 15:00:29 -05:00
IndicateConfigChanged ( ) ; /* completed transfer -> save */
2008-10-29 16:58:23 -04:00
return true ;
2008-08-09 13:03:24 -04:00
}
2014-03-17 16:56:06 -04:00
bool ftController : : setPeerState ( ftTransferModule * tm , const RsPeerId & id , uint32_t maxrate , bool online )
2008-11-13 18:03:46 -05:00
{
2014-03-28 23:57:44 -04:00
if ( id = = mServiceCtrl - > getOwnId ( ) )
2008-11-13 18:03:46 -05:00
{
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController::setPeerState() is Self " ;
std : : cerr < < std : : endl ;
# endif
tm - > setPeerState ( id , PQIPEER_IDLE , maxrate ) ;
}
2009-05-26 17:42:45 -04:00
else if ( online | | mTurtle - > isOnline ( id ) )
2008-11-13 18:03:46 -05:00
{
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController::setPeerState() " ;
std : : cerr < < " Peer is Online " ;
std : : cerr < < std : : endl ;
# endif
tm - > setPeerState ( id , PQIPEER_IDLE , maxrate ) ;
}
else
{
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController::setPeerState() " ;
std : : cerr < < " Peer is Offline " ;
std : : cerr < < std : : endl ;
# endif
tm - > setPeerState ( id , PQIPEER_NOT_ONLINE , maxrate ) ;
}
return true ;
}
2014-03-17 16:56:06 -04:00
bool ftController : : setChunkStrategy ( const RsFileHash & hash , FileChunksInfo : : ChunkStrategy s )
2009-12-08 17:29:52 -05:00
{
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator mit = mDownloads . find ( hash ) ;
2009-12-08 17:29:52 -05:00
if ( mit = = mDownloads . end ( ) )
{
# ifdef CONTROL_DEBUG
2010-01-26 15:40:21 -05:00
std : : cerr < < " ftController::setChunkStrategy file is not found in mDownloads " < < std : : endl ;
2009-12-08 17:29:52 -05:00
# endif
return false ;
}
2010-03-06 18:29:47 -05:00
mit - > second - > mCreator - > setChunkStrategy ( s ) ;
2009-12-08 17:29:52 -05:00
return true ;
}
2008-11-04 18:12:53 -05:00
2014-03-17 16:56:06 -04:00
bool ftController : : FileCancel ( const RsFileHash & hash )
2008-08-09 13:03:24 -04:00
{
2016-11-02 15:51:42 -04:00
mFtServer - > activateTunnels ( hash , mDefaultEncryptionPolicy , TransferRequestFlags ( 0 ) , false ) ;
2010-01-11 17:38:18 -05:00
2008-09-08 04:44:37 -04:00
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController::FileCancel " < < std : : endl ;
# endif
/*check if the file in the download map*/
2010-01-26 15:40:21 -05:00
2008-09-08 04:44:37 -04:00
{
2010-01-26 15:40:21 -05:00
RsStackMutex mtx ( ctrlMutex ) ;
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator mit = mDownloads . find ( hash ) ;
2010-01-26 15:40:21 -05:00
if ( mit = = mDownloads . end ( ) )
{
2008-09-08 04:44:37 -04:00
# ifdef CONTROL_DEBUG
2010-01-26 15:40:21 -05:00
std : : cerr < < " ftController::FileCancel file is not found in mDownloads " < < std : : endl ;
2008-09-08 04:44:37 -04:00
# endif
2010-01-26 15:40:21 -05:00
return false ;
}
2008-09-08 04:44:37 -04:00
2010-01-26 15:40:21 -05:00
/* check if finished */
2010-03-06 18:29:47 -05:00
if ( ( mit - > second ) - > mCreator - > finished ( ) )
2010-01-26 15:40:21 -05:00
{
2008-11-29 17:03:36 -05:00
# ifdef CONTROL_DEBUG
2010-01-26 15:40:21 -05:00
std : : cerr < < " ftController:FileCancel( " < < hash < < " ) " ;
std : : cerr < < " Transfer Already finished " ;
std : : cerr < < std : : endl ;
2008-11-29 17:03:36 -05:00
2010-01-26 15:40:21 -05:00
std : : cerr < < " FileSize: " ;
2010-03-06 18:29:47 -05:00
std : : cerr < < ( mit - > second ) - > mCreator - > getFileSize ( ) ;
2010-01-26 15:40:21 -05:00
std : : cerr < < " and Recvd: " ;
2010-03-06 18:29:47 -05:00
std : : cerr < < ( mit - > second ) - > mCreator - > getRecvd ( ) ;
2008-11-29 17:03:36 -05:00
# endif
2010-01-26 15:40:21 -05:00
return false ;
}
2008-11-29 17:03:36 -05:00
2010-01-26 15:40:21 -05:00
/*find the point to transfer module*/
2010-03-06 18:29:47 -05:00
ftTransferModule * ft = ( mit - > second ) - > mTransfer ;
2010-01-26 15:40:21 -05:00
ft - > cancelTransfer ( ) ;
2008-11-29 17:03:36 -05:00
2010-03-06 18:29:47 -05:00
ftFileControl * fc = mit - > second ;
2010-01-26 15:40:21 -05:00
mDataplex - > removeTransferModule ( fc - > mTransfer - > hash ( ) ) ;
2008-11-29 17:03:36 -05:00
2010-01-26 15:40:21 -05:00
if ( fc - > mTransfer )
{
delete fc - > mTransfer ;
fc - > mTransfer = NULL ;
}
2008-11-29 17:03:36 -05:00
2010-01-26 15:40:21 -05:00
if ( fc - > mCreator )
{
delete fc - > mCreator ;
fc - > mCreator = NULL ;
}
2008-11-29 17:03:36 -05:00
2010-01-26 15:40:21 -05:00
/* delete the temporary file */
if ( 0 = = remove ( fc - > mCurrentPath . c_str ( ) ) )
{
2008-11-30 16:43:51 -05:00
# ifdef CONTROL_DEBUG
2010-01-26 15:40:21 -05:00
std : : cerr < < " ftController::FileCancel() remove temporary file " ;
std : : cerr < < fc - > mCurrentPath ;
std : : cerr < < std : : endl ;
2008-11-30 16:43:51 -05:00
# endif
2010-01-26 15:40:21 -05:00
}
else
{
2008-11-30 16:43:51 -05:00
# ifdef CONTROL_DEBUG
2010-01-26 15:40:21 -05:00
std : : cerr < < " ftController::FileCancel() fail to remove file " ;
std : : cerr < < fc - > mCurrentPath ;
std : : cerr < < std : : endl ;
2008-11-30 16:43:51 -05:00
# endif
2010-01-26 15:40:21 -05:00
}
2008-11-30 16:43:51 -05:00
2010-03-06 18:29:47 -05:00
locked_queueRemove ( fc - > mQueuePosition ) ;
delete fc ;
2010-01-26 15:40:21 -05:00
mDownloads . erase ( mit ) ;
}
2008-11-29 17:03:36 -05:00
2009-06-14 15:34:22 -04:00
IndicateConfigChanged ( ) ; /* completed transfer -> save */
2008-09-08 04:44:37 -04:00
return true ;
2008-07-23 18:01:59 -04:00
}
2014-03-17 16:56:06 -04:00
bool ftController : : FileControl ( const RsFileHash & hash , uint32_t flags )
2008-08-09 13:03:24 -04:00
{
2010-10-16 12:49:35 -04:00
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController::FileControl( " < < hash < < " , " ;
std : : cerr < < flags < < " ) " < < std : : endl ;
# endif
2010-03-15 08:57:08 -04:00
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2008-09-08 04:44:37 -04:00
/*check if the file in the download map*/
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator mit = mDownloads . find ( hash ) ;
2008-09-08 04:44:37 -04:00
if ( mit = = mDownloads . end ( ) )
{
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController::FileControl file is not found in mDownloads " < < std : : endl ;
# endif
return false ;
}
/*find the point to transfer module*/
switch ( flags )
{
case RS_FILE_CTRL_PAUSE :
2010-03-15 08:57:08 -04:00
mit - > second - > mState = ftFileControl : : PAUSED ;
2010-07-21 19:14:10 -04:00
std : : cerr < < " setting state to " < < ftFileControl : : PAUSED < < std : : endl ;
2008-09-08 04:44:37 -04:00
break ;
2010-07-21 19:14:10 -04:00
2008-09-08 04:44:37 -04:00
case RS_FILE_CTRL_START :
2010-03-15 08:57:08 -04:00
mit - > second - > mState = ftFileControl : : DOWNLOADING ;
2010-07-21 19:14:10 -04:00
std : : cerr < < " setting state to " < < ftFileControl : : DOWNLOADING < < std : : endl ;
2008-09-08 04:44:37 -04:00
break ;
2010-07-21 19:14:10 -04:00
case RS_FILE_CTRL_FORCE_CHECK :
mit - > second - > mTransfer - > forceCheck ( ) ;
std : : cerr < < " setting state to " < < ftFileControl : : CHECKING_HASH < < std : : endl ;
break ;
2008-09-08 04:44:37 -04:00
default :
return false ;
}
2013-10-06 08:56:37 -04:00
IndicateConfigChanged ( ) ;
2008-09-08 04:44:37 -04:00
return true ;
2008-08-09 13:03:24 -04:00
}
2008-07-23 18:01:59 -04:00
2008-08-09 13:03:24 -04:00
bool ftController : : FileClearCompleted ( )
{
2008-12-04 16:34:19 -05:00
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController::FileClearCompleted() " < < std : : endl ;
# endif
2010-11-24 19:20:25 -05:00
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2014-03-17 16:56:06 -04:00
for ( std : : map < RsFileHash , ftFileControl * > : : iterator it ( mCompleted . begin ( ) ) ; it ! = mCompleted . end ( ) ; + + it )
2010-11-24 19:20:25 -05:00
delete it - > second ;
2010-03-06 18:29:47 -05:00
2010-11-24 19:20:25 -05:00
mCompleted . clear ( ) ;
2010-03-06 18:29:47 -05:00
2010-11-24 19:20:25 -05:00
IndicateConfigChanged ( ) ;
} /******* UNLOCKED ********/
2010-03-06 18:29:47 -05:00
2014-01-07 17:51:22 -05:00
RsServer : : notify ( ) - > notifyDownloadCompleteCount ( 0 ) ;
2010-02-19 15:36:47 -05:00
2008-08-09 13:03:24 -04:00
return false ;
}
2008-07-23 18:01:59 -04:00
/* get Details of File Transfers */
2015-03-08 09:46:07 -04:00
void ftController : : FileDownloads ( std : : list < RsFileHash > & hashs )
2008-07-23 18:01:59 -04:00
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator it ;
2014-10-24 18:07:26 -04:00
for ( it = mDownloads . begin ( ) ; it ! = mDownloads . end ( ) ; + + it )
2008-07-23 18:01:59 -04:00
{
2010-03-06 18:29:47 -05:00
hashs . push_back ( it - > second - > mHash ) ;
2008-07-23 18:01:59 -04:00
}
2014-10-24 18:07:26 -04:00
for ( it = mCompleted . begin ( ) ; it ! = mCompleted . end ( ) ; + + it )
2008-11-09 17:17:20 -05:00
{
2010-03-06 18:29:47 -05:00
hashs . push_back ( it - > second - > mHash ) ;
2008-11-09 17:17:20 -05:00
}
2008-07-23 18:01:59 -04:00
}
/* Directory Handling */
bool ftController : : setDownloadDirectory ( std : : string path )
{
2008-08-29 21:07:24 -04:00
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController::setDownloadDirectory( " < < path < < " ) " ;
std : : cerr < < std : : endl ;
# endif
2008-07-23 18:01:59 -04:00
/* check if it exists */
if ( RsDirUtil : : checkCreateDirectory ( path ) )
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2011-05-15 08:42:55 -04:00
mDownloadPath = RsDirUtil : : convertPathToUnix ( path ) ;
2011-09-23 17:08:11 -04:00
RsDiscSpace : : setDownloadPath ( mDownloadPath ) ;
2008-08-29 21:07:24 -04:00
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController::setDownloadDirectory() Okay! " ;
std : : cerr < < std : : endl ;
# endif
2009-06-11 17:41:42 -04:00
IndicateConfigChanged ( ) ;
2008-07-23 18:01:59 -04:00
return true ;
}
2008-08-29 21:07:24 -04:00
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController::setDownloadDirectory() Failed " ;
std : : cerr < < std : : endl ;
# endif
2008-07-23 18:01:59 -04:00
return false ;
}
2008-08-09 13:03:24 -04:00
bool ftController : : setPartialsDirectory ( std : : string path )
2008-07-23 18:01:59 -04:00
{
2008-08-09 13:03:24 -04:00
2008-07-23 18:01:59 -04:00
/* check it is not a subdir of download / shared directories (BAD) - TODO */
2009-06-11 17:41:42 -04:00
{
RsStackMutex stack ( ctrlMutex ) ;
2011-05-15 08:42:55 -04:00
path = RsDirUtil : : convertPathToUnix ( path ) ;
2009-06-11 17:41:42 -04:00
if ( ! path . find ( mDownloadPath ) ) {
return false ;
}
if ( rsFiles ) {
2009-08-04 05:19:32 -04:00
std : : list < SharedDirInfo > : : iterator it ;
std : : list < SharedDirInfo > dirs ;
2009-06-11 17:41:42 -04:00
rsFiles - > getSharedDirectories ( dirs ) ;
2014-10-24 18:07:26 -04:00
for ( it = dirs . begin ( ) ; it ! = dirs . end ( ) ; + + it ) {
2009-08-04 05:19:32 -04:00
if ( ! path . find ( ( * it ) . filename ) ) {
2009-06-11 17:41:42 -04:00
return false ;
}
}
}
}
2008-07-23 18:01:59 -04:00
/* check if it exists */
if ( RsDirUtil : : checkCreateDirectory ( path ) )
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2008-10-29 16:58:23 -04:00
mPartialsPath = path ;
2008-07-23 18:01:59 -04:00
2011-09-23 17:08:11 -04:00
RsDiscSpace : : setPartialsPath ( path ) ;
2008-10-29 16:58:23 -04:00
#if 0 /*** FIX ME !!!**************/
2008-07-23 18:01:59 -04:00
/* move all existing files! */
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl > : : iterator it ;
2014-10-24 18:07:26 -04:00
for ( it = mDownloads . begin ( ) ; it ! = mDownloads . end ( ) ; + + it )
2008-07-23 18:01:59 -04:00
{
( it - > second ) . mCreator - > changePartialDirectory ( mPartialPath ) ;
}
2008-10-29 16:58:23 -04:00
# endif
2009-06-11 17:41:42 -04:00
IndicateConfigChanged ( ) ;
2008-07-23 18:01:59 -04:00
return true ;
}
2008-08-09 13:03:24 -04:00
2008-07-23 18:01:59 -04:00
return false ;
}
std : : string ftController : : getDownloadDirectory ( )
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
return mDownloadPath ;
}
std : : string ftController : : getPartialsDirectory ( )
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2008-10-29 16:58:23 -04:00
return mPartialsPath ;
2008-07-23 18:01:59 -04:00
}
2014-03-17 16:56:06 -04:00
bool ftController : : setDestinationDirectory ( const RsFileHash & hash , const std : : string & dest_dir )
2013-02-27 11:59:16 -05:00
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator it = mDownloads . find ( hash ) ;
2013-02-27 11:59:16 -05:00
if ( it = = mDownloads . end ( ) )
return false ;
std : : cerr < < " (II) Changing destination of file " < < it - > second - > mDestination < < std : : endl ;
it - > second - > mDestination = dest_dir + ' / ' + it - > second - > mName ;
std : : cerr < < " (II) ...to " < < it - > second - > mDestination < < std : : endl ;
return true ;
}
2014-03-17 16:56:06 -04:00
bool ftController : : setDestinationName ( const RsFileHash & hash , const std : : string & dest_name )
2013-02-27 11:59:16 -05:00
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator it = mDownloads . find ( hash ) ;
2013-02-27 11:59:16 -05:00
if ( it = = mDownloads . end ( ) )
return false ;
std : : cerr < < " (II) Changing destination of file " < < it - > second - > mDestination < < std : : endl ;
std : : string dest_path ;
RsDirUtil : : removeTopDir ( it - > second - > mDestination , dest_path ) ; /* remove fname */
it - > second - > mDestination = dest_path + ' / ' + dest_name ;
it - > second - > mName = dest_name ;
std : : cerr < < " (II) ...to " < < it - > second - > mDestination < < std : : endl ;
return true ;
}
2014-03-17 16:56:06 -04:00
bool ftController : : FileDetails ( const RsFileHash & hash , FileInfo & info )
2008-07-23 18:01:59 -04:00
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2008-11-09 17:17:20 -05:00
bool completed = false ;
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator it = mDownloads . find ( hash ) ;
2008-07-23 18:01:59 -04:00
if ( it = = mDownloads . end ( ) )
{
2008-11-09 17:17:20 -05:00
/* search completed files too */
it = mCompleted . find ( hash ) ;
if ( it = = mCompleted . end ( ) )
{
2009-06-11 17:41:42 -04:00
/* Note: mTransfer & mCreator
2008-11-09 17:17:20 -05:00
* are both NULL
*/
return false ;
}
completed = true ;
2008-07-23 18:01:59 -04:00
}
/* extract details */
2008-11-02 06:38:11 -05:00
info . hash = hash ;
2010-03-06 18:29:47 -05:00
info . fname = it - > second - > mName ;
2012-11-08 14:47:39 -05:00
info . storage_permission_flags . clear ( ) ;
2012-11-01 06:06:12 -04:00
info . transfer_info_flags = it - > second - > mFlags ;
2011-11-18 03:49:53 -05:00
info . priority = SPEED_NORMAL ;
2012-06-01 16:51:14 -04:00
RsDirUtil : : removeTopDir ( it - > second - > mDestination , info . path ) ; /* remove fname */
2010-03-06 18:29:47 -05:00
info . queue_position = it - > second - > mQueuePosition ;
2008-11-02 06:38:11 -05:00
2012-11-08 14:47:39 -05:00
if ( it - > second - > mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING )
2016-10-31 09:26:01 -04:00
info . storage_permission_flags | = DIR_FLAGS_ANONYMOUS_DOWNLOAD ; // file being downloaded anonymously are always anonymously available.
2012-11-08 14:47:39 -05:00
2008-11-02 06:38:11 -05:00
/* get list of sources from transferModule */
2014-03-17 16:56:06 -04:00
std : : list < RsPeerId > peerIds ;
std : : list < RsPeerId > : : iterator pit ;
2008-11-02 06:38:11 -05:00
2008-11-09 17:17:20 -05:00
if ( ! completed )
2011-11-18 03:49:53 -05:00
{
2010-03-06 18:29:47 -05:00
it - > second - > mTransfer - > getFileSources ( peerIds ) ;
2011-11-18 03:49:53 -05:00
info . priority = it - > second - > mTransfer - > downloadPriority ( ) ;
2013-12-04 15:26:54 -05:00
info . lastTS = it - > second - > mCreator - > lastRecvTimeStamp ( ) ; // last time the file was actually written
2011-11-18 03:49:53 -05:00
}
2013-11-28 14:43:14 -05:00
else
info . lastTS = 0 ;
2008-11-02 06:38:11 -05:00
2009-02-12 07:47:57 -05:00
double totalRate = 0 ;
uint32_t tfRate = 0 ;
uint32_t state = 0 ;
2008-11-02 06:38:11 -05:00
bool isDownloading = false ;
bool isSuspended = false ;
2014-10-24 18:07:26 -04:00
for ( pit = peerIds . begin ( ) ; pit ! = peerIds . end ( ) ; + + pit )
2008-11-02 06:38:11 -05:00
{
2010-03-06 18:29:47 -05:00
if ( it - > second - > mTransfer - > getPeerState ( * pit , state , tfRate ) )
2008-11-02 06:38:11 -05:00
{
TransferInfo ti ;
switch ( state )
{
case PQIPEER_INIT :
ti . status = FT_STATE_OKAY ;
break ;
case PQIPEER_NOT_ONLINE :
ti . status = FT_STATE_WAITING ;
break ;
case PQIPEER_DOWNLOADING :
isDownloading = true ;
ti . status = FT_STATE_DOWNLOADING ;
break ;
case PQIPEER_IDLE :
ti . status = FT_STATE_OKAY ;
break ;
default :
case PQIPEER_SUSPEND :
isSuspended = true ;
ti . status = FT_STATE_FAILED ;
break ;
}
ti . tfRate = tfRate / 1024.0 ;
ti . peerId = * pit ;
info . peers . push_back ( ti ) ;
totalRate + = tfRate / 1024.0 ;
}
}
2010-03-06 18:29:47 -05:00
if ( ( completed ) | | ( ( it - > second ) - > mCreator - > finished ( ) ) )
2008-11-02 06:38:11 -05:00
{
info . downloadStatus = FT_STATE_COMPLETE ;
}
else if ( isDownloading )
{
info . downloadStatus = FT_STATE_DOWNLOADING ;
}
else if ( isSuspended )
{
info . downloadStatus = FT_STATE_FAILED ;
}
2009-06-11 17:41:42 -04:00
else
2008-11-02 06:38:11 -05:00
{
info . downloadStatus = FT_STATE_WAITING ;
}
2010-03-06 18:29:47 -05:00
if ( it - > second - > mState = = ftFileControl : : QUEUED )
info . downloadStatus = FT_STATE_QUEUED ;
2010-03-15 08:57:08 -04:00
if ( it - > second - > mState = = ftFileControl : : PAUSED )
info . downloadStatus = FT_STATE_PAUSED ;
2010-07-06 01:04:11 -04:00
if ( ( ! completed ) & & it - > second - > mTransfer - > isCheckingHash ( ) )
info . downloadStatus = FT_STATE_CHECKING_HASH ;
2008-11-02 06:38:11 -05:00
info . tfRate = totalRate ;
2010-03-06 18:29:47 -05:00
info . size = ( it - > second ) - > mSize ;
2008-11-09 17:17:20 -05:00
if ( completed )
{
info . transfered = info . size ;
2008-11-30 12:17:28 -05:00
info . avail = info . transfered ;
2008-11-09 17:17:20 -05:00
}
else
{
2010-03-06 18:29:47 -05:00
info . transfered = ( it - > second ) - > mCreator - > getRecvd ( ) ;
2008-11-30 12:17:28 -05:00
info . avail = info . transfered ;
2008-11-09 17:17:20 -05:00
}
2008-07-23 18:01:59 -04:00
return true ;
}
/***************************************************************/
/********************** Controller Access **********************/
/***************************************************************/
/* pqiMonitor callback:
* Used to tell TransferModules new available peers
*/
2014-03-28 23:57:44 -04:00
void ftController : : statusChange ( const std : : list < pqiServicePeer > & plist )
2008-07-23 18:01:59 -04:00
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2008-11-13 18:03:46 -05:00
uint32_t rate = FT_CNTRL_STANDARD_RATE ;
2008-07-23 18:01:59 -04:00
/* add online to all downloads */
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator it ;
2014-03-28 23:57:44 -04:00
std : : list < pqiServicePeer > : : const_iterator pit ;
2008-07-23 18:01:59 -04:00
2016-11-23 13:12:38 -05:00
# ifdef CONTROL_DEBUG
2008-11-13 18:03:46 -05:00
std : : cerr < < " ftController::statusChange() " ;
std : : cerr < < std : : endl ;
2016-11-23 13:12:38 -05:00
# endif
2008-11-13 18:03:46 -05:00
2014-10-24 18:07:26 -04:00
for ( it = mDownloads . begin ( ) ; it ! = mDownloads . end ( ) ; + + it )
2008-07-23 18:01:59 -04:00
{
2008-11-13 18:03:46 -05:00
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController::statusChange() Updating Hash: " ;
std : : cerr < < it - > first ;
std : : cerr < < std : : endl ;
# endif
2014-10-24 18:07:26 -04:00
for ( pit = plist . begin ( ) ; pit ! = plist . end ( ) ; + + pit )
2008-07-23 18:01:59 -04:00
{
2008-11-13 18:03:46 -05:00
# ifdef CONTROL_DEBUG
std : : cerr < < " Peer: " < < pit - > id ;
# endif
2014-03-28 23:57:44 -04:00
if ( pit - > actions & RS_SERVICE_PEER_CONNECTED )
2008-11-13 18:03:46 -05:00
{
# ifdef CONTROL_DEBUG
std : : cerr < < " is Newly Connected! " ;
std : : cerr < < std : : endl ;
# endif
2010-03-06 18:29:47 -05:00
setPeerState ( it - > second - > mTransfer , pit - > id , rate , true ) ;
2008-11-13 18:03:46 -05:00
}
2014-03-28 23:57:44 -04:00
else if ( pit - > actions & RS_SERVICE_PEER_DISCONNECTED )
2008-07-23 18:01:59 -04:00
{
2008-11-13 18:03:46 -05:00
# ifdef CONTROL_DEBUG
std : : cerr < < " is Just disconnected! " ;
std : : cerr < < std : : endl ;
2009-05-26 17:42:45 -04:00
# endif
2010-03-06 18:29:47 -05:00
setPeerState ( it - > second - > mTransfer , pit - > id , rate , false ) ;
2009-05-26 17:42:45 -04:00
}
2014-03-28 23:57:44 -04:00
else // Added or Removed.
2009-05-26 17:42:45 -04:00
{
# ifdef CONTROL_DEBUG
std : : cerr < < " had something happen to it: " ;
std : : cerr < < pit - > actions ;
std : : cerr < < std : : endl ;
# endif
2010-03-06 18:29:47 -05:00
setPeerState ( it - > second - > mTransfer , pit - > id , rate , false ) ;
2009-05-26 17:42:45 -04:00
}
}
2009-06-11 17:41:42 -04:00
2016-11-22 17:19:34 -05:00
// Now also look at turtle virtual peers, for ongoing downloads only.
2009-05-26 17:42:45 -04:00
//
2016-11-22 17:19:34 -05:00
if ( it - > second - > mState ! = ftFileControl : : DOWNLOADING )
continue ;
2013-10-21 05:05:51 -04:00
std : : list < pqipeer > vlist ;
2014-03-28 23:57:44 -04:00
std : : list < pqipeer > : : const_iterator vit ;
2013-10-21 05:05:51 -04:00
mTurtle - > getSourceVirtualPeersList ( it - > first , vlist ) ;
2013-10-21 14:09:40 -04:00
# ifdef CONTROL_DEBUG
2013-10-21 05:05:51 -04:00
std : : cerr < < " vlist.size() = " < < vlist . size ( ) < < std : : endl ;
2013-10-21 14:09:40 -04:00
# endif
2013-10-21 05:05:51 -04:00
2014-10-24 18:07:26 -04:00
for ( vit = vlist . begin ( ) ; vit ! = vlist . end ( ) ; + + vit )
2009-05-26 17:42:45 -04:00
{
# ifdef CONTROL_DEBUG
2014-03-28 23:57:44 -04:00
std : : cerr < < " Peer: " < < vit - > id ;
2009-05-26 17:42:45 -04:00
# endif
2014-03-28 23:57:44 -04:00
if ( vit - > actions & RS_PEER_CONNECTED )
2009-05-26 17:42:45 -04:00
{
# ifdef CONTROL_DEBUG
std : : cerr < < " is Newly Connected! " ;
std : : cerr < < std : : endl ;
# endif
2014-03-28 23:57:44 -04:00
setPeerState ( it - > second - > mTransfer , vit - > id , rate , true ) ;
2009-05-26 17:42:45 -04:00
}
2014-03-28 23:57:44 -04:00
else if ( vit - > actions & RS_PEER_DISCONNECTED )
2009-05-26 17:42:45 -04:00
{
# ifdef CONTROL_DEBUG
std : : cerr < < " is Just disconnected! " ;
std : : cerr < < std : : endl ;
2008-11-13 18:03:46 -05:00
# endif
2014-03-28 23:57:44 -04:00
setPeerState ( it - > second - > mTransfer , vit - > id , rate , false ) ;
2008-07-23 18:01:59 -04:00
}
2008-11-13 18:03:46 -05:00
else
2008-07-23 18:01:59 -04:00
{
2008-11-13 18:03:46 -05:00
# ifdef CONTROL_DEBUG
std : : cerr < < " had something happen to it: " ;
2014-03-28 23:57:44 -04:00
std : : cerr < < vit - > actions ;
2008-11-13 18:03:46 -05:00
std : : cerr < < std : : endl ;
# endif
2014-03-28 23:57:44 -04:00
setPeerState ( it - > second - > mTransfer , vit - > id , rate , false ) ;
2008-07-23 18:01:59 -04:00
}
}
}
2008-08-09 13:03:24 -04:00
}
2008-07-23 18:01:59 -04:00
2011-01-23 09:55:57 -05:00
const std : : string active_downloads_size_ss ( " MAX_ACTIVE_DOWNLOADS " ) ;
2008-11-15 15:00:29 -05:00
const std : : string download_dir_ss ( " DOWN_DIR " ) ;
const std : : string partial_dir_ss ( " PART_DIR " ) ;
2017-05-08 16:00:51 -04:00
const std : : string max_uploads_per_friend_ss ( " MAX_UPLOADS_PER_FRIEND " ) ;
2010-03-21 17:07:12 -04:00
const std : : string default_chunk_strategy_ss ( " DEFAULT_CHUNK_STRATEGY " ) ;
2010-05-21 16:49:48 -04:00
const std : : string free_space_limit_ss ( " FREE_SPACE_LIMIT " ) ;
2016-10-30 06:36:00 -04:00
const std : : string default_encryption_policy_ss ( " DEFAULT_ENCRYPTION_POLICY " ) ;
2017-06-26 17:35:01 -04:00
const std : : string file_perm_direct_dl_ss ( " FILE_PERM_DIRECT_DL " ) ;
2008-11-15 15:00:29 -05:00
/* p3Config Interface */
RsSerialiser * ftController : : setupSerialiser ( )
{
RsSerialiser * rss = new RsSerialiser ( ) ;
/* add in the types we need! */
rss - > addSerialType ( new RsFileConfigSerialiser ( ) ) ;
rss - > addSerialType ( new RsGeneralConfigSerialiser ( ) ) ;
return rss ;
}
2010-12-18 14:35:07 -05:00
bool ftController : : saveList ( bool & cleanup , std : : list < RsItem * > & saveData )
2008-11-15 15:00:29 -05:00
{
2010-12-18 14:35:07 -05:00
2008-11-15 15:00:29 -05:00
/* it can delete them! */
cleanup = true ;
/* create a key/value set for most of the parameters */
std : : map < std : : string , std : : string > configMap ;
std : : map < std : : string , std : : string > : : iterator mit ;
2014-03-17 16:56:06 -04:00
std : : list < RsFileHash > : : iterator it ;
2008-11-15 15:00:29 -05:00
/* basic control parameters */
2012-04-17 20:00:59 -04:00
std : : string s ;
rs_sprintf ( s , " %lu " , getQueueSize ( ) ) ;
configMap [ active_downloads_size_ss ] = s ;
2008-11-15 15:00:29 -05:00
configMap [ download_dir_ss ] = getDownloadDirectory ( ) ;
configMap [ partial_dir_ss ] = getPartialsDirectory ( ) ;
2013-03-22 08:14:48 -04:00
switch ( mDefaultChunkStrategy )
{
case FileChunksInfo : : CHUNK_STRATEGY_STREAMING : configMap [ default_chunk_strategy_ss ] = " STREAMING " ;
break ;
case FileChunksInfo : : CHUNK_STRATEGY_RANDOM : configMap [ default_chunk_strategy_ss ] = " RANDOM " ;
break ;
default :
case FileChunksInfo : : CHUNK_STRATEGY_PROGRESSIVE : configMap [ default_chunk_strategy_ss ] = " PROGRESSIVE " ;
break ;
}
2008-11-15 15:00:29 -05:00
2017-05-08 16:00:51 -04:00
rs_sprintf ( s , " %lu " , _max_uploads_per_friend ) ;
configMap [ max_uploads_per_friend_ss ] = s ;
2016-10-30 06:36:00 -04:00
configMap [ default_encryption_policy_ss ] = ( mDefaultEncryptionPolicy = = RS_FILE_CTRL_ENCRYPTION_POLICY_PERMISSIVE ) ? " PERMISSIVE " : " STRICT " ;
2017-06-26 17:35:01 -04:00
switch ( mFilePermDirectDLPolicy ) {
case RS_FILE_PERM_DIRECT_DL_YES : configMap [ file_perm_direct_dl_ss ] = " YES " ;
break ;
case RS_FILE_PERM_DIRECT_DL_NO : configMap [ file_perm_direct_dl_ss ] = " NO " ;
break ;
default : configMap [ file_perm_direct_dl_ss ] = " PER_USER " ;
break ;
}
2012-04-17 20:00:59 -04:00
rs_sprintf ( s , " %lu " , RsDiscSpace : : freeSpaceLimit ( ) ) ;
configMap [ free_space_limit_ss ] = s ;
2010-05-21 16:49:48 -04:00
2008-11-15 15:00:29 -05:00
RsConfigKeyValueSet * rskv = new RsConfigKeyValueSet ( ) ;
/* Convert to TLV */
2014-10-24 18:07:26 -04:00
for ( mit = configMap . begin ( ) ; mit ! = configMap . end ( ) ; + + mit )
2008-11-15 15:00:29 -05:00
{
RsTlvKeyValue kv ;
kv . key = mit - > first ;
kv . value = mit - > second ;
rskv - > tlvkvs . pairs . push_back ( kv ) ;
}
/* Add KeyValue to saveList */
saveData . push_back ( rskv ) ;
/* get list of Downloads ....
* strip out Caches / ExtraList / Channels ? ? ? ?
* ( anything with a callback ? )
* - most systems will restart missing files .
*/
/* get Details of File Transfers */
2014-03-17 16:56:06 -04:00
std : : list < RsFileHash > hashs ;
2008-11-15 15:00:29 -05:00
FileDownloads ( hashs ) ;
2014-10-24 18:07:26 -04:00
for ( it = hashs . begin ( ) ; it ! = hashs . end ( ) ; + + it )
2008-11-15 15:00:29 -05:00
{
/* stack mutex released each loop */
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator fit = mDownloads . find ( * it ) ;
2008-11-15 15:00:29 -05:00
if ( fit = = mDownloads . end ( ) )
continue ;
2010-10-16 11:21:37 -04:00
/* ignore cache files. As this is small files, better download them again from scratch at restart.*/
2012-02-16 17:04:03 -05:00
// Node: We still save finished transfers. This keeps transfers that are
// in checking mode. Finished or checked transfers will restart and
// immediately terminate/recheck at next startup.
//
// if ((fit->second)->mCreator->finished())
// continue;
2008-11-15 15:00:29 -05:00
/* make RsFileTransfer item for save list */
RsFileTransfer * rft = new RsFileTransfer ( ) ;
/* what data is important? */
2010-03-06 18:29:47 -05:00
rft - > file . name = fit - > second - > mName ;
rft - > file . hash = fit - > second - > mHash ;
rft - > file . filesize = fit - > second - > mSize ;
2012-06-01 16:51:14 -04:00
RsDirUtil : : removeTopDir ( fit - > second - > mDestination , rft - > file . path ) ; /* remove fname */
2012-11-02 09:52:29 -04:00
rft - > flags = fit - > second - > mFlags . toUInt32 ( ) ;
2010-03-06 18:29:47 -05:00
rft - > state = fit - > second - > mState ;
2010-01-11 11:00:42 -05:00
2014-03-17 16:56:06 -04:00
std : : list < RsPeerId > lst ;
fit - > second - > mTransfer - > getFileSources ( lst ) ;
2010-02-13 15:42:49 -05:00
2010-01-11 11:00:42 -05:00
// Remove turtle peers from sources, as they are not supposed to survive a reboot of RS, since they are dynamic sources.
// Otherwize, such sources are unknown from the turtle router, at restart, and never get removed.
//
2014-03-17 16:56:06 -04:00
for ( std : : list < RsPeerId > : : const_iterator it ( lst . begin ( ) ) ; it ! = lst . end ( ) ; + + it )
if ( ! mTurtle - > isTurtlePeer ( * it ) )
2015-04-17 17:36:22 -04:00
rft - > allPeerIds . ids . insert ( * it ) ;
2010-01-11 11:00:42 -05:00
2014-03-17 16:56:06 -04:00
rft - > transferred = fit - > second - > mCreator - > getRecvd ( ) ;
2010-03-06 18:29:47 -05:00
fit - > second - > mCreator - > getAvailabilityMap ( rft - > compressed_chunk_map ) ;
rft - > chunk_strategy = fit - > second - > mCreator - > getChunkStrategy ( ) ;
2008-11-15 15:00:29 -05:00
saveData . push_back ( rft ) ;
}
2012-05-07 10:54:46 -04:00
{
/* Save pending list of downloads */
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
std : : list < ftPendingRequest > : : iterator pit ;
for ( pit = mPendingRequests . begin ( ) ; pit ! = mPendingRequests . end ( ) ; + + pit )
{
/* make RsFileTransfer item for save list */
RsFileTransfer * rft = NULL ;
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , RsFileTransfer * > : : iterator rit = mPendingChunkMaps . find ( pit - > mHash ) ;
2012-05-07 10:54:46 -04:00
if ( rit ! = mPendingChunkMaps . end ( ) ) {
/* use item from the not loaded pending list */
rft = new RsFileTransfer ( * ( rit - > second ) ) ;
} else {
rft = new RsFileTransfer ( ) ;
/* what data is important? */
rft - > file . name = pit - > mName ;
rft - > file . hash = pit - > mHash ;
rft - > file . filesize = pit - > mSize ;
2012-06-01 16:51:14 -04:00
RsDirUtil : : removeTopDir ( pit - > mDest , rft - > file . path ) ; /* remove fname */
2012-11-02 09:52:29 -04:00
rft - > flags = pit - > mFlags . toUInt32 ( ) ;
2013-10-06 08:56:37 -04:00
rft - > state = pit - > mState ;
2014-03-17 16:56:06 -04:00
rft - > allPeerIds . ids . clear ( ) ;
for ( std : : list < RsPeerId > : : const_iterator it ( pit - > mSrcIds . begin ( ) ) ; it ! = pit - > mSrcIds . end ( ) ; + + it )
2015-04-17 17:36:22 -04:00
rft - > allPeerIds . ids . insert ( * it ) ;
2012-05-07 10:54:46 -04:00
}
// Remove turtle peers from sources, as they are not supposed to survive a reboot of RS, since they are dynamic sources.
2014-03-17 16:56:06 -04:00
// Otherwize, such sources are unknown from the turtle router, at restart, and never get removed. We do that in post
// process since the rft object may have been created from mPendingChunkMaps
2012-05-07 10:54:46 -04:00
//
2015-04-17 17:36:22 -04:00
for ( std : : set < RsPeerId > : : iterator sit ( rft - > allPeerIds . ids . begin ( ) ) ; sit ! = rft - > allPeerIds . ids . end ( ) ; )
2014-03-17 16:56:06 -04:00
if ( mTurtle - > isTurtlePeer ( RsPeerId ( * sit ) ) )
{
2015-04-17 17:36:22 -04:00
std : : set < RsPeerId > : : iterator sittmp ( sit ) ;
2014-03-17 16:56:06 -04:00
+ + sittmp ;
rft - > allPeerIds . ids . erase ( sit ) ;
sit = sittmp ;
}
2012-05-07 10:54:46 -04:00
else
+ + sit ;
saveData . push_back ( rft ) ;
}
}
2008-11-15 15:00:29 -05:00
/* list completed! */
2010-12-18 14:35:07 -05:00
return true ;
2008-11-15 15:00:29 -05:00
}
2010-12-18 14:35:07 -05:00
bool ftController : : loadList ( std : : list < RsItem * > & load )
2008-11-15 15:00:29 -05:00
{
std : : list < RsItem * > : : iterator it ;
std : : list < RsTlvKeyValue > : : iterator kit ;
RsConfigKeyValueSet * rskv ;
RsFileTransfer * rsft ;
2009-06-11 17:41:42 -04:00
# ifdef CONTROL_DEBUG
2008-11-15 15:00:29 -05:00
std : : cerr < < " ftController::loadList() Item Count: " < < load . size ( ) ;
std : : cerr < < std : : endl ;
# endif
2014-10-24 18:07:26 -04:00
for ( it = load . begin ( ) ; it ! = load . end ( ) ; + + it )
2008-11-15 15:00:29 -05:00
{
/* switch on type */
if ( NULL ! = ( rskv = dynamic_cast < RsConfigKeyValueSet * > ( * it ) ) )
{
/* make into map */
std : : map < std : : string , std : : string > configMap ;
for ( kit = rskv - > tlvkvs . pairs . begin ( ) ;
2014-10-24 18:07:26 -04:00
kit ! = rskv - > tlvkvs . pairs . end ( ) ; + + kit )
2008-11-15 15:00:29 -05:00
{
configMap [ kit - > key ] = kit - > value ;
}
loadConfigMap ( configMap ) ;
}
else if ( NULL ! = ( rsft = dynamic_cast < RsFileTransfer * > ( * it ) ) )
{
2009-06-11 17:41:42 -04:00
/* This will get stored on a waiting list - until the
2008-11-20 19:10:59 -05:00
* config files are fully loaded
*/
2012-11-08 14:18:45 -05:00
// Compatibility with previous versions.
if ( rsft - > flags & RS_FILE_HINTS_NETWORK_WIDE . toUInt32 ( ) )
{
std : : cerr < < " Ensuring compatibility, replacing RS_FILE_HINTS_NETWORK_WIDE with RS_FILE_REQ_ANONYMOUS_ROUTING " < < std : : endl ;
rsft - > flags & = ~ RS_FILE_HINTS_NETWORK_WIDE . toUInt32 ( ) ;
rsft - > flags | = RS_FILE_REQ_ANONYMOUS_ROUTING . toUInt32 ( ) ;
}
2010-10-15 18:12:29 -04:00
# ifdef CONTROL_DEBUG
std : : cerr < < " ftController::loadList(): requesting " < < rsft - > file . name < < " , " < < rsft - > file . hash < < " , " < < rsft - > file . filesize < < std : : endl ;
# endif
2014-03-17 16:56:06 -04:00
std : : list < RsPeerId > src_lst ;
2015-04-17 17:36:22 -04:00
for ( std : : set < RsPeerId > : : const_iterator it ( rsft - > allPeerIds . ids . begin ( ) ) ; it ! = rsft - > allPeerIds . ids . end ( ) ; + + it )
2014-03-17 16:56:06 -04:00
src_lst . push_back ( * it ) ;
FileRequest ( rsft - > file . name , rsft - > file . hash , rsft - > file . filesize , rsft - > file . path , TransferRequestFlags ( rsft - > flags ) , src_lst , rsft - > state ) ;
2009-12-10 17:55:27 -05:00
{
RsStackMutex mtx ( ctrlMutex ) ;
2014-03-17 16:56:06 -04:00
std : : map < RsFileHash , ftFileControl * > : : iterator fit = mDownloads . find ( rsft - > file . hash ) ;
2008-11-20 19:10:59 -05:00
2010-03-06 18:29:47 -05:00
if ( ( fit = = mDownloads . end ( ) | | ( fit - > second ) - > mCreator = = NULL ) )
2009-12-10 17:55:27 -05:00
{
std : : cerr < < " ftController::loadList(): Error: could not find hash " < < rsft - > file . hash < < " in mDownloads list ! " < < std : : endl ;
std : : cerr < < " Storing the map in a wait list. " < < std : : endl ;
mPendingChunkMaps [ rsft - > file . hash ] = rsft ;
2012-11-08 14:18:45 -05:00
2009-12-10 17:55:27 -05:00
continue ; // i.e. don't delete the item!
}
else
2010-01-11 11:00:42 -05:00
{
2010-03-06 18:29:47 -05:00
( fit - > second ) - > mCreator - > setAvailabilityMap ( rsft - > compressed_chunk_map ) ;
( fit - > second ) - > mCreator - > setChunkStrategy ( ( FileChunksInfo : : ChunkStrategy ) ( rsft - > chunk_strategy ) ) ;
2010-01-11 11:00:42 -05:00
}
2009-12-10 17:55:27 -05:00
}
2008-11-15 15:00:29 -05:00
}
2008-11-20 19:10:59 -05:00
/* cleanup */
delete ( * it ) ;
2008-11-15 15:00:29 -05:00
}
2015-12-30 18:20:09 -05:00
load . clear ( ) ;
2008-11-15 15:00:29 -05:00
return true ;
}
bool ftController : : loadConfigMap ( std : : map < std : : string , std : : string > & configMap )
{
std : : map < std : : string , std : : string > : : iterator mit ;
2017-06-26 17:35:01 -04:00
//std::string str_true("true");
//std::string empty("");
//std::string dir = "notempty";
2008-11-15 15:00:29 -05:00
if ( configMap . end ( ) ! = ( mit = configMap . find ( download_dir_ss ) ) )
setDownloadDirectory ( mit - > second ) ;
2011-01-23 09:55:57 -05:00
if ( configMap . end ( ) ! = ( mit = configMap . find ( active_downloads_size_ss ) ) )
{
int n = 5 ;
2012-05-03 09:41:03 -04:00
sscanf ( mit - > second . c_str ( ) , " %d " , & n ) ;
2011-01-23 09:55:57 -05:00
std : : cerr < < " Note: loading active max downloads: " < < n < < std : : endl ;
setQueueSize ( n ) ;
2008-11-15 15:00:29 -05:00
}
if ( configMap . end ( ) ! = ( mit = configMap . find ( partial_dir_ss ) ) )
{
2009-06-11 17:41:42 -04:00
setPartialsDirectory ( mit - > second ) ;
2008-11-15 15:00:29 -05:00
}
2016-10-30 06:36:00 -04:00
if ( configMap . end ( ) ! = ( mit = configMap . find ( default_encryption_policy_ss ) ) )
2016-10-29 11:59:03 -04:00
{
if ( mit - > second = = " STRICT " )
{
mDefaultEncryptionPolicy = RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT ;
std : : cerr < < " Note: loading default value for encryption policy: STRICT " < < std : : endl ;
}
else if ( mit - > second = = " PERMISSIVE " )
{
mDefaultEncryptionPolicy = RS_FILE_CTRL_ENCRYPTION_POLICY_PERMISSIVE ;
std : : cerr < < " Note: loading default value for encryption policy: PERMISSIVE " < < std : : endl ;
}
else
{
std : : cerr < < " (EE) encryption policy not recognized: \" " < < mit - > second < < " \" " < < std : : endl ;
mDefaultEncryptionPolicy = RS_FILE_CTRL_ENCRYPTION_POLICY_PERMISSIVE ;
}
}
if ( configMap . end ( ) ! = ( mit = configMap . find ( default_chunk_strategy_ss ) ) )
2010-03-21 17:07:12 -04:00
{
if ( mit - > second = = " STREAMING " )
2010-04-30 17:07:21 -04:00
{
2010-03-21 17:07:12 -04:00
setDefaultChunkStrategy ( FileChunksInfo : : CHUNK_STRATEGY_STREAMING ) ;
2010-04-30 17:07:21 -04:00
std : : cerr < < " Note: loading default value for chunk strategy: streaming " < < std : : endl ;
}
2010-03-21 17:07:12 -04:00
else if ( mit - > second = = " RANDOM " )
2010-04-30 17:07:21 -04:00
{
2010-03-21 17:07:12 -04:00
setDefaultChunkStrategy ( FileChunksInfo : : CHUNK_STRATEGY_RANDOM ) ;
2010-04-30 17:07:21 -04:00
std : : cerr < < " Note: loading default value for chunk strategy: random " < < std : : endl ;
}
2013-02-28 15:42:01 -05:00
else if ( mit - > second = = " PROGRESSIVE " )
{
setDefaultChunkStrategy ( FileChunksInfo : : CHUNK_STRATEGY_PROGRESSIVE ) ;
std : : cerr < < " Note: loading default value for chunk strategy: progressive " < < std : : endl ;
}
2010-04-30 17:07:21 -04:00
else
std : : cerr < < " **** ERROR ***: Unknown value for default chunk strategy in keymap. " < < std : : endl ;
2010-03-21 17:07:12 -04:00
}
2010-05-21 16:49:48 -04:00
if ( configMap . end ( ) ! = ( mit = configMap . find ( free_space_limit_ss ) ) )
{
uint32_t size ;
2012-05-03 09:41:03 -04:00
if ( sscanf ( mit - > second . c_str ( ) , " %u " , & size ) = = 1 ) {
std : : cerr < < " have read a size limit of " < < size < < " MB " < < std : : endl ;
2010-05-21 16:49:48 -04:00
2012-05-03 09:41:03 -04:00
RsDiscSpace : : setFreeSpaceLimit ( size ) ;
}
2010-05-21 16:49:48 -04:00
}
2017-05-08 16:00:51 -04:00
if ( configMap . end ( ) ! = ( mit = configMap . find ( max_uploads_per_friend_ss ) ) )
{
uint32_t n ;
if ( sscanf ( mit - > second . c_str ( ) , " %u " , & n ) = = 1 ) {
std : : cerr < < " have read a max upload slots limit of " < < n < < std : : endl ;
_max_uploads_per_friend = n ;
}
}
2017-06-26 17:35:01 -04:00
if ( configMap . end ( ) ! = ( mit = configMap . find ( file_perm_direct_dl_ss ) ) )
{
if ( mit - > second = = " YES " )
{
mFilePermDirectDLPolicy = RS_FILE_PERM_DIRECT_DL_YES ;
std : : cerr < < " Note: loading default value for file permission direct download: YES " < < std : : endl ;
}
else if ( mit - > second = = " NO " )
{
mFilePermDirectDLPolicy = RS_FILE_PERM_DIRECT_DL_NO ;
std : : cerr < < " Note: loading default value for file permission direct download: NO " < < std : : endl ;
}
else if ( mit - > second = = " PER_USER " )
{
mFilePermDirectDLPolicy = RS_FILE_PERM_DIRECT_DL_PER_USER ;
std : : cerr < < " Note: loading default value for file permission direct download: PER_USER " < < std : : endl ;
}
}
2008-11-15 15:00:29 -05:00
return true ;
}
2017-05-08 16:00:51 -04:00
void ftController : : setMaxUploadsPerFriend ( uint32_t m )
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
_max_uploads_per_friend = m ;
IndicateConfigChanged ( ) ;
}
uint32_t ftController : : getMaxUploadsPerFriend ( )
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
return _max_uploads_per_friend ;
}
2016-10-29 12:18:02 -04:00
void ftController : : setDefaultEncryptionPolicy ( uint32_t p )
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
mDefaultEncryptionPolicy = p ;
IndicateConfigChanged ( ) ;
}
uint32_t ftController : : defaultEncryptionPolicy ( )
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
return mDefaultEncryptionPolicy ;
}
2017-06-26 17:35:01 -04:00
void ftController : : setFilePermDirectDL ( uint32_t perm )
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
if ( mFilePermDirectDLPolicy ! = perm )
{
mFilePermDirectDLPolicy = perm ;
IndicateConfigChanged ( ) ;
}
}
uint32_t ftController : : filePermDirectDL ( )
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
return mFilePermDirectDLPolicy ;
}
2016-10-29 12:18:02 -04:00
void ftController : : setFreeDiskSpaceLimit ( uint32_t size_in_mb )
2010-05-21 16:49:48 -04:00
{
RsDiscSpace : : setFreeSpaceLimit ( size_in_mb ) ;
IndicateConfigChanged ( ) ;
}
uint32_t ftController : : freeDiskSpaceLimit ( ) const
{
return RsDiscSpace : : freeSpaceLimit ( ) ;
}
2010-03-21 17:07:12 -04:00
FileChunksInfo : : ChunkStrategy ftController : : defaultChunkStrategy ( )
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
return mDefaultChunkStrategy ;
}
void ftController : : setDefaultChunkStrategy ( FileChunksInfo : : ChunkStrategy S )
{
RsStackMutex stack ( ctrlMutex ) ; /******* LOCKED ********/
2010-04-30 17:07:21 -04:00
# ifdef CONTROL_DEBUG
std : : cerr < < " Note: in frController: setting chunk strategy to " < < S < < std : : endl ;
# endif
2010-03-21 17:07:12 -04:00
mDefaultChunkStrategy = S ;
IndicateConfigChanged ( ) ;
}