📄 downloadmanagercontroller.java
字号:
}
DiskManager old_dm = getDiskManager();
if ( old_dm != null ){
Debug.out( "DownloadManagerController::initializeDiskManager: disk manager is not null" );
// we shouldn't get here but try to recover the situation
old_dm.stop( false );
setDiskManager( null, null );
}
errorDetail = "";
setState( initialising_state, false );
DiskManager dm = DiskManagerFactory.create( download_manager.getTorrent(), download_manager);
setDiskManager( dm, listener );
}finally{
this_mon.exit();
download_manager.informStateChanged();
}
}
public boolean
canForceRecheck()
{
int state = getState();
// gotta check error + disk manager state as error can be generated by both
// an overall error or a running disk manager in faulty state
return( (state == DownloadManager.STATE_STOPPED ) ||
(state == DownloadManager.STATE_QUEUED ) ||
(state == DownloadManager.STATE_ERROR && getDiskManager() == null));
}
public void
forceRecheck()
{
try{
this_mon.enter();
if ( getDiskManager() != null || !canForceRecheck() ){
Debug.out( "DownloadManagerController::forceRecheck: illegal entry state" );
return;
}
final int start_state = DownloadManagerController.this.getState();
// remove resume data
download_manager.getDownloadState().clearResumeData();
// For extra protection from a plugin stopping a checking torrent,
// fake a forced start.
final boolean wasForceStarted = force_start;
force_start = true;
// if a file has been deleted we want this recheck to recreate the file and mark
// it as 0%, not fail the recheck. Otherwise the only way of recovering is to remove and
// re-add the torrent
download_manager.setDataAlreadyAllocated( false );
initializeDiskManagerSupport(
DownloadManager.STATE_CHECKING,
new DiskManagerListener()
{
public void
stateChanged(
int oldDMState,
int newDMState )
{
try{
this_mon.enter();
if ( getDiskManager() == null ){
// already closed down via stop
download_manager.setAssumedComplete(false);
return;
}
}finally{
this_mon.exit();
}
if ( newDMState == DiskManager.CHECKING ){
makeSureFilesFacadeFilled(true);
}
if ( newDMState == DiskManager.READY || newDMState == DiskManager.FAULTY ){
force_start = wasForceStarted;
stats.setDownloadCompleted(stats.getDownloadCompleted(true));
if ( newDMState == DiskManager.READY ){
try{
boolean only_seeding = false;
boolean update_only_seeding = false;
try{
this_mon.enter();
DiskManager dm = getDiskManager();
if ( dm != null ){
dm.stop( false );
only_seeding = dm.getRemainingExcludingDND() == 0;
update_only_seeding = true;
setDiskManager( null, null );
if ( start_state == DownloadManager.STATE_ERROR ){
setState( DownloadManager.STATE_STOPPED, false );
}else{
setState( start_state, false );
}
}
}finally{
this_mon.exit();
download_manager.informStateChanged();
}
// careful here, don't want to update seeding while holding monitor
// as potential deadlock
if ( update_only_seeding ){
download_manager.setAssumedComplete( only_seeding );
}
}catch( Exception e ){
setFailed( "Resume data save fails: " + Debug.getNestedExceptionMessage(e));
}
}else{ // Faulty
try{
this_mon.enter();
DiskManager dm = getDiskManager();
if ( dm != null ){
dm.stop( false );
setDiskManager( null, null );
setFailed( dm.getErrorMessage());
}
}finally{
this_mon.exit();
}
download_manager.setAssumedComplete(false);
}
}
}
public void
filePriorityChanged(
DiskManagerFileInfo file )
{
download_manager.informPriorityChange( file );
}
public void
pieceDoneChanged(
DiskManagerPiece piece )
{
}
public void
fileAccessModeChanged(
DiskManagerFileInfo file,
int old_mode,
int new_mode )
{
}
});
}finally{
this_mon.exit();
}
}
public void
stopIt(
int _stateAfterStopping,
final boolean remove_torrent,
final boolean remove_data )
{
long current_up = stats.getDataSendRate();
if ( current_up != 0 ){
data_send_rate_at_close = current_up;
}
boolean closing = _stateAfterStopping == DownloadManager.STATE_CLOSED;
if ( closing ){
_stateAfterStopping = DownloadManager.STATE_STOPPED;
}
final int stateAfterStopping = _stateAfterStopping;
try{
this_mon.enter();
int state = getState();
if ( state == DownloadManager.STATE_STOPPED ||
( state == DownloadManager.STATE_ERROR && getDiskManager() == null )) {
//already in stopped state, just do removals if necessary
if( remove_data ){
download_manager.deleteDataFiles();
}
if( remove_torrent ){
download_manager.deleteTorrentFile();
}
setState( _stateAfterStopping, false );
return;
}
if ( state == DownloadManager.STATE_STOPPING){
return;
}
setSubState( _stateAfterStopping );
setState( DownloadManager.STATE_STOPPING, false );
// this will run synchronously but on a non-daemon thread so that it will under
// normal circumstances complete, even if we're closing
final AESemaphore nd_sem = new AESemaphore( "DM:DownloadManager.NDTR" );
NonDaemonTaskRunner.runAsync(
new NonDaemonTask()
{
public Object
run()
{
nd_sem.reserve();
return( null );
}
});
try{
try{
if ( peer_manager != null ){
peer_manager.stopAll();
stats.saveSessionTotals();
}
// do this even if null as it also triggers tracker actions
download_manager.informStopped( peer_manager, stateAfterStopping==DownloadManager.STATE_QUEUED );
peer_manager = null;
DiskManager dm = getDiskManager();
if ( dm != null ){
dm.stop( closing );
stats.setCompleted(stats.getCompleted());
stats.setDownloadCompleted(stats.getDownloadCompleted(true));
// we don't want to update the torrent if we're seeding
if ( !download_manager.getAssumedComplete()){
download_manager.getDownloadState().save();
}
setDiskManager( null, null );
}
}finally{
force_start = false;
if( remove_data ){
download_manager.deleteDataFiles();
}
if( remove_torrent ){
download_manager.deleteTorrentFile();
}
// only update the state if things haven't gone wrong
if ( getState() == DownloadManager.STATE_STOPPING ){
setState( stateAfterStopping, true );
}
}
}finally{
nd_sem.release();
}
}catch( Throwable e ){
Debug.printStackTrace( e );
}finally{
this_mon.exit();
download_manager.informStateChanged();
}
}
protected void
setStateWaiting()
{
setState(DownloadManager.STATE_WAITING, true );
}
public void
setStateFinishing()
{
setState(DownloadManager.STATE_FINISHING, true);
}
public void
setStateDownloading()
{
if (getState() == DownloadManager.STATE_SEEDING) {
setState(DownloadManager.STATE_DOWNLOADING, true);
} else if (getState() != DownloadManager.STATE_DOWNLOADING) {
Logger.log(new LogEvent(this, LogIDs.CORE, LogEvent.LT_WARNING,
"Trying to set state to downloading when state is not seeding"));
}
}
public void
setStateSeeding(
boolean never_downloaded )
{
setState(DownloadManager.STATE_SEEDING, true);
download_manager.downloadEnded( never_downloaded );
}
public boolean
isStateSeeding()
{
return( getState() == DownloadManager.STATE_SEEDING );
}
protected void
setStateQueued()
{
setState(DownloadManager.STATE_QUEUED, true);
}
public int
getState()
{
if ( state_set_by_method != DownloadManager.STATE_INITIALIZED ){
return( state_set_by_method );
}
// we don't want to synchronize here as there are potential deadlock problems
// regarding the DownloadManager::addListener call invoking this method while
// holding the listeners monitor.
//
DiskManager dm = getDiskManager();
if ( dm == null){
return DownloadManager.STATE_INITIALIZED;
}
int diskManagerState = dm.getState();
if (diskManagerState == DiskManager.INITIALIZING){
return DownloadManager.STATE_INITIALIZED;
}else if (diskManagerState == DiskManager.ALLOCATING){
return DownloadManager.STATE_ALLOCATING;
}else if (diskManagerState == DiskManager.CHECKING){
return DownloadManager.STATE_CHECKING;
}else if (diskManagerState == DiskManager.READY){
return DownloadManager.STATE_READY;
}else if (diskManagerState == DiskManager.FAULTY){
return DownloadManager.STATE_ERROR;
}
return DownloadManager.STATE_ERROR;
}
protected int
getSubState()
{
if ( state_set_by_method == DownloadManager.STATE_STOPPING ){
return( substate );
}else{
return( getState());
}
}
private void
setSubState(
int ss )
{
substate = ss;
}
private void
setState(
int _state,
boolean _inform_changed )
{
// we bring this call out of the monitor block to prevent a potential deadlock whereby we chain
// state_mon -> this_mon (there exist numerous dependencies this_mon -> state_mon...
boolean call_filesExist = false;
try{
state_mon.enter();
int old_state = state_set_by_method;
// note: there is a DIFFERENCE between the state held on the DownloadManager and
// that reported via getState as getState incorporated DiskManager states when
// the DownloadManager is INITIALIZED
//System.out.println( "DM:setState - " + _state );
if ( old_state != _state ){
state_set_by_method = _state;
if ( state_set_by_method != DownloadManager.STATE_QUEUED ){
// only maintain this while queued
activation_bloom = null;
if ( state_set_by_method == DownloadManager.STATE_STOPPED ){
activation_count = 0;
}
}
if (state_set_by_method == DownloadManager.STATE_QUEUED ){
// don't pick up errors regarding missing data while queued.
// We'll do that when the torrent starts. Saves time at startup
// pick up any errors regarding missing data for queued SEEDING torrents
// if ( download_manager.getAssumedComplete()){
//
// call_filesExist = true;
// }
}else if ( state_set_by_method == DownloadManager.STATE_ERROR ){
// the process of attempting to start the torrent may have left some empty
// directories created, some users take exception to this.
// the most straight forward way of remedying this is to delete such empty
// folders here
TOTorrent torrent = download_manager.getTorrent();
if ( torrent != null && !torrent.isSimpleTorrent()){
File save_dir_file = download_manager.getAbsoluteSaveLocation();
if ( save_dir_file != null && save_dir_file.exists() && save_dir_file.isDirectory()){
TorrentUtils.recursiveEmptyDirDelete( save_dir_file, false );
}
}
}
}
}finally{
state_mon.exit();
}
if ( call_filesExist ){
filesExist();
}
if ( _inform_changed ){
download_manager.informStateChanged();
}
}
/**
* Stops the current download, then restarts it again.
*/
public void
restartDownload()
{
boolean was_force_start = isForceStart();
stopIt( DownloadManager.STATE_STOPPED, false, false );
download_manager.initialize();
if ( was_force_start ){
setForceStart(true);
}
}
protected void
destroy()
{
if ( peer_manager_registration != null ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -