libkdepim

weaver.h
1 /* -*- C++ -*-
2 
3  This file declares the Weaver, Job and Thread classes.
4 
5  $ Author: Mirko Boehm $
6  $ Copyright: (C) 2004, Mirko Boehm $
7  $ Contact: mirko@kde.org
8  http://www.kde.org
9  http://www.hackerbuero.org $
10  $ License: LGPL with the following explicit clarification:
11  This code may be linked against any version of the TQt toolkit
12  from Troll Tech, Norway. $
13 
14 */
15 
16 #ifndef WEAVER_H
17 #define WEAVER_H
18 
19 extern "C"
20 {
21 #include <stdarg.h>
22 #include <unistd.h>
23 #include <stdio.h>
24 }
25 
26 #include <tqobject.h>
27 #include <tqptrlist.h>
28 #include <tqthread.h>
29 #include <tqwaitcondition.h>
30 #include <tqmutex.h>
31 #include <tqevent.h>
32 
33 #include <kdepimmacros.h>
34 
35 namespace KPIM {
36 namespace ThreadWeaver {
37 
54  KDE_EXPORT extern bool Debug;
55  KDE_EXPORT extern int DebugLevel;
56 
57  KDE_EXPORT inline void setDebugLevel (bool debug, int level)
58  {
59  Debug = debug;
60  DebugLevel = level;
61  }
62 
63  KDE_EXPORT inline void debug(int severity, const char * cformat, ...)
64 #ifdef __GNUC__
65  __attribute__ ( (format (printf, 2, 3 ) ) )
66 #endif
67 ;
68 
69  KDE_EXPORT inline void debug(int severity, const char * cformat, ...)
70  {
71  if ( Debug == true && ( severity<=DebugLevel || severity == 0) )
72  {
73  static TQMutex mutex;
74  TQString text;
75 
76  mutex.lock();
77  va_list ap;
78  va_start( ap, cformat );
79  vprintf (cformat, ap);
80  va_end (ap);
81  mutex.unlock();
82  }
83  }
84 
85 
86  class Thread;
87  class Job;
88 
100  class KDE_EXPORT Event : public TQCustomEvent
101  {
102  public:
103  enum Action {
104  NoAction = 0,
105  Finished,
108  ThreadExiting,
109  ThreadBusy,
110  ThreadSuspended,
111  JobStarted,
112  JobFinished,
113  JobSPR,
114  JobAPR
115  };
116  Event ( Action = NoAction, Thread * = 0, Job *job = 0);
118  static int type ();
120  Thread* thread () const;
122  Job* job () const;
124  Action action () const;
125  private:
126  Action m_action;
127  Thread *m_thread;
128  Job *m_job;
129  static const int Type;
130  };
131 
164  class KDE_EXPORT Job : public TQObject
165  {
166  Q_OBJECT
167  TQ_OBJECT
168  public:
170  Job(TQObject* parent=0, const char* name=0);
171 
173  virtual ~Job();
174 
179  virtual void execute(Thread*);
180 
182  virtual bool isFinished() const;
183 
185  void wakeAPR ();
186 
189  virtual void processEvent ( Event* );
190 
191  signals:
193  void started ();
195  void done ();
208  void SPR ();
211  void APR ();
212  protected:
214  void lock();
216  void unlock();
220  virtual void run () = 0;
223  Thread *thread();
225  virtual void setFinished(bool status);
229  void triggerSPR ();
235  void triggerAPR ();
236 
237  bool m_finished;
238 
239  TQMutex *m_mutex;
240 
241  Thread * m_thread;
242 
243  TQWaitCondition *m_wc;
244  };
245 
246  class Weaver;
247 
250  class KDE_EXPORT Thread : public TQThread
251  {
252  public:
256  Thread(Weaver *parent);
257 
259  ~Thread();
260 
270  void run();
271 
272  /* Provide the msleep() method (protected in TQThread) to be
273  available for executed jobs. */
274  void msleep(unsigned long msec);
275 
280  unsigned int id() const;
281 
283  void post (Event::Action, Job* = 0);
284 
285  private:
286  Weaver *m_parent;
287 
288  const unsigned int m_id;
289 
290  static unsigned int sm_Id;
291 
292  static unsigned int makeId();
293  };
294 
297  class KDE_EXPORT Weaver : public TQObject
298  {
299  Q_OBJECT
300  TQ_OBJECT
301  public:
302  Weaver (TQObject* parent=0, const char* name=0,
303  int inventoryMin = 4, // minimal number of provided threads
304  int inventoryMax = 32); // maximum number of provided threads
305  virtual ~Weaver ();
307  virtual void enqueue (Job*);
316  void enqueue (TQPtrList<Job> jobs);
326  virtual bool dequeue (Job*);
330  virtual void dequeue ();
333  // virtual void jobFinished(Thread *);
341  virtual void finish();
352  virtual void suspend (bool state);
354  bool isEmpty () const;
358  bool isIdle () const;
360  int queueLength ();
371  virtual Job* applyForWork (Thread *thread, Job *previous);
375  void lock ();
377  void unlock ();
382  void post (Event::Action, Thread* = 0, Job* = 0);
384  int threads () const;
385  signals:
392  void finished ();
397  void suspended ();
401  void jobDone (Job*);
402 // The following signals are used mainly for debugging purposes.
403  void threadCreated (Thread *);
404  void threadDestroyed (Thread *);
405  void threadBusy (Thread *);
406  void threadSuspended (Thread *);
407 
408  protected:
412  void assignJobs();
415  bool event ( TQEvent* );
417  TQPtrList<Thread> m_inventory;
419  TQPtrList<Job> m_assignments;
422  int m_active;
428  TQWaitCondition m_jobAvailable;
430  TQWaitCondition m_jobFinished;
438  bool m_running;
443  bool m_suspend;
444  private:
446  TQMutex *m_mutex;
447  };
448 } // namespace ThreadWeaver
449 } // namespace KPIM
450 
451 #endif // defined WEAVER_H