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 Qt 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 <qobject.h>
00027 #include <qptrlist.h>
00028 #include <qthread.h>
00029 #include <qwaitcondition.h>
00030 #include <qmutex.h>
00031 #include <qevent.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 QMutex mutex;
00074             QString 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 QCustomEvent
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 const 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 QObject
00165     {
00166         Q_OBJECT
00167     public:
00169         Job(QObject* parent=0, const char* name=0);
00170 
00172         virtual ~Job();
00173 
00178         virtual void execute(Thread*);
00179 
00181         virtual bool isFinished() const;
00182 
00184         void wakeAPR ();
00185 
00188         virtual void processEvent ( Event* );
00189 
00190     signals:
00192         void started ();
00194         void done ();
00207         void SPR ();
00210         void APR ();
00211     protected:
00213         void lock();
00215         void unlock();
00219         virtual void run () = 0;
00222         Thread *thread();
00224         virtual void setFinished(bool status);
00228         void triggerSPR ();
00234         void triggerAPR ();
00235 
00236         bool m_finished;
00237 
00238         QMutex *m_mutex;
00239 
00240         Thread * m_thread;
00241 
00242         QWaitCondition *m_wc;
00243     };
00244 
00245     class Weaver;
00246 
00249     class KDE_EXPORT Thread : public QThread
00250     {
00251     public:
00255         Thread(Weaver *parent);
00256 
00258         ~Thread();
00259 
00269         void run();
00270 
00271         /* Provide the msleep() method (protected in QThread) to be
00272            available  for executed jobs. */
00273         void msleep(unsigned long msec);
00274 
00279         const unsigned int id() const;
00280 
00282         void post (Event::Action, Job* = 0);
00283 
00284     private:
00285         Weaver *m_parent;
00286 
00287         const unsigned int m_id;
00288 
00289         static unsigned int sm_Id;
00290 
00291         static unsigned int makeId();
00292     };
00293 
00296     class KDE_EXPORT Weaver : public QObject
00297     {
00298         Q_OBJECT
00299     public:
00300         Weaver (QObject* parent=0, const char* name=0,
00301                 int inventoryMin = 4, // minimal number of provided threads
00302                 int inventoryMax = 32); // maximum number of provided threads
00303         virtual ~Weaver ();
00305         virtual void enqueue (Job*);
00314         void enqueue (QPtrList<Job> jobs);
00324         virtual bool dequeue (Job*);
00328         virtual void dequeue ();
00331         // virtual void jobFinished(Thread *);
00339         virtual void finish();
00350         virtual void suspend (bool state);
00352         bool isEmpty () const;
00356         bool isIdle () const;
00358         int queueLength ();
00369         virtual Job* applyForWork (Thread *thread, Job *previous);
00373         void lock ();
00375         void unlock ();
00380                void post (Event::Action, Thread* = 0, Job* = 0);
00382         int threads () const;
00383     signals:
00390         void finished ();
00395         void suspended ();
00399         void jobDone (Job*);
00400 // The following signals are used mainly for debugging purposes.
00401         void threadCreated (Thread *);
00402         void threadDestroyed (Thread *);
00403         void threadBusy (Thread *);
00404         void threadSuspended (Thread *);
00405 
00406     protected:
00410         void assignJobs();
00413         bool event ( QEvent* );
00415         QPtrList<Thread> m_inventory;
00417         QPtrList<Job> m_assignments;
00420         int m_active;
00422         int m_inventoryMin;
00424         int m_inventoryMax;
00426         QWaitCondition m_jobAvailable;
00428         QWaitCondition m_jobFinished;
00431         bool m_shuttingDown;
00436         bool m_running;
00441         bool m_suspend;
00442     private:
00444         QMutex *m_mutex;
00445     };
00446 } // namespace ThreadWeaver
00447 } // namespace KPIM
00448 
00449 #endif // defined WEAVER_H
KDE Home | KDE Accessibility Home | Description of Access Keys