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