[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kfm-devel
Subject:    PATCH: Handing over of IO-slaves
From:       Waldo Bastian <bastian () kde ! org>
Date:       2001-10-30 22:05:10
[Download RAW message or body]

The following patch makes it possible to hand over IO-Slaves from one process 
to another. There are two functions that you might be interested in:

* KIO::Scheduler::publishSlaveOnHold()
After an IO-slave has been put on hold by calling putSlaveOnHold(), 
publishSlaveOnHold() will send the slave back to klauncher, making it 
available for other processes as well.

* KIO::Scheduler::checkSlaveOnHold(bool b)
Calling this function before starting a "GET" job, will, once the GET job 
starts, query klauncher whether a slave has been put on hold for it. The 
default is "true" at startup and it is reset to false after each GET request.

Together with some changes to KRun, this means that you can now click on a 
link in an application and that determining the mimetype (which happens in 
the application) and actually reading the contents (which happens in the 
application that gets started for the mimetype) is handled by a single GET 
request and a single io-slave.

Some problems:
* If the link is handled by an other but already running application, 
KIO::Scheduler::checkSlaveOnHold() should be called. I guess I need to add 
that to NetAccess somewhere.

* There is a race condition between publising the slave and requesting the 
slave by the other application. It can be that the slave still has to connect 
to klauncher when the other application checks for the slave. I think 
publishSlaveOnHold should wait till the slave has connected itself to 
klauncher somehow.

Please test. With this change it should be possible to simplify konq_run and 
khtml_run as well I think.

Cheers,
Waldo
-- 
bastian@kde.org | SuSE Labs KDE Developer | bastian@suse.com

["kio_slave_hold.diff" (text/x-diff)]

Index: krun.cpp
===================================================================
RCS file: /home/kde/kdelibs/kio/krun.cpp,v
retrieving revision 1.180
diff -u -3 -d -p -r1.180 krun.cpp
--- krun.cpp	2001/10/29 11:45:06	1.180
+++ krun.cpp	2001/10/30 21:29:49
@@ -28,6 +28,7 @@
 #include "kmimemagic.h"
 #include "kio/job.h"
 #include "kio/global.h"
+#include "kio/scheduler.h"
 
 #include <kdatastream.h>
 #include <kmessageboxwrapper.h>
@@ -643,9 +644,11 @@ void KRun::scanFile()
   }
   kdDebug(7010) << this << " Scanning file " << m_strURL.url() << endl;
 
-  KIO::MimetypeJob *job = KIO::mimetype( m_strURL, m_bProgressInfo );
-  connect(job, SIGNAL( result( KIO::Job *)),
+  KIO::TransferJob *job = KIO::get( m_strURL, m_bProgressInfo );
+  connect(job, SIGNAL( result(KIO::Job *)),
           this, SLOT( slotScanFinished(KIO::Job *)));
+  connect(job, SIGNAL( mimetype(KIO::Job *, const QString &)),
+          this, SLOT( slotScanMimeType(KIO::Job *, const QString &)));
   m_job = job;
 }
 
@@ -729,18 +732,19 @@ void KRun::slotStatResult( KIO::Job * jo
   }
 }
 
-void KRun::slotScanFinished( KIO::Job *job )
+void KRun::slotScanMimeType( KIO::Job *job, const QString &mimetype )
 {
-  m_job = 0;
-  if (job->error())
-  {
-     slotStatResult( job ); // hacky - we just want to use the same code on error
-     return;
-  }
-  QString mimetype = ((KIO::MimetypeJob *)job)->mimetype();
   if ( mimetype.isEmpty() )
     kdWarning(7010) << "KRun::slotScanFinished : MimetypeJob didn't find a mimetype! \
Probably a kioslave bug." << endl;  foundMimeType( mimetype );
+  m_job = 0;
+}
+
+void KRun::slotScanFinished( KIO::Job *job )
+{
+  m_job = 0;
+  slotStatResult( job ); // hacky - we just want to use the same code on error
+  return;
 }
 
 void KRun::foundMimeType( const QString& type )
@@ -799,6 +803,13 @@ void KRun::foundMimeType( const QString&
     return;
   }
 */
