TDE core libraries
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

scheduler.h 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. // -*- c++ -*-
  2. /* This file is part of the KDE libraries
  3. Copyright (C) 2000 Stephan Kulow <coolo@kde.org>
  4. Waldo Bastian <bastian@kde.org>
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public
  7. License as published by the Free Software Foundation; either
  8. version 2 of the License, or (at your option) any later version.
  9. This library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public License
  14. along with this library; see the file COPYING.LIB. If not, write to
  15. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  16. Boston, MA 02110-1301, USA.
  17. */
  18. #ifndef _tdeio_scheduler_h
  19. #define _tdeio_scheduler_h
  20. #include "tdeio/job.h"
  21. #include "tdeio/jobclasses.h"
  22. #include <tqtimer.h>
  23. #include <tqptrdict.h>
  24. #include <tqmap.h>
  25. #include <dcopobject.h>
  26. namespace TDEIO {
  27. class Slave;
  28. class SlaveList;
  29. class SlaveConfig;
  30. class SessionData;
  31. /**
  32. * The TDEIO::Scheduler manages io-slaves for the application.
  33. * It also queues jobs and assigns the job to a slave when one
  34. * becomes available.
  35. *
  36. * There are 3 possible ways for a job to get a slave:
  37. *
  38. * <h3>1. Direct</h3>
  39. * This is the default. When you create a job the
  40. * TDEIO::Scheduler will be notified and will find either an existing
  41. * slave that is idle or it will create a new slave for the job.
  42. *
  43. * Example:
  44. * \code
  45. * TransferJob *job = TDEIO::get(KURL("http://www.kde.org"));
  46. * \endcode
  47. *
  48. *
  49. * <h3>2. Scheduled</h3>
  50. * If you create a lot of jobs, you might want not want to have a
  51. * slave for each job. If you schedule a job, a maximum number
  52. * of slaves will be created. When more jobs arrive, they will be
  53. * queued. When a slave is finished with a job, it will be assigned
  54. * a job from the queue.
  55. *
  56. * Example:
  57. * \code
  58. * TransferJob *job = TDEIO::get(KURL("http://www.kde.org"));
  59. * TDEIO::Scheduler::scheduleJob(job);
  60. * \endcode
  61. *
  62. * <h3>3. Connection Oriented</h3>
  63. * For some operations it is important that multiple jobs use
  64. * the same connection. This can only be ensured if all these jobs
  65. * use the same slave.
  66. *
  67. * You can ask the scheduler to open a slave for connection oriented
  68. * operations. You can then use the scheduler to assign jobs to this
  69. * slave. The jobs will be queued and the slave will handle these jobs
  70. * one after the other.
  71. *
  72. * Example:
  73. * \code
  74. * Slave *slave = TDEIO::Scheduler::getConnectedSlave(
  75. * KURL("pop3://bastian:password@mail.kde.org"));
  76. * TransferJob *job1 = TDEIO::get(
  77. * KURL("pop3://bastian:password@mail.kde.org/msg1"));
  78. * TDEIO::Scheduler::assignJobToSlave(slave, job1);
  79. * TransferJob *job2 = TDEIO::get(
  80. * KURL("pop3://bastian:password@mail.kde.org/msg2"));
  81. * TDEIO::Scheduler::assignJobToSlave(slave, job2);
  82. * TransferJob *job3 = TDEIO::get(
  83. * KURL("pop3://bastian:password@mail.kde.org/msg3"));
  84. * TDEIO::Scheduler::assignJobToSlave(slave, job3);
  85. *
  86. * // ... Wait for jobs to finish...
  87. *
  88. * TDEIO::Scheduler::disconnectSlave(slave);
  89. * \endcode
  90. *
  91. * Note that you need to explicitly disconnect the slave when the
  92. * connection goes down, so your error handler should contain:
  93. * \code
  94. * if (error == TDEIO::ERR_CONNECTION_BROKEN)
  95. * TDEIO::Scheduler::disconnectSlave(slave);
  96. * \endcode
  97. *
  98. * @see TDEIO::Slave
  99. * @see TDEIO::Job
  100. **/
  101. class TDEIO_EXPORT Scheduler : public TQObject, virtual public DCOPObject {
  102. Q_OBJECT
  103. public:
  104. typedef TQPtrList<SimpleJob> JobList;
  105. // InfoDict needs Info, so we can't declare it private
  106. class ProtocolInfo;
  107. class JobData;
  108. ~Scheduler();
  109. /**
  110. * Register @p job with the scheduler.
  111. * The default is to create a new slave for the job if no slave
  112. * is available. This can be changed by calling scheduleJob.
  113. * @param job the job to register
  114. */
  115. static void doJob(SimpleJob *job)
  116. { self()->_doJob(job); }
  117. /**
  118. * Calling ths function makes that @p job gets scheduled for later
  119. * execution, if multiple jobs are registered it might wait for
  120. * other jobs to finish.
  121. * @param job the job to schedule
  122. */
  123. static void scheduleJob(SimpleJob *job)
  124. { self()->_scheduleJob(job); }
  125. /**
  126. * Stop the execution of a job.
  127. * @param job the job to cancel
  128. */
  129. static void cancelJob(SimpleJob *job)
  130. { self()->_cancelJob(job); }
  131. /**
  132. * Called when a job is done.
  133. * @param job the finished job
  134. * @param slave the slave that executed the @p job
  135. */
  136. static void jobFinished(TDEIO::SimpleJob *job, TDEIO::Slave *slave)
  137. { self()->_jobFinished(job, slave); }
  138. /**
  139. * Puts a slave on notice. A next job may reuse this slave if it
  140. * requests the same URL.
  141. *
  142. * A job can be put on hold after it has emit'ed its mimetype.
  143. * Based on the mimetype, the program can give control to another
  144. * component in the same process which can then resume the job
  145. * by simply asking for the same URL again.
  146. * @param job the job that should be stopped
  147. * @param url the URL that is handled by the @p url
  148. */
  149. static void putSlaveOnHold(TDEIO::SimpleJob *job, const KURL &url)
  150. { self()->_putSlaveOnHold(job, url); }
  151. /**
  152. * Removes any slave that might have been put on hold. If a slave
  153. * was put on hold it will be killed.
  154. */
  155. static void removeSlaveOnHold()
  156. { self()->_removeSlaveOnHold(); }
  157. /**
  158. * Send the slave that was put on hold back to KLauncher. This
  159. * allows another process to take over the slave and resume the job
  160. * that was started.
  161. */
  162. static void publishSlaveOnHold()
  163. { self()->_publishSlaveOnHold(); }
  164. /**
  165. * Requests a slave for use in connection-oriented mode.
  166. *
  167. * @param url This defines the username,password,host & port to
  168. * connect with.
  169. * @param config Configuration data for the slave.
  170. *
  171. * @return A pointer to a connected slave or 0 if an error occurred.
  172. * @see assignJobToSlave()
  173. * @see disconnectSlave()
  174. */
  175. static TDEIO::Slave *getConnectedSlave(const KURL &url, const TDEIO::MetaData &config = MetaData() )
  176. { return self()->_getConnectedSlave(url, config); }
  177. /*
  178. * Uses @p slave to do @p job.
  179. * This function should be called immediately after creating a Job.
  180. *
  181. * @param slave The slave to use. The slave must have been obtained
  182. * with a call to getConnectedSlave and must not
  183. * be currently assigned to any other job.
  184. * @param job The job to do.
  185. *
  186. * @return true is successful, false otherwise.
  187. *
  188. * @see getConnectedSlave()
  189. * @see disconnectSlave()
  190. * @see slaveConnected()
  191. * @see slaveError()
  192. */
  193. static bool assignJobToSlave(TDEIO::Slave *slave, TDEIO::SimpleJob *job)
  194. { return self()->_assignJobToSlave(slave, job); }
  195. /*
  196. * Disconnects @p slave.
  197. *
  198. * @param slave The slave to disconnect. The slave must have been
  199. * obtained with a call to getConnectedSlave
  200. * and must not be assigned to any job.
  201. *
  202. * @return true is successful, false otherwise.
  203. *
  204. * @see getConnectedSlave
  205. * @see assignJobToSlave
  206. */
  207. static bool disconnectSlave(TDEIO::Slave *slave)
  208. { return self()->_disconnectSlave(slave); }
  209. /**
  210. * Send the slave that was put on hold back to KLauncher. This
  211. * allows another process to take over the slave and resume the job
  212. * the that was started.
  213. * Register the mainwindow @p wid with the KIO subsystem
  214. * Do not call this, it is called automatically from
  215. * void TDEIO::Job::setWindow(TQWidget*).
  216. * @param wid the window to register
  217. * @since 3.1
  218. */
  219. static void registerWindow(TQWidget *wid)
  220. { self()->_registerWindow(wid); }
  221. /**
  222. * @internal
  223. * Unregisters the window registered by registerWindow().
  224. */
  225. static void unregisterWindow(TQObject *wid)
  226. { self()->slotUnregisterWindow(wid); }
  227. /**
  228. * Function to connect signals emitted by the scheduler.
  229. *
  230. * @see slaveConnected()
  231. * @see slaveError()
  232. */
  233. static bool connect( const char *signal, const TQObject *receiver,
  234. const char *member)
  235. { return TQObject::connect(self(), signal, receiver, member); }
  236. static bool connect( const TQObject* sender, const char* signal,
  237. const TQObject* receiver, const char* member )
  238. { return TQObject::connect(sender, signal, receiver, member); }
  239. static bool disconnect( const TQObject* sender, const char* signal,
  240. const TQObject* receiver, const char* member )
  241. { return TQObject::disconnect(sender, signal, receiver, member); }
  242. bool connect( const TQObject *sender, const char *signal,
  243. const char *member )
  244. { return TQObject::connect(sender, signal, member); }
  245. /**
  246. * When true, the next job will check whether KLauncher has a slave
  247. * on hold that is suitable for the job.
  248. * @param b true when KLauncher has a job on hold
  249. */
  250. static void checkSlaveOnHold(bool b) { self()->_checkSlaveOnHold(b); }
  251. void debug_info();
  252. virtual bool process(const TQCString &fun, const TQByteArray &data,
  253. TQCString& replyType, TQByteArray &replyData);
  254. virtual QCStringList functions();
  255. public slots:
  256. void slotSlaveDied(TDEIO::Slave *slave);
  257. void slotSlaveStatus(pid_t pid, const TQCString &protocol,
  258. const TQString &host, bool connected);
  259. signals:
  260. void slaveConnected(TDEIO::Slave *slave);
  261. void slaveError(TDEIO::Slave *slave, int error, const TQString &errorMsg);
  262. protected:
  263. void setupSlave(TDEIO::Slave *slave, const KURL &url, const TQString &protocol, const TQString &proxy , bool newSlave, const TDEIO::MetaData *config=0);
  264. bool startJobScheduled(ProtocolInfo *protInfo);
  265. bool startJobDirect();
  266. Scheduler();
  267. protected slots:
  268. void startStep();
  269. void slotCleanIdleSlaves();
  270. void slotSlaveConnected();
  271. void slotSlaveError(int error, const TQString &errorMsg);
  272. void slotScheduleCoSlave();
  273. /// @since 3.1
  274. void slotUnregisterWindow(TQObject *);
  275. private:
  276. class ProtocolInfoDict;
  277. class ExtraJobData;
  278. Scheduler(const Scheduler&);
  279. static Scheduler *self();
  280. static Scheduler *instance;
  281. void _doJob(SimpleJob *job);
  282. void _scheduleJob(SimpleJob *job);
  283. void _cancelJob(SimpleJob *job);
  284. void _jobFinished(TDEIO::SimpleJob *job, TDEIO::Slave *slave);
  285. void _scheduleCleanup();
  286. void _putSlaveOnHold(TDEIO::SimpleJob *job, const KURL &url);
  287. void _removeSlaveOnHold();
  288. Slave *_getConnectedSlave(const KURL &url, const TDEIO::MetaData &metaData );
  289. bool _assignJobToSlave(TDEIO::Slave *slave, TDEIO::SimpleJob *job);
  290. bool _disconnectSlave(TDEIO::Slave *slave);
  291. void _checkSlaveOnHold(bool b);
  292. void _publishSlaveOnHold();
  293. void _registerWindow(TQWidget *wid);
  294. Slave *findIdleSlave(ProtocolInfo *protInfo, SimpleJob *job, bool &exact);
  295. Slave *createSlave(ProtocolInfo *protInfo, SimpleJob *job, const KURL &url);
  296. TQTimer slaveTimer;
  297. TQTimer coSlaveTimer;
  298. TQTimer cleanupTimer;
  299. bool busy;
  300. SlaveList *slaveList;
  301. SlaveList *idleSlaves;
  302. SlaveList *coIdleSlaves;
  303. ProtocolInfoDict *protInfoDict;
  304. Slave *slaveOnHold;
  305. KURL urlOnHold;
  306. JobList newJobs;
  307. TQPtrDict<JobList> coSlaves;
  308. ExtraJobData *extraJobData;
  309. SlaveConfig *slaveConfig;
  310. SessionData *sessionData;
  311. bool checkOnHold;
  312. TQMap<TQObject *,WId> m_windowList;
  313. protected:
  314. virtual void virtual_hook( int id, void* data );
  315. private:
  316. class SchedulerPrivate* d;
  317. };
  318. }
  319. #endif