Index: kio/scheduler.cpp
===================================================================
--- kio/scheduler.cpp	(revision 1016510)
+++ kio/scheduler.cpp	(working copy)
@@ -162,13 +162,17 @@
 class KIO::SchedulerPrivate::ProtocolInfo
 {
 public:
-    ProtocolInfo() : maxSlaves(1), skipCount(0)
+    ProtocolInfo() : maxSlaves(1), maxSlavesPerHost(0), skipCount(0)
     {
     }
 
     ~ProtocolInfo()
     {
-        qDeleteAll(allSlaves());
+        qDeleteAll(joblist.begin(), joblist.end());
+        qDeleteAll(activeSlaves.begin(), activeSlaves.end());
+        qDeleteAll(idleSlaves.begin(), idleSlaves.end());
+        qDeleteAll(coSlaves.begin(), coSlaves.end());
+        qDeleteAll(coIdleSlaves.begin(), coIdleSlaves.end());
     }
 
     // bad performance, but will change this later
@@ -181,12 +185,30 @@
         return ret;
     }
 
+    int activeSlavesCountFor(const QString& host) const
+    {
+        int count = 0;
+
+        if (!host.isEmpty())
+        {
+            QListIterator<Slave *> it (activeSlaves);
+            while (it.hasNext())
+            {
+                if (host == it.next()->host())
+                    count++;
+            }
+        }
+
+        return count;
+    }
+
     QList<SimpleJob *> joblist;
     SlaveList activeSlaves;
     SlaveList idleSlaves;
     CoSlaveMap coSlaves;
     SlaveList coIdleSlaves;
     int maxSlaves;
+    int maxSlavesPerHost;
     int skipCount;
     QString protocol;
 };
@@ -200,6 +222,7 @@
         info = new ProtocolInfo;
         info->protocol = protocol;
         info->maxSlaves = KProtocolInfo::maxSlaves( protocol );
+        info->maxSlavesPerHost = KProtocolInfo::maxSlavesPerHost( protocol );
 
         insert(protocol, info);
     }
@@ -382,9 +405,9 @@
     }
 }
 
-void SchedulerPrivate::doJob(SimpleJob *job) {
+void SchedulerPrivate::doJob(SimpleJob *job) {  
     JobData jobData;
-    jobData.protocol = KProtocolManager::slaveProtocol(job->url(), jobData.proxy);
+    jobData.protocol = KProtocolManager::slaveProtocol(job->url(), jobData.proxy);    
 //    kDebug(7006) << "protocol=" << jobData->protocol;
     if (jobCommand(job) == CMD_GET)
     {
@@ -401,15 +424,17 @@
 }
 
 void SchedulerPrivate::scheduleJob(SimpleJob *job) {
+
     newJobs.removeOne(job);
     const JobData& jobData = extraJobData.value(job);
 
     QString protocol = jobData.protocol;
 //    kDebug(7006) << "protocol=" << protocol;
     ProtocolInfo *protInfo = protInfoDict.get(protocol);
-    protInfo->joblist.append(job);
-
-    slaveTimer.start(0);
+    if (!protInfo->joblist.contains(job)) { // scheduleJob already called for this job?
+        protInfo->joblist.append(job);
+        slaveTimer.start(0);
+    }
 }
 
 void SchedulerPrivate::cancelJob(SimpleJob *job) {
@@ -520,7 +545,7 @@
 
     SimpleJob *job = 0;
     Slave *slave = 0;
-
+    
     if (protInfo->skipCount > 2)
     {
        bool dummy;
@@ -528,7 +553,10 @@
        // 2 times in a row. The
        protInfo->skipCount = 0;
        job = protInfo->joblist.at(0);
-       slave = findIdleSlave(protInfo, job, dummy );
+       
+       if (protInfo->maxSlavesPerHost < 1 ||
+           protInfo->maxSlavesPerHost > protInfo->activeSlavesCountFor(job->url().host()))       
+          slave = findIdleSlave(protInfo, job, dummy );
     }
     else
     {
@@ -538,7 +566,11 @@
        for(int i = 0; (i < protInfo->joblist.count()) && (i < 10); i++)
        {
           job = protInfo->joblist.at(i);
-          slave = findIdleSlave(protInfo, job, exact);
+
+          if (protInfo->maxSlavesPerHost < 1 ||
+              protInfo->maxSlavesPerHost > protInfo->activeSlavesCountFor(job->url().host()))
+             slave = findIdleSlave(protInfo, job, exact);
+
           if (!firstSlave)
           {
              firstJob = job;
@@ -561,10 +593,20 @@
 
     if (!slave)
     {
-       if ( protInfo->maxSlaves > static_cast<int>(protInfo->activeSlaves.count()) )
+      KUrl url (job->url());
+
+//      kDebug() << "# of slave allowed  : " << protInfo->maxSlaves;
+//      kDebug() << "# of active ioslaves: " << protInfo->activeSlaves.count();
+//      kDebug() << "# of active ioslaves allowed per host: " << protInfo->maxSlavesPerHost;
+//      if (!url.isLocalFile())
+//        kDebug() << "# of active ioslaves for " << url.host() << ": " << protInfo->activeSlavesCountFor(url.host());
+
+       if ( protInfo->maxSlaves > protInfo->activeSlaves.count() &&
+            (protInfo->maxSlavesPerHost < 1 ||
+             protInfo->maxSlavesPerHost > protInfo->activeSlavesCountFor(url.host())) )
        {
           newSlave = true;
-          slave = createSlave(protInfo, job, job->url());
+          slave = createSlave(protInfo, job, url);
           if (!slave)
              slaveTimer.start(0);
        }
@@ -955,16 +997,15 @@
 {
 //    kDebug(7006) << "_assignJobToSlave( " << job << ", " << slave << ")";
     QString dummy;
-    if ((slave->slaveProtocol() != KProtocolManager::slaveProtocol( job->url(), dummy ))
-        ||
-        (!newJobs.removeAll(job)))
+    ProtocolInfo *protInfo = protInfoDict.get(slave->protocol());
+    if ((slave->slaveProtocol() != KProtocolManager::slaveProtocol( job->url(), dummy )) ||
+        (!protInfo->joblist.removeAll(job) && !newJobs.removeAll(job)))
     {
         kDebug(7006) << "_assignJobToSlave(): ERROR, nonmatching or unknown job.";
         job->kill();
         return false;
     }
 
-    ProtocolInfo *protInfo = protInfoDict.get(slave->protocol());
     JobList *list = protInfo->coSlaves.value(slave);
     assert(list);
     if (!list)