+  if (m_job && m_job->inherits("KIO::TransferJob"))
+  {
+     KIO::TransferJob *job = static_cast<KIO::TransferJob *>(m_job);
+     job->putOnHold();
+     KIO::Scheduler::publishSlaveOnHold();
+     m_job = 0;
+  }
 
   if (KRun::runURL( m_strURL, type )){
     m_bFinished = true;
Index: krun.h
===================================================================
RCS file: /home/kde/kdelibs/kio/krun.h,v
retrieving revision 1.65
diff -u -3 -d -p -r1.65 krun.h
--- krun.h	2001/10/29 11:45:06	1.65
+++ krun.h	2001/10/30 21:29:49
@@ -179,6 +179,7 @@ signals:
 protected slots:
   void slotTimeout();
   void slotScanFinished( KIO::Job * );
+  void slotScanMimeType( KIO::Job *, const QString &type );
   void slotStatResult( KIO::Job * );
 
 protected:
Index: scheduler.cpp
===================================================================
RCS file: /home/kde/kdelibs/kio/scheduler.cpp,v
retrieving revision 1.78
diff -u -3 -d -p -r1.78 scheduler.cpp
--- scheduler.cpp	2001/09/10 19:42:58	1.78
+++ scheduler.cpp	2001/10/30 21:29:50
@@ -68,6 +68,7 @@ class KIO::Scheduler::JobData
 public:
     QString protocol;
     QString proxy;
+    bool checkOnHold;
 };
 
 class KIO::Scheduler::ExtraJobData: public QPtrDict<KIO::Scheduler::JobData>
