libkdepim

weaver.h

00001 /* -*- C++ -*-
00002 
00003    This file declares the Weaver, Job and Thread classes.
00004 
00005    $ Author: Mirko Boehm $
00006    $ Copyright: (C) 2004, Mirko Boehm $
00007    $ Contact: mirko@kde.org
00008          http://www.kde.org
00009          http://www.hackerbuero.org $
00010    $ License: LGPL with the following explicit clarification:
00011          This code may be linked against any version of the TQt toolkit
00012          from Troll Tech, Norway. $
00013 
00014 */
00015 
00016 #ifndef WEAVER_H
00017 #define WEAVER_H
00018 
00019 extern "C"
00020 {
00021 #include <stdarg.h>
00022 #include <unistd.h>
00023 #include <stdio.h>
00024 }
00025 
00026 #include <tqobject.h>
00027 #include <tqptrlist.h>
00028 #include <tqthread.h>
00029 #include <tqwaitcondition.h>
00030 #include <tqmutex.h>
00031 #include <tqevent.h>
00032 
00033 #include <kdepimmacros.h>
00034 
00035 namespace KPIM {
00036 namespace ThreadWeaver {
00037 
00054     KDE_EXPORT extern bool Debug;
00055     KDE_EXPORT extern int DebugLevel;
00056 
00057     KDE_EXPORT inline void setDebugLevel (bool debug, int level)
00058         {
00059             Debug = debug;
00060             DebugLevel = level;
00061         }
00062 
00063     KDE_EXPORT inline void debug(int severity, const char * cformat, ...)
00064 #ifdef __GNUC__
00065         __attribute__ ( (format (printf, 2, 3 ) ) )
00066 #endif
00067 ;
00068 
00069     KDE_EXPORT inline void debug(int severity, const char * cformat, ...)
00070     {
00071         if ( Debug == true && ( severity<=DebugLevel || severity == 0) )
00072         {
00073             static TQMutex mutex;
00074             TQString text;
00075 
00076             mutex.lock();
00077             va_list ap;
00078             va_start( ap, cformat );
00079             vprintf (cformat, ap);
00080             va_end (ap);
00081             mutex.unlock();
00082         }
00083     }
00084 
00085 
00086     class Thread;
00087     class Job;
00088 
00100     class KDE_EXPORT Event : public TQCustomEvent
00101     {
00102     public:
00103         enum Action {
00104             NoAction = 0,
00105             Finished, 
00106             Suspended, 
00107             ThreadStarted,
00108             ThreadExiting,
00109             ThreadBusy,
00110             ThreadSuspended,
00111             JobStarted,
00112             JobFinished,
00113             JobSPR, 
00114             JobAPR  
00115         };
00116         Event ( Action = NoAction, Thread * = 0, Job *job = 0);
00118         static int type ();
00120         Thread* thread () const;
00122         Job* job () const;
00124         Action action () const;
00125     private:
00126         Action m_action;
00127         Thread *m_thread;
00128         Job *m_job;
00129         static const int Type;
00130     };
00131 
00164     class KDE_EXPORT Job : public TQObject
00165     {
00166         Q_OBJECT
00167   TQ_OBJECT
00168     public:
00170         Job(TQObject* parent=0, const char* name=0);
00171 
00173         virtual ~Job();
00174 
00179         virtual void execute(Thread*);
00180 
00182         virtual bool isFinished() const;
00183 
00185         void wakeAPR ();
00186 
00189         virtual void processEvent ( Event* );
00190 
00191     signals:
00193         void started ();
00195         void done ();
00208         void SPR ();
00211         void APR ();
00212     protected:
00214         void lock();
00216         void unlock();
00220         virtual void run () = 0;
00223         Thread *thread();
00225         virtual void setFinished(bool status);
00229         void triggerSPR ();
00235         void triggerAPR ();
00236 
00237         bool m_finished;
00238 
00239         TQMutex *m_mutex;
00240 
00241         Thread * m_thread;
00242 
00243         TQWaitCondition *m_wc;
00244     };
00245 
00246     class Weaver;
00247 
00250     class KDE_EXPORT Thread : public TQThread
00251     {
00252     public:
00256         Thread(Weaver *parent);
00257 
00259         ~Thread();
00260 
00270         void run();
00271 
00272         /* Provide the msleep() method (protected in TQThread) to be
00273            available  for executed jobs. */
00274         void msleep(unsigned long msec);
00275 
00280         unsigned int id() const;
00281 
00283         void post (Event::Action, Job* = 0);
00284 
00285     private:
00286         Weaver *m_parent;
00287 
00288         const unsigned int m_id;
00289 
00290         static unsigned int sm_Id;
00291 
00292         static unsigned int makeId();
00293     };
00294 
00297     class KDE_EXPORT Weaver : public TQObject
00298     {
00299         Q_OBJECT
00300   TQ_OBJECT
00301     public:
00302         Weaver (TQObject* parent=0, const char* name=0,
00303                 int inventoryMin = 4, // minimal number of provided threads
00304                 int inventoryMax = 32); // maximum number of provided threads
00305         virtual ~Weaver ();
00307         virtual void enqueue (Job*);
00316         void enqueue (TQPtrList<Job> jobs);
00326         virtual bool dequeue (Job*);
00330         virtual void dequeue ();
00333         // virtual void jobFinished(Thread *);
00341         virtual void finish();
00352         virtual void suspend (bool state);
00354         bool isEmpty () const;
00358         bool isIdle () const;
00360         int queueLength ();
00371         virtual Job* applyForWork (Thread *thread, Job *previous);
00375         void lock ();
00377         void unlock ();
00382                void post (Event::Action, Thread* = 0, Job* = 0);
00384         int threads () const;
00385     signals:
00392         void finished ();
00397         void suspended ();
00401         void jobDone (Job*);
00402 // The following signals are used mainly for debugging purposes.
00403         void threadCreated (Thread *);
00404         void threadDestroyed (Thread *);
00405         void threadBusy (Thread *);
00406         void threadSuspended (Thread *);
00407 
00408     protected:
00412         void assignJobs();
00415         bool event ( TQEvent* );
00417         TQPtrList<Thread> m_inventory;
00419         TQPtrList<Job> m_assignments;
00422         int m_active;
00424         int m_inventoryMin;
00426         int m_inventoryMax;
00428         TQWaitCondition m_jobAvailable;
00430         TQWaitCondition m_jobFinished;
00433         bool m_shuttingDown;
00438         bool m_running;
00443         bool m_suspend;
00444     private:
00446         TQMutex *m_mutex;
00447     };
00448 } // namespace ThreadWeaver
00449 } // namespace KPIM
00450 
00451 #endif // defined WEAVER_H