00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
namespace KPIM {
00034
namespace ThreadWeaver {
00035
00052
extern bool Debug;
00053
extern int DebugLevel;
00054
00055
inline void setDebugLevel (
bool debug,
int level)
00056 {
00057 Debug = debug;
00058 DebugLevel = level;
00059 }
00060
00061
inline void debug(
int severity,
const char * cformat, ...)
00062 #ifdef __GNUC__
00063 __attribute__ ( (format (printf, 2, 3 ) ) )
00064 #endif
00065 ;
00066
00067
inline void debug(
int severity,
const char * cformat, ...)
00068 {
00069
if ( Debug ==
true && ( severity<=DebugLevel || severity == 0) )
00070 {
00071
static QMutex mutex;
00072
QString text;
00073
00074 mutex.lock();
00075 va_list ap;
00076 va_start( ap, cformat );
00077 vprintf (cformat, ap);
00078 va_end (ap);
00079 mutex.unlock();
00080 }
00081 }
00082
00083
00084
class Thread;
00085
class Job;
00086
00098 class Event :
public QCustomEvent
00099 {
00100
public:
00101 enum Action {
00102 NoAction = 0,
00103 Finished,
00104
Suspended,
00105
ThreadStarted,
00106 ThreadExiting,
00107 ThreadBusy,
00108 ThreadSuspended,
00109 JobStarted,
00110 JobFinished,
00111 JobSPR,
00112
JobAPR
00113 };
00114
Event ( Action = NoAction,
Thread * = 0,
Job *job = 0);
00116
static const int type ();
00118
Thread*
thread () const;
00120
Job* job () const;
00122 Action action () const;
00123 private:
00124 Action m_action;
00125
Thread *m_thread;
00126
Job *m_job;
00127 static const
int Type;
00128 };
00129
00162 class
Job : public
QObject
00163 {
00164 Q_OBJECT
00165
public:
00167
Job(QObject* parent=0,
const char* name=0);
00168
00170
virtual ~
Job();
00171
00176
virtual void execute(
Thread*);
00177
00179
virtual bool isFinished()
const;
00180
00182
void wakeAPR ();
00183
00186
virtual void processEvent (
Event* );
00187
00188 signals:
00190
void started ();
00192
void done ();
00205
void SPR ();
00208
void APR ();
00209
protected:
00211
void lock();
00213
void unlock();
00217
virtual void run () = 0;
00220
Thread *
thread();
00222
virtual void setFinished(
bool status);
00226
void triggerSPR ();
00232
void triggerAPR ();
00233
00234
bool m_finished;
00235
00236
QMutex *m_mutex;
00237
00238
Thread * m_thread;
00239
00240
QWaitCondition *m_wc;
00241 };
00242
00243
class Weaver;
00244
00247 class Thread :
public QThread
00248 {
00249
public:
00253
Thread(
Weaver *parent);
00254
00256 ~
Thread();
00257
00267
void run();
00268
00269
00270
00271
void msleep(
unsigned long msec);
00272
00277
const unsigned int id()
const;
00278
00280
void post (Event::Action,
Job* = 0);
00281
00282
private:
00283
Weaver *m_parent;
00284
00285
const unsigned int m_id;
00286
00287
static unsigned int sm_Id;
00288
00289
static unsigned int makeId();
00290 };
00291
00294 class Weaver :
public QObject
00295 {
00296 Q_OBJECT
00297
public:
00298
Weaver (
QObject* parent=0,
const char* name=0,
00299
int inventoryMin = 4,
00300
int inventoryMax = 32);
00301
virtual ~
Weaver ();
00303
virtual void enqueue (
Job*);
00312
void enqueue (
QPtrList<Job> jobs);
00322
virtual bool dequeue (
Job*);
00326
virtual void dequeue ();
00329
00337
virtual void finish();
00348
virtual void suspend (
bool state);
00350
bool isEmpty ()
const;
00354
bool isIdle ()
const;
00356
int queueLength ();
00367
virtual Job* applyForWork (
Thread *thread,
Job *previous);
00371
void lock ();
00373
void unlock ();
00378
void post (Event::Action,
Thread* = 0,
Job* = 0);
00380
int threads ()
const;
00381 signals:
00388
void finished ();
00393
void suspended ();
00397
void jobDone (
Job*);
00398
00399
void threadCreated (
Thread *);
00400
void threadDestroyed (
Thread *);
00401
void threadBusy (
Thread *);
00402
void threadSuspended (
Thread *);
00403
00404
protected:
00408
void assignJobs();
00411
bool event (
QEvent* );
00413 QPtrList<Thread> m_inventory;
00415 QPtrList<Job> m_assignments;
00418 int m_active;
00420 int m_inventoryMin;
00422 int m_inventoryMax;
00424 QWaitCondition m_jobAvailable;
00426 QWaitCondition m_jobFinished;
00429 bool m_shuttingDown;
00434 bool m_running;
00439 bool m_suspend;
00440
private:
00442
QMutex *m_mutex;
00443 };
00444 }
00445 }
00446
00447
#endif // defined WEAVER_H