00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "kio/sessiondata.h"
00021
#include "kio/slaveconfig.h"
00022
#include "kio/scheduler.h"
00023
#include "kio/authinfo.h"
00024
#include "kio/slave.h"
00025
#include <qptrlist.h>
00026
#include <qdict.h>
00027
00028
#include <dcopclient.h>
00029
00030
#include <kdebug.h>
00031
#include <kglobal.h>
00032
#include <kprotocolmanager.h>
00033
#include <kprotocolinfo.h>
00034
#include <assert.h>
00035
#include <kstaticdeleter.h>
00036
#include <kdesu/client.h>
00037
00038
00039
00040
00041
#define MAX_SLAVE_IDLE (3*60)
00042
00043
using namespace KIO;
00044
00045
template class QDict<KIO::Scheduler::ProtocolInfo>;
00046
00047
Scheduler *Scheduler::instance = 0;
00048
00049
class KIO::SlaveList:
public QPtrList<Slave>
00050 {
00051
public:
00052 SlaveList() { }
00053 };
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
class KIO::Scheduler::JobData
00071 {
00072
public:
00073 JobData() : checkOnHold(false) { }
00074
00075
public:
00076
QString protocol;
00077
QString proxy;
00078
bool checkOnHold;
00079 };
00080
00081
class KIO::Scheduler::ExtraJobData:
public QPtrDict<KIO::Scheduler::JobData>
00082 {
00083
public:
00084 ExtraJobData() { setAutoDelete(
true); }
00085 };
00086
00087
class KIO::Scheduler::ProtocolInfo
00088 {
00089
public:
00090 ProtocolInfo() : maxSlaves(1), skipCount(0)
00091 {
00092 joblist.setAutoDelete(
false);
00093 }
00094
00095
QPtrList<SimpleJob> joblist;
00096 SlaveList activeSlaves;
00097
int maxSlaves;
00098
int skipCount;
00099
QString protocol;
00100 };
00101
00102
class KIO::Scheduler::ProtocolInfoDict :
public QDict<KIO::Scheduler::ProtocolInfo>
00103 {
00104
public:
00105 ProtocolInfoDict() { }
00106
00107 KIO::Scheduler::ProtocolInfo *
get(
const QString &protocol);
00108 };
00109
00110 KIO::Scheduler::ProtocolInfo *
00111
KIO::Scheduler::ProtocolInfoDict::get(
const QString &protocol)
00112 {
00113 ProtocolInfo *info =
find(protocol);
00114
if (!info)
00115 {
00116 info =
new ProtocolInfo;
00117 info->protocol = protocol;
00118 info->maxSlaves =
KProtocolInfo::maxSlaves( protocol );
00119
00120
insert(protocol, info);
00121 }
00122
return info;
00123 }
00124
00125
00126 Scheduler::Scheduler()
00127 :
DCOPObject( "KIO::
Scheduler" ),
00128
QObject(kapp, "scheduler"),
00129 slaveTimer(0, "
Scheduler::slaveTimer"),
00130 coSlaveTimer(0, "
Scheduler::coSlaveTimer"),
00131 cleanupTimer(0, "
Scheduler::cleanupTimer")
00132 {
00133 checkOnHold =
true;
00134 slaveOnHold = 0;
00135 protInfoDict =
new ProtocolInfoDict;
00136 slaveList =
new SlaveList;
00137 idleSlaves =
new SlaveList;
00138 coIdleSlaves =
new SlaveList;
00139 extraJobData =
new ExtraJobData;
00140 sessionData =
new SessionData;
00141 slaveConfig = SlaveConfig::self();
00142 connect(&slaveTimer, SIGNAL(timeout()), SLOT(startStep()));
00143 connect(&coSlaveTimer, SIGNAL(timeout()), SLOT(slotScheduleCoSlave()));
00144 connect(&cleanupTimer, SIGNAL(timeout()), SLOT(slotCleanIdleSlaves()));
00145 busy =
false;
00146 }
00147
00148 Scheduler::~Scheduler()
00149 {
00150 protInfoDict->setAutoDelete(
true);
00151
delete protInfoDict; protInfoDict = 0;
00152
delete idleSlaves; idleSlaves = 0;
00153
delete coIdleSlaves; coIdleSlaves = 0;
00154 slaveList->setAutoDelete(
true);
00155
delete slaveList; slaveList = 0;
00156
delete extraJobData; extraJobData = 0;
00157
delete sessionData; sessionData = 0;
00158 instance = 0;
00159 }
00160
00161
void
00162 Scheduler::debug_info()
00163 {
00164 }
00165
00166
bool Scheduler::process(
const QCString &fun,
const QByteArray &data,
QCString &replyType,
QByteArray &replyData )
00167 {
00168
if ( fun !=
"reparseSlaveConfiguration(QString)" )
00169
return DCOPObject::process( fun, data, replyType, replyData );
00170
00171 slaveConfig = SlaveConfig::self();
00172 replyType =
"void";
00173
QDataStream stream( data, IO_ReadOnly );
00174
QString proto;
00175 stream >> proto;
00176
00177
kdDebug( 7006 ) <<
"reparseConfiguration( " << proto <<
" )" <<
endl;
00178
KProtocolManager::reparseConfiguration();
00179 slaveConfig->reset();
00180 sessionData->reset();
00181
NetRC::self()->
reload();
00182
00183 Slave *slave = slaveList->first();
00184
for (; slave; slave = slaveList->next() )
00185
if ( slave->slaveProtocol() == proto || proto.isEmpty() )
00186 {
00187 slave->send( CMD_REPARSECONFIGURATION );
00188 slave->resetHost();
00189 }
00190
return true;
00191 }
00192
00193 QCStringList
Scheduler::functions()
00194 {
00195 QCStringList funcs =
DCOPObject::functions();
00196 funcs <<
"void reparseSlaveConfiguration(QString)";
00197
return funcs;
00198 }
00199
00200
void Scheduler::_doJob(
SimpleJob *job) {
00201 JobData *jobData =
new JobData;
00202 jobData->protocol =
KProtocolManager::slaveProtocol(job->
url(), jobData->proxy);
00203
00204
if (job->
command() == CMD_GET)
00205 {
00206 jobData->checkOnHold = checkOnHold;
00207 checkOnHold =
false;
00208 }
00209 extraJobData->replace(job, jobData);
00210 newJobs.
append(job);
00211 slaveTimer.
start(0,
true);
00212
#ifndef NDEBUG
00213
if (newJobs.
count() > 150)
00214
kdDebug() <<
"WARNING - KIO::Scheduler got more than 150 jobs! This shows a misuse in your app (yes, a job is a QObject)." <<
endl;
00215
#endif
00216
}
00217
00218
void Scheduler::_scheduleJob(
SimpleJob *job) {
00219 newJobs.
removeRef(job);
00220 JobData *jobData = extraJobData->find(job);
00221
if (!jobData)
00222 {
00223
kdFatal(7006) <<
"BUG! _ScheduleJob(): No extraJobData for job!" <<
endl;
00224
return;
00225 }
00226
QString protocol = jobData->protocol;
00227
00228 ProtocolInfo *protInfo = protInfoDict->get(protocol);
00229 protInfo->joblist.append(job);
00230
00231 slaveTimer.
start(0,
true);
00232 }
00233
00234
void Scheduler::_cancelJob(
SimpleJob *job) {
00235
00236 Slave *slave = job->
slave();
00237
if ( !slave )
00238 {
00239
00240 JobData *jobData = extraJobData->find(job);
00241
if (!jobData)
00242
return;
00243
00244 newJobs.
removeRef(job);
00245 ProtocolInfo *protInfo = protInfoDict->get(jobData->protocol);
00246 protInfo->joblist.removeRef(job);
00247
00248
00249 slave = slaveList->first();
00250
for(; slave; slave = slaveList->next())
00251 {
00252 JobList *list = coSlaves.
find(slave);
00253
if (list && list->removeRef(job))
00254
break;
00255
00256 }
00257
if (!slave)
00258 {
00259 extraJobData->remove(job);
00260
return;
00261 }
00262 }
00263
kdDebug(7006) <<
"Scheduler: killing slave " << slave->slave_pid() <<
endl;
00264 slave->kill();
00265 _jobFinished( job, slave );
00266 slotSlaveDied( slave);
00267 }
00268
00269
void Scheduler::startStep()
00270 {
00271
while(newJobs.
count())
00272 {
00273 (
void) startJobDirect();
00274 }
00275
QDictIterator<KIO::Scheduler::ProtocolInfo> it(*protInfoDict);
00276
while(it.
current())
00277 {
00278
if (startJobScheduled(it.
current()))
return;
00279 ++it;
00280 }
00281 }
00282
00283
void Scheduler::setupSlave(KIO::Slave *slave,
const KURL &url,
const QString &protocol,
const QString &proxy ,
bool newSlave,
const KIO::MetaData *config)
00284 {
00285
QString host = url.
host();
00286
int port = url.
port();
00287
QString user = url.
user();
00288
QString passwd = url.
pass();
00289
00290
if ((newSlave) ||
00291 (slave->host() != host) ||
00292 (slave->port() != port) ||
00293 (slave->user() != user) ||
00294 (slave->passwd() != passwd))
00295 {
00296 slaveConfig = SlaveConfig::self();
00297
00298
MetaData configData = slaveConfig->configData(protocol, host);
00299 sessionData->configDataFor( configData, protocol, host );
00300
00301 configData[
"UseProxy"] = proxy;
00302
00303
QString autoLogin = configData[
"EnableAutoLogin"].lower();
00304
if ( autoLogin ==
"true" )
00305 {
00306
NetRC::AutoLogin l;
00307 l.
login = user;
00308
bool usern = (protocol ==
"ftp");
00309
if (
NetRC::self()->
lookup( url, l, usern) )
00310 {
00311 configData[
"autoLoginUser"] = l.
login;
00312 configData[
"autoLoginPass"] = l.
password;
00313
if ( usern )
00314 {
00315
QString macdef;
00316
QMap<QString, QStringList>::ConstIterator it = l.
macdef.
begin();
00317
for ( ; it != l.
macdef.
end(); ++it )
00318 macdef += it.key() +
'\\' + it.data().join(
"\\" ) +
'\n';
00319 configData[
"autoLoginMacro"] = macdef;
00320 }
00321 }
00322 }
00323
if (config)
00324 configData += *config;
00325 slave->setConfig(configData);
00326 slave->setProtocol(url.
protocol());
00327 slave->setHost(host, port, user, passwd);
00328 }
00329 }
00330
00331
bool Scheduler::startJobScheduled(ProtocolInfo *protInfo)
00332 {
00333
if (protInfo->joblist.isEmpty())
00334
return false;
00335
00336
00337 debug_info();
00338
bool newSlave =
false;
00339
00340
SimpleJob *job = 0;
00341 Slave *slave = 0;
00342
00343
if (protInfo->skipCount > 2)
00344 {
00345
bool dummy;
00346
00347
00348 protInfo->skipCount = 0;
00349 job = protInfo->joblist.at(0);
00350 slave = findIdleSlave(protInfo, job, dummy );
00351 }
00352
else
00353 {
00354
bool exact=
false;
00355
SimpleJob *firstJob = 0;
00356 Slave *firstSlave = 0;
00357
for(uint i = 0; (i < protInfo->joblist.count()) && (i < 10); i++)
00358 {
00359 job = protInfo->joblist.at(i);
00360 slave = findIdleSlave(protInfo, job, exact);
00361
if (!firstSlave)
00362 {
00363 firstJob = job;
00364 firstSlave = slave;
00365 }
00366
if (!slave)
break;
00367
if (exact)
break;
00368 }
00369
00370
if (!exact)
00371 {
00372 slave = firstSlave;
00373 job = firstJob;
00374 }
00375
if (job == firstJob)
00376 protInfo->skipCount = 0;
00377
else
00378 protInfo->skipCount++;
00379 }
00380
00381
if (!slave)
00382 {
00383
if ( protInfo->maxSlaves > static_cast<int>(protInfo->activeSlaves.count()) )
00384 {
00385 newSlave =
true;
00386 slave = createSlave(protInfo, job, job->
url());
00387
if (!slave)
00388 slaveTimer.
start(0,
true);
00389 }
00390 }
00391
00392
if (!slave)
00393 {
00394
00395
00396
return false;
00397 }
00398
00399 protInfo->activeSlaves.append(slave);
00400 idleSlaves->removeRef(slave);
00401 protInfo->joblist.removeRef(job);
00402
00403
00404
00405 JobData *jobData = extraJobData->find(job);
00406 setupSlave(slave, job->
url(), jobData->
protocol, jobData->proxy, newSlave);
00407 job->
start(slave);
00408
00409 slaveTimer.
start(0,
true);
00410
return true;
00411 }
00412
00413
bool Scheduler::startJobDirect()
00414 {
00415 debug_info();
00416
SimpleJob *job = newJobs.
take(0);
00417 JobData *jobData = extraJobData->find(job);
00418
if (!jobData)
00419 {
00420
kdFatal(7006) <<
"BUG! startjobDirect(): No extraJobData for job!"
00421 <<
endl;
00422
return false;
00423 }
00424
QString protocol = jobData->protocol;
00425 ProtocolInfo *protInfo = protInfoDict->get(protocol);
00426
00427
bool newSlave =
false;
00428
bool dummy;
00429
00430
00431 Slave *slave = findIdleSlave(protInfo, job, dummy);
00432
00433
if (!slave)
00434 {
00435 newSlave =
true;
00436 slave = createSlave(protInfo, job, job->
url());
00437 }
00438
00439
if (!slave)
00440
return false;
00441
00442 idleSlaves->removeRef(slave);
00443
00444
00445 setupSlave(slave, job->
url(), protocol, jobData->proxy, newSlave);
00446 job->
start(slave);
00447
return true;
00448 }
00449
00450
static Slave *searchIdleList(SlaveList *idleSlaves,
const KURL &url,
const QString &protocol,
bool &exact)
00451 {
00452
QString host = url.
host();
00453
int port = url.
port();
00454
QString user = url.
user();
00455 exact =
true;
00456
00457
for( Slave *slave = idleSlaves->first();
00458 slave;
00459 slave = idleSlaves->next())
00460 {
00461
if ((protocol == slave->slaveProtocol()) &&
00462 (host == slave->host()) &&
00463 (port == slave->port()) &&
00464 (user == slave->user()))
00465
return slave;
00466 }
00467
00468 exact =
false;
00469
00470
00471
for( Slave *slave = idleSlaves->first();
00472 slave;
00473 slave = idleSlaves->next())
00474 {
00475
if (protocol == slave->slaveProtocol())
00476
return slave;
00477 }
00478
return 0;
00479 }
00480
00481 Slave *Scheduler::findIdleSlave(ProtocolInfo *,
SimpleJob *job,
bool &exact)
00482 {
00483 Slave *slave = 0;
00484 JobData *jobData = extraJobData->find(job);
00485
if (!jobData)
00486 {
00487
kdFatal(7006) <<
"BUG! findIdleSlave(): No extraJobData for job!" <<
endl;
00488
return 0;
00489 }
00490
if (jobData->checkOnHold)
00491 {
00492 slave = Slave::holdSlave(jobData->protocol, job->
url());
00493
if (slave)
00494
return slave;
00495 }
00496
if (slaveOnHold)
00497 {
00498
00499
bool bCanReuse = (job->
command() == CMD_GET);
00500
KIO::TransferJob * tJob = dynamic_cast<KIO::TransferJob *>(job);
00501
if ( tJob )
00502 {
00503 bCanReuse = (job->
command() == CMD_GET || job->
command() == CMD_SPECIAL);
00504
if ( bCanReuse )
00505 {
00506
KIO::MetaData outgoing = tJob->
outgoingMetaData();
00507
QString resume = (!outgoing.
contains(
"resume")) ? QString::null : outgoing[
"resume"];
00508
kdDebug(7006) <<
"Resume metadata is '" << resume <<
"'" <<
endl;
00509 bCanReuse = (resume.
isEmpty() || resume ==
"0");
00510 }
00511 }
00512
00513
if (bCanReuse)
00514 {
00515
if (job->
url() == urlOnHold)
00516 {
00517
kdDebug(7006) <<
"HOLD: Reusing held slave for " << urlOnHold.
prettyURL() <<
endl;
00518 slave = slaveOnHold;
00519 }
00520
else
00521 {
00522
kdDebug(7006) <<
"HOLD: Discarding held slave (" << urlOnHold.
prettyURL() <<
")" <<
endl;
00523 slaveOnHold->kill();
00524 }
00525 slaveOnHold = 0;
00526 urlOnHold =
KURL();
00527 }
00528
if (slave)
00529
return slave;
00530 }
00531
00532
return searchIdleList(idleSlaves, job->
url(), jobData->
protocol, exact);
00533 }
00534
00535 Slave *Scheduler::createSlave(ProtocolInfo *protInfo,
SimpleJob *job,
const KURL &url)
00536 {
00537
int error;
00538
QString errortext;
00539 Slave *slave = Slave::createSlave(protInfo->protocol, url, error, errortext);
00540
if (slave)
00541 {
00542 slaveList->append(slave);
00543 idleSlaves->append(slave);
00544
connect(slave, SIGNAL(slaveDied(KIO::Slave *)),
00545 SLOT(slotSlaveDied(KIO::Slave *)));
00546
connect(slave, SIGNAL(slaveStatus(pid_t,
const QCString &,
const QString &,
bool)),
00547 SLOT(slotSlaveStatus(pid_t,
const QCString &,
const QString &,
bool)));
00548
00549
connect(slave,SIGNAL(authorizationKey(
const QCString&,
const QCString&,
bool)),
00550 sessionData,SLOT(slotAuthData(
const QCString&,
const QCString&,
bool)));
00551
connect(slave,SIGNAL(delAuthorization(
const QCString&)), sessionData,
00552 SLOT(slotDelAuthData(
const QCString&)));
00553 }
00554
else
00555 {
00556
kdError() <<
": couldn't create slave : " << errortext <<
endl;
00557
if (job)
00558 {
00559 protInfo->joblist.removeRef(job);
00560 extraJobData->remove(job);
00561 job->
slotError( error, errortext );
00562 }
00563 }
00564
return slave;
00565 }
00566
00567
void Scheduler::slotSlaveStatus(pid_t,
const QCString &,
const QString &,
bool)
00568 {
00569 }
00570
00571
void Scheduler::_jobFinished(
SimpleJob *job, Slave *slave)
00572 {
00573 JobData *jobData = extraJobData->take(job);
00574
if (!jobData)
00575 {
00576
kdFatal(7006) <<
"BUG! _jobFinished(): No extraJobData for job!" <<
endl;
00577
return;
00578 }
00579 ProtocolInfo *protInfo = protInfoDict->get(jobData->protocol);
00580
delete jobData;
00581 slave->disconnect(job);
00582 protInfo->activeSlaves.removeRef(slave);
00583
if (slave->isAlive())
00584 {
00585 JobList *list = coSlaves.
find(slave);
00586
if (list)
00587 {
00588 assert(slave->isConnected());
00589 assert(!coIdleSlaves->contains(slave));
00590 coIdleSlaves->append(slave);
00591
if (!list->isEmpty())
00592 coSlaveTimer.
start(0,
true);
00593
return;
00594 }
00595
else
00596 {
00597 assert(!slave->isConnected());
00598 idleSlaves->append(slave);
00599 slave->setIdle();
00600 _scheduleCleanup();
00601
00602 }
00603 }
00604
if (protInfo->joblist.count())
00605 {
00606 slaveTimer.
start(0,
true);
00607 }
00608 }
00609
00610
void Scheduler::slotSlaveDied(KIO::Slave *slave)
00611 {
00612 assert(!slave->isAlive());
00613 ProtocolInfo *protInfo = protInfoDict->get(slave->slaveProtocol());
00614 protInfo->activeSlaves.removeRef(slave);
00615
if (slave == slaveOnHold)
00616 {
00617 slaveOnHold = 0;
00618 urlOnHold =
KURL();
00619 }
00620 idleSlaves->removeRef(slave);
00621 JobList *list = coSlaves.
find(slave);
00622
if (list)
00623 {
00624
00625 disconnectSlave(slave);
00626 }
00627
00628
if (!slaveList->removeRef(slave))
00629
kdDebug(7006) <<
"Scheduler: BUG!! Slave died, but is NOT in slaveList!!!\n" <<
endl;
00630 slave->deref();
00631 }
00632
00633
void Scheduler::slotCleanIdleSlaves()
00634 {
00635
for(Slave *slave = idleSlaves->first();slave;)
00636 {
00637
if (slave->idleTime() >= MAX_SLAVE_IDLE)
00638 {
00639
00640 Slave *removeSlave = slave;
00641 slave = idleSlaves->next();
00642 idleSlaves->removeRef(removeSlave);
00643 slaveList->removeRef(removeSlave);
00644 removeSlave->connection()->close();
00645 removeSlave->deref();
00646 }
00647
else
00648 {
00649 slave = idleSlaves->next();
00650 }
00651 }
00652 _scheduleCleanup();
00653 }
00654
00655
void Scheduler::_scheduleCleanup()
00656 {
00657
if (idleSlaves->count())
00658 {
00659
if (!cleanupTimer.
isActive())
00660 cleanupTimer.
start( MAX_SLAVE_IDLE*1000,
true );
00661 }
00662 }
00663
00664
void Scheduler::_putSlaveOnHold(
KIO::SimpleJob *job,
const KURL &url)
00665 {
00666 Slave *slave = job->
slave();
00667 slave->disconnect(job);
00668
00669
if (slaveOnHold)
00670 {
00671 slaveOnHold->kill();
00672 }
00673 slaveOnHold = slave;
00674 urlOnHold = url;
00675 slaveOnHold->suspend();
00676 }
00677
00678
void Scheduler::_publishSlaveOnHold()
00679 {
00680
if (!slaveOnHold)
00681
return;
00682
00683 slaveOnHold->hold(urlOnHold);
00684 }
00685
00686
void Scheduler::_removeSlaveOnHold()
00687 {
00688
if (slaveOnHold)
00689 {
00690 slaveOnHold->kill();
00691 }
00692 slaveOnHold = 0;
00693 urlOnHold =
KURL();
00694 }
00695
00696 Slave *
00697 Scheduler::_getConnectedSlave(
const KURL &url,
const KIO::MetaData &config )
00698 {
00699
QString proxy;
00700
QString protocol =
KProtocolManager::slaveProtocol(url, proxy);
00701
bool dummy;
00702 Slave *slave = searchIdleList(idleSlaves, url, protocol, dummy);
00703
if (!slave)
00704 {
00705 ProtocolInfo *protInfo = protInfoDict->get(protocol);
00706 slave = createSlave(protInfo, 0, url);
00707 }
00708
if (!slave)
00709
return 0;
00710 idleSlaves->removeRef(slave);
00711
00712 setupSlave(slave, url, protocol, proxy,
true, &config);
00713
00714 slave->send( CMD_CONNECT );
00715
connect(slave, SIGNAL(connected()),
00716 SLOT(slotSlaveConnected()));
00717
connect(slave, SIGNAL(error(
int,
const QString &)),
00718 SLOT(slotSlaveError(
int,
const QString &)));
00719
00720 coSlaves.
insert(slave,
new QPtrList<SimpleJob>());
00721
00722
return slave;
00723 }
00724
00725
void
00726 Scheduler::slotScheduleCoSlave()
00727 {
00728 Slave *nextSlave;
00729 slaveConfig = SlaveConfig::self();
00730
for(Slave *slave = coIdleSlaves->first();
00731 slave;
00732 slave = nextSlave)
00733 {
00734 nextSlave = coIdleSlaves->next();
00735 JobList *list = coSlaves.
find(slave);
00736 assert(list);
00737
if (list && !list->isEmpty())
00738 {
00739
SimpleJob *job = list->take(0);
00740 coIdleSlaves->removeRef(slave);
00741
00742
00743 assert(!coIdleSlaves->contains(slave));
00744
00745
KURL url =job->
url();
00746
QString host = url.
host();
00747
int port = url.
port();
00748
00749
if (slave->host() ==
"<reset>")
00750 {
00751
QString user = url.
user();
00752
QString passwd = url.
pass();
00753
00754
MetaData configData = slaveConfig->configData(url.
protocol(), url.
host());
00755 slave->setConfig(configData);
00756 slave->setProtocol(url.
protocol());
00757 slave->setHost(host, port, user, passwd);
00758 }
00759
00760 assert(slave->protocol() == url.
protocol());
00761 assert(slave->host() == host);
00762 assert(slave->port() == port);
00763 job->
start(slave);
00764 }
00765 }
00766 }
00767
00768
void
00769 Scheduler::slotSlaveConnected()
00770 {
00771 Slave *slave = (Slave *)
sender();
00772
00773 slave->setConnected(
true);
00774 disconnect(slave, SIGNAL(connected()),
00775
this, SLOT(slotSlaveConnected()));
00776 emit slaveConnected(slave);
00777 assert(!coIdleSlaves->contains(slave));
00778 coIdleSlaves->append(slave);
00779 coSlaveTimer.
start(0,
true);
00780 }
00781
00782
void
00783 Scheduler::slotSlaveError(
int errorNr,
const QString &errorMsg)
00784 {
00785 Slave *slave = (Slave *)
sender();
00786
if (!slave->isConnected() || (coIdleSlaves->find(slave) != -1))
00787 {
00788
00789 emit slaveError(slave, errorNr, errorMsg);
00790 }
00791 }
00792
00793
bool
00794 Scheduler::_assignJobToSlave(KIO::Slave *slave,
SimpleJob *job)
00795 {
00796
00797
QString dummy;
00798
if ((slave->slaveProtocol() !=
KProtocolManager::slaveProtocol( job->
url(), dummy ))
00799 ||
00800 (!newJobs.
removeRef(job)))
00801 {
00802
kdDebug(7006) <<
"_assignJobToSlave(): ERROR, nonmatching or unknown job." <<
endl;
00803 job->
kill();
00804
return false;
00805 }
00806
00807 JobList *list = coSlaves.
find(slave);
00808 assert(list);
00809
if (!list)
00810 {
00811
kdDebug(7006) <<
"_assignJobToSlave(): ERROR, unknown slave." <<
endl;
00812 job->
kill();
00813
return false;
00814 }
00815
00816 assert(list->contains(job) == 0);
00817 list->append(job);
00818 coSlaveTimer.
start(0,
true);
00819
00820
return true;
00821 }
00822
00823
bool
00824 Scheduler::_disconnectSlave(KIO::Slave *slave)
00825 {
00826
00827 JobList *list = coSlaves.
take(slave);
00828 assert(list);
00829
if (!list)
00830
return false;
00831
00832
while(!list->isEmpty())
00833 {
00834 Job *job = list->take(0);
00835 job->kill();
00836 }
00837
delete list;
00838 coIdleSlaves->removeRef(slave);
00839 assert(!coIdleSlaves->contains(slave));
00840 disconnect(slave, SIGNAL(connected()),
00841
this, SLOT(slotSlaveConnected()));
00842 disconnect(slave, SIGNAL(error(
int,
const QString &)),
00843
this, SLOT(slotSlaveError(
int,
const QString &)));
00844
if (slave->isAlive())
00845 {
00846 idleSlaves->append(slave);
00847 slave->send( CMD_DISCONNECT );
00848 slave->setIdle();
00849 slave->setConnected(
false);
00850 _scheduleCleanup();
00851 }
00852
return true;
00853 }
00854
00855
void
00856 Scheduler::_checkSlaveOnHold(
bool b)
00857 {
00858 checkOnHold = b;
00859 }
00860
00861
void
00862 Scheduler::_registerWindow(
QWidget *wid)
00863 {
00864
if (!wid)
00865
return;
00866
00867
QObject *obj = static_cast<QObject *>(wid);
00868
if (!m_windowList.
contains(obj))
00869 {
00870
00871
00872
00873 WId windowId = wid->
winId();
00874 m_windowList.
insert(obj, windowId);
00875
connect(wid, SIGNAL(
destroyed(
QObject *)),
00876
this, SLOT(
slotUnregisterWindow(
QObject*)));
00877
QByteArray params;
00878
QDataStream stream(params, IO_WriteOnly);
00879 stream << windowId;
00880
if( !kapp->dcopClient()->send(
"kded",
"kded",
00881
"registerWindowId(long int)", params ) )
00882
kdDebug(7006) <<
"Could not register window with kded!" <<
endl;
00883 }
00884 }
00885
00886
void
00887 Scheduler::slotUnregisterWindow(
QObject *obj)
00888 {
00889
if (!obj)
00890
return;
00891
00892
QMap<QObject *, WId>::Iterator it = m_windowList.
find(obj);
00893
if (it == m_windowList.
end())
00894
return;
00895 WId windowId = it.data();
00896 disconnect( it.key(), SIGNAL(
destroyed(
QObject *)),
00897
this, SLOT(
slotUnregisterWindow(
QObject*)));
00898 m_windowList.
remove( it );
00899
if (kapp)
00900 {
00901
QByteArray params;
00902
QDataStream stream(params, IO_WriteOnly);
00903 stream << windowId;
00904 kapp->dcopClient()->send(
"kded",
"kded",
00905
"unregisterWindowId(long int)", params );
00906 }
00907 }
00908
00909
Scheduler* Scheduler::self() {
00910
if ( !instance ) {
00911 instance =
new Scheduler;
00912 }
00913
return instance;
00914 }
00915
00916
void Scheduler::virtual_hook(
int id,
void* data )
00917 {
DCOPObject::virtual_hook(
id, data ); }
00918
00919
00920
00921
#include "scheduler.moc"