@@ -118,6 +119,7 @@ Scheduler::Scheduler()
            coSlaveTimer(this, "Scheduler::coSlaveTimer"),
            cleanupTimer(this, "Scheduler::cleanupTimer")
 {
+    checkOnHold = true; // !! Always check with KLauncher for the first request.
     slaveOnHold = 0;
     protInfoDict = new ProtocolInfoDict;
     slaveList = new SlaveList;
@@ -189,6 +191,11 @@ void Scheduler::_doJob(SimpleJob *job) {
     JobData *jobData = new JobData;
     jobData->protocol = KProtocolManager::slaveProtocol(job->url(), jobData->proxy);
 //    kdDebug(7006) << "Scheduler::_doJob protocol=" << jobData->protocol << endl;
+    if (job->command() == CMD_GET)
+    {
+       jobData->checkOnHold = checkOnHold;
+       checkOnHold = false;
+    }
     extraJobData->replace(job, jobData);
     newJobs.append(job);
     slaveTimer.start(0, true);
@@ -495,6 +502,18 @@ static Slave *searchIdleList(SlaveList *
 Slave *Scheduler::findIdleSlave(ProtocolInfo *, SimpleJob *job, bool &exact)
 {
     Slave *slave = 0;
+    JobData *jobData = extraJobData->find(job);
+if (!jobData)
+{
+    kdFatal(7006) << "BUG! findIdleSlave(): No extraJobData for job!" << endl;
+    return 0;
+}
+    if (jobData->checkOnHold)
+    {
+       slave = Slave::holdSlave(jobData->protocol, job->url());
+       if (slave)
+          return slave;
+    }
     if (slaveOnHold)
     {
        // Make sure that the job wants to do a GET or a POST, and with no offset
@@ -531,12 +550,6 @@ Slave *Scheduler::findIdleSlave(Protocol
           return slave;
     }
 
-    JobData *jobData = extraJobData->find(job);
-if (!jobData)
-{
-    kdFatal(7006) << "BUG! findIdleSlave(): No extraJobData for job!" << endl;
-    return 0;
-}
     return searchIdleList(idleSlaves, job->url(), jobData->protocol, exact);
 }
 
@@ -683,6 +696,14 @@ void Scheduler::_putSlaveOnHold(KIO::Sim
     slaveOnHold->suspend();
 }
 
+void Scheduler::_publishSlaveOnHold()
+{
+    if (!slaveOnHold)
+       return;
+
+    slaveOnHold->hold(urlOnHold);
+}
+
 void Scheduler::_removeSlaveOnHold()
 {
     if (slaveOnHold)
@@ -879,6 +900,13 @@ Scheduler::_disconnectSlave(KIO::Slave *
     }
     return true;
 }
+
+void 
+Scheduler::_checkSlaveOnHold(bool b)
+{
+    checkOnHold = b;
+}
+
 
 static KStaticDeleter<Scheduler> ksds;
 
Index: scheduler.h
===================================================================
RCS file: /home/kde/kdelibs/kio/scheduler.h,v
retrieving revision 1.35
diff -u -3 -d -p -r1.35 scheduler.h
--- scheduler.h	2001/10/15 21:02:40	1.35
+++ scheduler.h	2001/10/30 21:29:50
@@ -107,25 +107,62 @@ namespace KIO {
 
         ~Scheduler();
 
+        /**
+         * Register @p job with the scheduler. 
+         * The default is to create a new slave for the job if no slave
+         * is available. This can be changed by calling @ref scheduleJob.
+         */
         static void doJob(SimpleJob *job)
         { self()->_doJob(job); }
 
+        /**
+         * Calling ths function makes that @p job gets scheduled for later
+         * execution, if multiple jobs are registered it might wait for
+         * other jobs to finish.
+         */
         static void scheduleJob(SimpleJob *job)
         { self()->_scheduleJob(job); }
 
+        /**
+         * Stop the execution of a job.
+         */
         static void cancelJob(SimpleJob *job)
         { self()->_cancelJob(job); }
 
+        /**
+         * Called when a job is done.
+         */
         static void jobFinished(KIO::SimpleJob *job, KIO::Slave *slave)
         { self()->_jobFinished(job, slave); }
 
+        /**
+         * Puts a slave on notice. A next job may reuse this slave if it
+         * requests the same URL.
+         *
+         * A job can be put on hold after it has emit'ed its mimetype.
+         * Based on the mimetype, the program can give control to another
+         * component in the same process which can then resume the job
+         * by simply asking for the same URL again.
+         */
         static void putSlaveOnHold(KIO::SimpleJob *job, const KURL &url)
         { self()->_putSlaveOnHold(job, url); }
 
+        /**
+         * Removes any slave that might have been put on hold. If a slave 
+         * was put on hold it will be killed.
+         */
         static void removeSlaveOnHold()
         { self()->_removeSlaveOnHold(); }
 
         /**
+         * Send the slave that was put on hold back to KLauncher. This
+         * allows another process to take over the slave and resume the job
+         * the that was started.
+         */
+        static void publishSlaveOnHold()
+        { self()->_publishSlaveOnHold(); }
+
+        /**
          * Requests a slave for use in connection-oriented mode.
          *
          * @param url This defines the username,password,host & port to
@@ -197,6 +234,12 @@ namespace KIO {
                       const char *member )
         { return QObject::connect(sender, signal, member); }
 
+        /**
+         * When true, the next job will check whether KLauncher has a slave 
+         * on hold that is suitable for the job.
+         */
+        static void checkSlaveOnHold(bool b) { self()->_checkSlaveOnHold(b); }
+
         void debug_info();
 
         virtual bool process(const QCString &fun, const QByteArray &data,
@@ -241,9 +284,12 @@ namespace KIO {
         Slave *_getConnectedSlave(const KURL &url, const KIO::MetaData &metaData );
         bool _assignJobToSlave(KIO::Slave *slave, KIO::SimpleJob *job);
         bool _disconnectSlave(KIO::Slave *slave);
+        void _checkSlaveOnHold(bool b);
+        void _publishSlaveOnHold();
 
         Slave *findIdleSlave(ProtocolInfo *protInfo, SimpleJob *job, bool &exact);
         Slave *createSlave(ProtocolInfo *protInfo, SimpleJob *job, const KURL &url);
+        
 
         QTimer slaveTimer;
         QTimer coSlaveTimer;
@@ -263,6 +309,7 @@ namespace KIO {
         ExtraJobData *extraJobData;
         SlaveConfig *slaveConfig;
         SessionData *sessionData;
+        bool checkOnHold;
 };
 
 };
Index: slave.cpp
===================================================================
RCS file: /home/kde/kdelibs/kio/slave.cpp,v
retrieving revision 1.45
diff -u -3 -d -p -r1.45 slave.cpp
--- slave.cpp	2001/09/25 12:04:11	1.45
+++ slave.cpp	2001/10/30 21:29:50
@@ -160,6 +160,19 @@ void Slave::setPID(pid_t pid)
     m_pid = pid;
 }
 
+void Slave::hold(const KURL &url)
+{
+   ref();
+   QByteArray data;
+   QDataStream stream( data, IO_WriteOnly );
+   stream << url;
+   slaveconn.send( CMD_SLAVE_HOLD, data );
+   slaveconn.close();
+   dead = true;
+   emit slaveDied(this);
+   deref();   
+}
+
 void Slave::suspend()
 {
    slaveconn.suspend();
@@ -263,12 +276,6 @@ void Slave::setConfig(const MetaData &co
     slaveconn.send( CMD_CONFIG, data );
 }
 
-
-Slave* Slave::createSlave( const KURL& url, int& error, QString& error_text )
-{
-   return createSlave(url.protocol(), url, error, error_text);
-}
-
 Slave* Slave::createSlave( const QString &protocol, const KURL& url, int& error, \
QString& error_text )  {
     //kdDebug(7002) << "createSlave '" << protocol << "' for " << url.prettyURL() << \
endl; @@ -305,6 +312,46 @@ Slave* Slave::createSlave( const QString
     {
 	error_text = i18n("Unable to create io-slave:\nklauncher said: %1").arg(errorStr);
 	error = KIO::ERR_CANNOT_LAUNCH_PROCESS;
+        delete slave;
+	return 0;
+    }
+    slave->setPID(pid);
+    QTimer::singleShot(1000*SLAVE_CONNECTION_TIMEOUT_MIN, slave, SLOT(timeout()));
+
+    return slave;
+}
+
+Slave* Slave::holdSlave( const QString &protocol, const KURL& url )
+{
+    //kdDebug(7002) << "holdSlave '" << protocol << "' for " << url.prettyURL() << \
endl; +
+    DCOPClient *client = kapp->dcopClient();
+    if (!client->isAttached())
+	client->attach();
+
+    QString prefix = locateLocal("socket", KGlobal::instance()->instanceName());
+    KTempFile socketfile(prefix, QString::fromLatin1(".slave-socket"));
+
+    KServerSocket *kss = new KServerSocket(QFile::encodeName(socketfile.name()));
+
+    Slave *slave = new Slave(kss, protocol, socketfile.name());
+
+    QByteArray params, reply;
+    QCString replyType;
+    QDataStream stream(params, IO_WriteOnly);
+    stream << url << socketfile.name();
+
+    QCString launcher = KApplication::launcher();
+    if (!client->call(launcher, launcher, "requestHoldSlave(KURL,QString)",
+	    params, replyType, reply)) {
+        delete slave;
+	return 0;
+    }
+    QDataStream stream2(reply, IO_ReadOnly);
+    pid_t pid;
+    stream2 >> pid;
+    if (!pid)
+    {
         delete slave;
 	return 0;
     }
Index: slave.h
===================================================================
RCS file: /home/kde/kdelibs/kio/slave.h,v
retrieving revision 1.23
diff -u -3 -d -p -r1.23 slave.h
--- slave.h	2001/06/01 04:56:11	1.23
+++ slave.h	2001/10/30 21:29:50
@@ -135,15 +135,13 @@ namespace KIO {
 	 */
 	static Slave* createSlave( const QString &protocol, const KURL& url, int& error, \
QString& error_text );  
-        /**
-         * @deprecated FIXME KDE 3.0: remove me
-         */
-	static Slave* createSlave( const KURL& url, int& error, QString& error_text );
+        static Slave* holdSlave( const QString &protocol, const KURL& url );
 
 	void queueOnly(bool queue) { slaveconn.queueOnly(queue); }
 
         void suspend();
         void resume();
+        void hold(const KURL &url);
 
         bool suspended();
 
Index: slavebase.cpp
===================================================================
RCS file: /home/kde/kdelibs/kio/slavebase.cpp,v
retrieving revision 1.95
diff -u -3 -d -p -r1.95 slavebase.cpp
--- slavebase.cpp	2001/10/09 22:51:53	1.95
+++ slavebase.cpp	2001/10/30 21:29:51
@@ -112,6 +112,8 @@ public:
     bool multipleAuthCaching:1;
     MetaData configData;
     SlaveBaseConfig *config;
+    KURL onHoldUrl;
+    bool onHold;
 };
 
 };
@@ -185,6 +187,7 @@ SlaveBase::SlaveBase( const QCString &pr
     d->needSendCanResume = false;
     d->multipleAuthCaching = false;
     d->config = new SlaveBaseConfig(this);
+    d->onHold = false;
 }
 
 SlaveBase::~SlaveBase()
@@ -218,20 +221,7 @@ void SlaveBase::dispatchLoop()
         QByteArray data;
         if ( appconn->read(&cmd, data) != -1 )
         {
-          if (cmd == CMD_SLAVE_CONNECT)
-          {
-            QString app_socket;
-            QDataStream stream( data, IO_ReadOnly);
-            stream >> app_socket;
-            appconn->send( MSG_SLAVE_ACK );
-            disconnectSlave();
-            mConnectedToApp = true;
-            connectSlave(app_socket);
-          }
-          else
-          {
-            dispatch(cmd, data);
-          }
+          dispatch(cmd, data);
         }
         else // some error occured, perhaps no more application
         {
@@ -358,6 +348,8 @@ void SlaveBase::slaveStatus( const QStri
     pid_t pid = getpid();
     Q_INT8 b = connected ? 1 : 0;
     KIO_DATA << pid << mProtocol << host << b;
+    if (d->onHold)
+       stream << d->onHoldUrl;
     m_pConnection->send( MSG_SLAVE_STATUS, data );
 }
 
@@ -402,6 +394,8 @@ static bool isSubCommand(int cmd)
             (cmd == CMD_CONFIG) ||
             (cmd == CMD_SUBURL) ||
             (cmd == CMD_SLAVE_STATUS) ||
+            (cmd == CMD_SLAVE_CONNECT) ||
+            (cmd == CMD_SLAVE_HOLD) ||
             (cmd == CMD_MULTI_GET));
 }
 
@@ -429,6 +423,9 @@ void SlaveBase::mimeType( const QString 
            this->~SlaveBase();
            ::exit(255);
        }
+kdDebug(7019) << "(" << getpid() << ") Slavebase: mimetype got " << cmd << endl;
+       if ( cmd == CMD_HOST) // Ignore.
+          continue;
        if ( isSubCommand(cmd) )
        {
           dispatch( cmd, data );
@@ -439,10 +436,6 @@ void SlaveBase::mimeType( const QString 
   }
   while (cmd != CMD_NONE);
   mOutgoingMetaData.clear();
-  // WABA: cmd can be "CMD_NONE" or "CMD_GET" (in which
-  // case the slave had been put on hold.) [or special,
-  // for http posts]. Something else is basically an error
-  Q_ASSERT( (cmd == CMD_NONE) || (cmd == CMD_GET) || (cmd == CMD_SPECIAL) );
 }
 
 // remove in KDE 3.0
@@ -764,6 +757,29 @@ void SlaveBase::dispatch( int command, c
     case CMD_SLAVE_STATUS:
         slave_status();
         break;
+    case CMD_SLAVE_CONNECT:
+    {
+        d->onHold = false; 
+        QString app_socket;
+        QDataStream stream( data, IO_ReadOnly);
+        stream >> app_socket;
+        appconn->send( MSG_SLAVE_ACK );
+        disconnectSlave();
+        mConnectedToApp = true;
+        connectSlave(app_socket);
+    } break;
+    case CMD_SLAVE_HOLD:
+    {
+        KURL url;
+        QDataStream stream( data, IO_ReadOnly);
+        stream >> url;
+        d->onHoldUrl = url;
+        d->onHold = true;
+        disconnectSlave();
+        mConnectedToApp = false;
+        // Do not close connection!
+        connectSlave(mPoolSocket);
+    } break;
     case CMD_REPARSECONFIGURATION:
         KProtocolManager::reparseConfiguration();
         reparseConfiguration();
@@ -771,12 +787,13 @@ void SlaveBase::dispatch( int command, c
     case CMD_CONFIG:
         stream >> d->configData;
         break;
-    case CMD_GET: {
+    case CMD_GET: 
+    {
         stream >> url;
         get( url );
-    }
-    break;
-    case CMD_PUT: {
+    } break;
+    case CMD_PUT: 
+    {
         int permissions;
         Q_INT8 iOverwrite, iResume;
         stream >> url >> iOverwrite >> iResume >> permissions;
@@ -789,8 +806,7 @@ void SlaveBase::dispatch( int command, c
         d->needSendCanResume = true   /* !resume */;
 
         put( url, permissions, overwrite, resume);
-    }
-    break;
+    } break;
     case CMD_STAT:
         stream >> url;
         stat( url );
@@ -807,37 +823,37 @@ void SlaveBase::dispatch( int command, c
         stream >> url >> i;
         mkdir( url, i );
         break;
-    case CMD_RENAME: {
+    case CMD_RENAME: 
+    {
         Q_INT8 iOverwrite;
         KURL url2;
         stream >> url >> url2 >> iOverwrite;
         bool overwrite = (iOverwrite != 0);
         rename( url, url2, overwrite );
-    }
-    break;
-    case CMD_SYMLINK: {
+    } break;
+    case CMD_SYMLINK: 
+    {
         Q_INT8 iOverwrite;
         QString target;
         stream >> target >> url >> iOverwrite;
         bool overwrite = (iOverwrite != 0);
         symlink( target, url, overwrite );
-    }
-    break;
-    case CMD_COPY: {
+    } break;
+    case CMD_COPY:  
+    {
         int permissions;
         Q_INT8 iOverwrite;
         KURL url2;
         stream >> url >> url2 >> permissions >> iOverwrite;
         bool overwrite = (iOverwrite != 0);
         copy( url, url2, permissions, overwrite );
-    }
-    break;
-    case CMD_DEL: {
+    } break;
+    case CMD_DEL: 
+    {
         Q_INT8 isFile;
         stream >> url >> isFile;
         del( url, isFile != 0);
-    }
-    break;
+    } break;
     case CMD_CHMOD:
         stream >> url >> i;
         chmod( url, i);
Index: slaveinterface.h
===================================================================
RCS file: /home/kde/kdelibs/kio/slaveinterface.h,v
retrieving revision 1.53
diff -u -3 -d -p -r1.53 slaveinterface.h
--- slaveinterface.h	2001/10/09 22:51:53	1.53
+++ slaveinterface.h	2001/10/30 21:29:52
@@ -46,6 +46,7 @@ class SlaveInterfacePrivate;
    CMD_DISCONNECT = '2',
    CMD_SLAVE_STATUS = '3',
    CMD_SLAVE_CONNECT = '4',
+   CMD_SLAVE_HOLD = '5',
    CMD_NONE = 'A', // 65
    CMD_TESTDIR = 'B', // 66
    CMD_GET = 'C', // 67
Index: klauncher/klauncher.cpp
===================================================================
RCS file: /home/kde/kdelibs/kio/klauncher/klauncher.cpp,v
retrieving revision 1.60
diff -u -3 -d -p -r1.60 klauncher.cpp
--- klauncher/klauncher.cpp	2001/10/19 00:34:29	1.60
+++ klauncher/klauncher.cpp	2001/10/30 21:29:53
@@ -60,6 +60,7 @@ IdleSlave::IdleSlave(KSocket *socket)
    mConn.send( CMD_SLAVE_STATUS );
    mPid = 0;
    mBirthDate = time(0);
+   mOnHold = false;
 }
 
 void
@@ -90,10 +91,22 @@ IdleSlave::gotInput()
       QString host;
       Q_INT8 b;
       stream >> pid >> protocol >> host >> b;
+// Overload with (bool) onHold, (KURL) url.
+      if (!stream.atEnd())
+      {
+         KURL url;
+         stream >> url;
+         mOnHold = true;
+         mUrl = url;
+      }
+
       mPid = pid;
       mConnected = (b != 0);
       mProtocol = protocol;
       mHost = host;
+qWarning("Launcher got slave: %d %s %s %s", mPid, mProtocol.latin1(),
+mHost.latin1(), mConnected ? "CONNECTED" : "NOT CONNECTED");
+qWarning("On hold = %s Url = %s", mOnHold ? "HOLD" : "-", mUrl.url().latin1());
    }
 }
 
@@ -116,6 +129,7 @@ IdleSlave::reparseConfiguration()
 bool
 IdleSlave::match(const QString &protocol, const QString &host, bool connected)
 {
+   if (mOnHold) return false;
    if (protocol != mProtocol) return false;
    if (host.isEmpty()) return true;
    if (host != mHost) return false;
@@ -124,6 +138,13 @@ IdleSlave::match(const QString &protocol
    return true;
 }
 
+bool
+IdleSlave::onHold(const KURL &url)
+{
+   if (!mOnHold) return false;
+   return (url == mUrl);
+}
+
 int
 IdleSlave::age(time_t now)
 {
@@ -290,7 +311,19 @@ KLauncher::process(const QCString &fun, 
       QString error;
       pid_t pid = requestSlave(protocol, host, app_socket, error);
       QDataStream stream2(replyData, IO_WriteOnly);
-      stream2 << pid << error;;
+      stream2 << pid << error;
+      return true;
+   }
+   else if (fun == "requestHoldSlave(KURL,QString)")
+   {
+      QDataStream stream(data, IO_ReadOnly);
+      KURL url;
+      QString app_socket;
+      stream >> url >> app_socket;
+      replyType = "pid";
+      pid_t pid = requestHoldSlave(url, app_socket);
+      QDataStream stream2(replyData, IO_WriteOnly);
+      stream2 << pid;
       return true;
    }
    else if (fun == "setLaunchEnv(QCString,QCString)")
@@ -1061,15 +1094,38 @@ KLauncher::removeArg( QValueList<QCStrin
 ///// IO-Slave functions
 
 pid_t
+KLauncher::requestHoldSlave(const KURL &url, const QString &app_socket) 
+{
+qWarning("Request hold slave '%s'", url.url().latin1());
+    IdleSlave *slave;
+    for(slave = mSlaveList.first(); slave; slave = mSlaveList.next())
+    {
+       if (slave->onHold(url))
+          break;
+    }
+    if (slave)
+    {
+qWarning("Found slave %d", slave->pid());
+       mSlaveList.removeRef(slave);
+       slave->connect(app_socket);
+       return slave->pid();
+    }
+qWarning("No slave found.");
+    return 0;
+}
+
+
+pid_t
 KLauncher::requestSlave(const QString &protocol,
                         const QString &host,
-                        const QString &app_socket, QString &error)
+                        const QString &app_socket, 
+                        QString &error)
 {
     IdleSlave *slave;
     for(slave = mSlaveList.first(); slave; slave = mSlaveList.next())
     {
-        if (slave->match(protocol, host, true))
-           break;
+       if (slave->match(protocol, host, true))
+          break;
     }
     if (!slave)
     {
Index: klauncher/klauncher.h
===================================================================
RCS file: /home/kde/kdelibs/kio/klauncher/klauncher.h,v
retrieving revision 1.21
diff -u -3 -d -p -r1.21 klauncher.h
--- klauncher/klauncher.h	2001/09/22 22:56:14	1.21
+++ klauncher/klauncher.h	2001/10/30 21:29:53
@@ -32,6 +32,7 @@
 #include <dcopclient.h>
 #include <kio/connection.h>
 #include <ksock.h>
+#include <kurl.h>
 #include <kuniqueapp.h>
 
 #include <kservice.h>
@@ -48,6 +49,7 @@ public:
    pid_t pid() { return mPid;}
    int age(time_t now);
    void reparseConfiguration();
+   bool onHold(const KURL &url);
 
 protected slots:
    void gotInput();
@@ -59,6 +61,8 @@ protected:
    bool mConnected;
    pid_t mPid;
    time_t mBirthDate;
+   bool mOnHold;
+   KURL mUrl;
 };
 
 class KLaunchRequest
@@ -132,6 +136,7 @@ protected:
 
    void removeArg( QValueList<QCString> &args, const QCString &target);
 
+   pid_t requestHoldSlave(const KURL &url, const QString &app_socket);
    pid_t requestSlave(const QString &protocol, const QString &host,
                       const QString &app_socket, QString &error);
 



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic