📄 scheduler.cpp
字号:
/* This file is part of the KDE project Copyright (C) 2000-2001 Simon Hausmann <hausmann@kde.org> Copyright (C) 2001 Dirk Mueller <mueller@kde.org> Copyright (C) 2005 Fastweb SpA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/#include "scheduler.h"#include "jobclasses.h"#include "slavebase.h"#include "slave.h"#include "launcher.h"#include "kprotocolmanager.h"#include <dcopclient.h>#include <dcopobject.h>#include <kdebug.h>#include <stdlib.h>#include <assert.h>#include <unistd.h>#include <sys/time.h>#include <sys/resource.h>using namespace KIO;Scheduler::ProtocolInfo::ProtocolInfo(){ for (int i = 0; i < SAM_MAX_TASKS; i++) { m_slaves[i] = 0; m_slavehost[i] = "<unknown>"; m_running[i] = false; } m_running_cnt = 0;}Scheduler::ProtocolInfo::~ProtocolInfo(){}Scheduler::JobInfo::JobInfo(SimpleJob* job) : m_job( job ), m_scheduled( false ){}Scheduler *Scheduler::s_self = 0;Scheduler::Scheduler(){ connect( &m_timer, SIGNAL( timeout() ), this, SLOT( slotStep() ) );}Scheduler::~Scheduler(){}bool Scheduler::doJob( SimpleJob *job ){ KURL url = job->url(); if ( !SlaveBase::knownProtocol( url.protocol() ) ) { return false; } ProtocolInfo *nfo = m_schedule[ url.protocol() ]; if ( !nfo ) { nfo = new ProtocolInfo; m_schedule.insert( url.protocol(), nfo ); } // Job already in list? for (QPtrListIterator <JobInfo>job_it(nfo->m_jobs); job_it.current(); ++job_it) { if ( job_it.current()->m_job == job ) { return false; } } JobInfo* ji = new JobInfo( job ); nfo->m_jobs.append( ji ); m_timer.start( 0, true ); return true;}void Scheduler::releaseJob( SimpleJob *job, bool _killSlave ){ kdDebug() << k_funcinfo << "called, job: " << job << endl; // the job's url might have changed or something, so let's iterate // over all entries QDictIterator<ProtocolInfo> it( m_schedule ); for (; it.current(); ++it ) { JobInfo* ji = it.current()->m_jobs.first(); while ( ji ) { if (ji->m_job == job) { int task = job->taskNumber(); if (task == -1) { qDebug( "sam: shouldn't have happend" ); } else { it.current()->m_running[task] = false; it.current()->m_running_cnt--; } delete it.current()->m_jobs.take(); ji = it.current()->m_jobs.current(); if ( _killSlave ) killSlave( it.current(), task ); } else ji = it.current()->m_jobs.next(); } } job->setTaskNumber( -1 ); m_timer.start( 0, true );}void Scheduler::scheduleJob( SimpleJob* job ){ Scheduler::self()->_scheduleJob( job );}void Scheduler::_scheduleJob(SimpleJob *job){ QDictIterator<ProtocolInfo> it( m_schedule ); for (; it.current(); ++it ) { for (QPtrListIterator <JobInfo>job_it(it.current()->m_jobs); job_it.current(); ++job_it) { if (job_it.current()->m_job == job) { job_it.current()->m_scheduled = true; break; } } } m_timer.start(0, true);}void Scheduler::slotStep(){ QDictIterator<ProtocolInfo> it( m_schedule ); for (; it.current(); ++it ) doStep( it.current() ); it.toFirst(); while ( it.current() ) { if ( it.current()->m_jobs.count() == 0 && !it.current()->m_running_cnt ) delete m_schedule.take( it.currentKey() ); else ++it; }}//#define SAM_DEBUG#ifdef SAM_DEBUGvoid Scheduler::debugInfo( ProtocolInfo* nfo ){ qDebug( "joblist: " ); int i =1; for (QPtrListIterator <JobInfo>job_it(nfo->m_jobs); job_it.current(); ++job_it, ++i) { qDebug( "job %d, Sched: %d, taskNumber: %d, url: %s", i, job_it.current()->m_scheduled, job_it.current()->m_job->taskNumber(), job_it.current()->m_job->url().url().latin1() ); } qDebug( "running count: %d", nfo->m_running_cnt ); qDebug( "slaves: " ); for ( int k = 0; k < SAM_MAX_TASKS; k++ ) { qDebug( "%3d: slave: %p, running: %d, slavehost: %s", k, nfo->m_slaves[k], nfo->m_running[k], nfo->m_slavehost[k].data()); } qDebug( "\n\n" );}#endifvoid Scheduler::doStep( ProtocolInfo *nfo ){#ifdef SAM_DEBUG debugInfo(nfo);#endif if (nfo->m_running_cnt >= SAM_MAX_TASKS) { return; } if ( nfo->m_jobs.count() == 0 ) { //work done. killSlave( nfo ); return; } int task = -1; for (int i = 0; i < SAM_MAX_TASKS; i++) { if ( !nfo->m_running[i] && nfo->m_slaves[i] ) { for (QPtrListIterator <JobInfo> it(nfo->m_jobs); it.current(); ++it) { SimpleJob *job = it.current()->m_job; if (job->taskNumber() != -1) continue; if ( (job->url().host()!= nfo->m_slavehost[i].data() ) && it.current()->m_scheduled ) { startJobSlaveTask(nfo, job, i ); break; } } } } for (QPtrListIterator <JobInfo>it(nfo->m_jobs); it.current(); ++it) { SimpleJob *job = it.current()->m_job; if (job->taskNumber() != -1) continue; QCString jobHost = job->url().host().latin1(); int jobHostCount = 0; task = -1; for (int i = 0; i < SAM_MAX_TASKS; i++) { if (nfo->m_slaves[i] && nfo->m_slavehost[i] == jobHost ) ++jobHostCount; if (!nfo->m_slaves[i] || !nfo->m_running[i]) { task = i; break; } } if (task == -1) break; if ( jobHostCount > 2 ) continue; if ( !nfo->m_slaves[task] ) { kdDebug() << "creating slave for " << job->url().prettyURL() << endl; nfo->m_slaves[task] = Launcher::self()->createSlave( job->url().protocol() ); nfo->m_slavehost[task] = job->url().host().latin1(); } startJobSlaveTask( nfo, job, task ); }}void Scheduler::startJobSlaveTask(ProtocolInfo* nfo, SimpleJob* job, int task ){ nfo->m_running_cnt++; nfo->m_running[task] = true; nfo->m_slavehost[task] = job->url().host().latin1(); job->setTaskNumber(task); Slave *slave = nfo->m_slaves[task]; MetaData configData = KProtocolManager::protocolConfig( job->url().protocol() ); slave->setConfig( configData ); job->start( slave );}void Scheduler::killSlave( ProtocolInfo *nfo, int task ){ for (int i = 0; i < SAM_MAX_TASKS; i++) { if ( nfo->m_slaves[i] && ( i == task || task == -1 ) ) { kdDebug() << "sam: killing " << i << endl; nfo->m_slaves[i]->kill(); delete nfo->m_slaves[i]; nfo->m_slaves[i] = 0; nfo->m_running[i] = false; nfo->m_slavehost[i] = "<unknown>"; } } nfo->m_running_cnt = 0;}Scheduler *Scheduler::self(){ if ( !s_self ) s_self = new Scheduler; return s_self;}#include "scheduler.moc"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -