📄 dmcheckerimpl.java
字号:
/*
* Created on 31-Jul-2004
* Created by Paul Gardner
* Copyright (C) 2004, 2005, 2006 Aelitis, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/
package org.gudy.azureus2.core3.disk.impl.access.impl;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.config.ParameterListener;
import org.gudy.azureus2.core3.disk.*;
import org.gudy.azureus2.core3.disk.impl.DiskManagerFileInfoImpl;
import org.gudy.azureus2.core3.disk.impl.DiskManagerHelper;
import org.gudy.azureus2.core3.disk.impl.DiskManagerRecheckInstance;
import org.gudy.azureus2.core3.disk.impl.access.DMChecker;
import org.gudy.azureus2.core3.disk.impl.piecemapper.DMPieceList;
import org.gudy.azureus2.core3.disk.impl.piecemapper.DMPieceMapEntry;
import org.gudy.azureus2.core3.logging.*;
import org.gudy.azureus2.core3.util.*;
import com.aelitis.azureus.core.diskmanager.cache.CacheFile;
/**
* @author parg
*
*/
public class
DMCheckerImpl
implements DMChecker
{
protected static final LogIDs LOGID = LogIDs.DISK;
private static boolean flush_pieces;
private static boolean checking_read_priority;
static{
ParameterListener param_listener = new ParameterListener() {
public void
parameterChanged(
String str )
{
flush_pieces = COConfigurationManager.getBooleanParameter( "diskmanager.perf.cache.flushpieces" );
checking_read_priority = COConfigurationManager.getBooleanParameter( "diskmanager.perf.checking.read.priority" );
}
};
COConfigurationManager.addAndFireParameterListeners(
new String[]{
"diskmanager.perf.cache.flushpieces",
"diskmanager.perf.checking.read.priority" },
param_listener );
}
protected DiskManagerHelper disk_manager;
protected int async_checks;
protected AESemaphore async_check_sem = new AESemaphore("DMChecker::asyncCheck");
protected int async_reads;
protected AESemaphore async_read_sem = new AESemaphore("DMChecker::asyncRead");
private boolean started;
protected volatile boolean stopped;
private int pieceLength;
private int lastPieceLength;
protected int nbPieces;
private volatile boolean complete_recheck_in_progress;
private volatile int complete_recheck_progress;
protected AEMonitor this_mon = new AEMonitor( "DMChecker" );
public
DMCheckerImpl(
DiskManagerHelper _disk_manager )
{
disk_manager = _disk_manager;
pieceLength = disk_manager.getPieceLength();
lastPieceLength = disk_manager.getLastPieceLength();
nbPieces = disk_manager.getNbPieces();
}
public void
start()
{
try{
this_mon.enter();
if ( started ){
throw( new RuntimeException( "DMChecker: start while started"));
}
if ( stopped ){
throw( new RuntimeException( "DMChecker: start after stopped"));
}
started = true;
}finally{
this_mon.exit();
}
}
public void
stop()
{
int check_wait;
int read_wait;
try{
this_mon.enter();
if ( stopped || !started ){
return;
}
// when we exit here we guarantee that all file usage operations have completed
// i.e. writes and checks (checks being doubly async)
stopped = true;
read_wait = async_reads;
check_wait = async_checks;
}finally{
this_mon.exit();
}
long log_time = SystemTime.getCurrentTime();
// wait for reads
for (int i=0;i<read_wait;i++){
long now = SystemTime.getCurrentTime();
if ( now < log_time ){
log_time = now;
}else{
if ( now - log_time > 1000 ){
log_time = now;
if ( Logger.isEnabled()){
Logger.log(new LogEvent(disk_manager, LOGID, "Waiting for check-reads to complete - " + (read_wait-i) + " remaining" ));
}
}
}
async_read_sem.reserve();
}
log_time = SystemTime.getCurrentTime();
// wait for checks
for (int i=0;i<check_wait;i++){
long now = SystemTime.getCurrentTime();
if ( now < log_time ){
log_time = now;
}else{
if ( now - log_time > 1000 ){
log_time = now;
if ( Logger.isEnabled()){
Logger.log(new LogEvent(disk_manager, LOGID, "Waiting for checks to complete - " + (read_wait-i) + " remaining" ));
}
}
}
async_check_sem.reserve();
}
}
public int
getCompleteRecheckStatus()
{
if (complete_recheck_in_progress ){
return( complete_recheck_progress );
}else{
return( -1 );
}
}
public DiskManagerCheckRequest
createRequest(
int pieceNumber,
Object user_data )
{
return( new DiskManagerCheckRequestImpl( pieceNumber, user_data ));
}
public void
enqueueCompleteRecheckRequest(
final DiskManagerCheckRequest request,
final DiskManagerCheckRequestListener listener )
{
complete_recheck_progress = 0;
complete_recheck_in_progress = true;
Thread t = new AEThread("DMChecker::completeRecheck")
{
public void
runSupport()
{
DiskManagerRecheckInstance recheck_inst = disk_manager.getRecheckScheduler().register( disk_manager, true );
try{
final AESemaphore sem = new AESemaphore( "DMChecker::completeRecheck" );
int checks_submitted = 0;
final AESemaphore run_sem = new AESemaphore( "DMChecker::completeRecheck:runsem", 2 );
for ( int i=0; i < nbPieces; i++ ){
complete_recheck_progress = 1000*i / nbPieces;
DiskManagerPiece dm_piece = disk_manager.getPiece(i);
// only recheck the piece if it happens to be done (a complete dnd file that's
// been set back to dnd for example) or the piece is part of a non-dnd file
if ( dm_piece.isDone() || !dm_piece.isSkipped()){
run_sem.reserve();
while( !stopped ){
if ( recheck_inst.getPermission()){
break;
}
}
if ( stopped ){
break;
}
enqueueCheckRequest(
createRequest( i, request.getUserData()),
new DiskManagerCheckRequestListener()
{
public void
checkCompleted(
DiskManagerCheckRequest request,
boolean passed )
{
try{
listener.checkCompleted( request, passed );
}catch( Throwable e ){
Debug.printStackTrace(e);
}finally{
complete();
}
}
public void
checkCancelled(
DiskManagerCheckRequest request )
{
try{
listener.checkCancelled( request );
}catch( Throwable e ){
Debug.printStackTrace(e);
}finally{
complete();
}
}
public void
checkFailed(
DiskManagerCheckRequest request,
Throwable cause )
{
try{
listener.checkFailed( request, cause );
}catch( Throwable e ){
Debug.printStackTrace(e);
}finally{
complete();
} }
protected void
complete()
{
run_sem.release();
sem.release();
}
},
false );
checks_submitted++;
}
}
// wait for all to complete
for (int i=0;i<checks_submitted;i++){
sem.reserve();
}
}finally{
complete_recheck_in_progress = false;
recheck_inst.unregister();
}
}
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -