20 #include <tqapplication.h> 25 namespace ThreadWeaver {
31 : TQObject (parent, name),
33 m_mutex (new TQMutex (true) ),
68 TQMutexLocker l (m_mutex);
74 TQMutexLocker l (m_mutex);
80 TQMutexLocker l (m_mutex);
88 case Event::JobStarted:
91 case Event::JobFinished:
110 m_wc =
new TQWaitCondition;
113 thread()->
post (KPIM::ThreadWeaver::Event::JobSPR,
this);
125 m_wc =
new TQWaitCondition;
134 TQMutexLocker l(m_mutex);
143 const int Event::Type = TQEvent::User + 1000;
146 : TQCustomEvent ( type () ),
178 unsigned int Thread::sm_Id;
191 unsigned int Thread::makeId()
193 static TQMutex mutex;
194 TQMutexLocker l (&mutex);
212 debug ( 3,
"Thread::run [%u]: trying to execute the next job.\n",
id() );
220 post ( Event::JobStarted, job );
222 post ( Event::JobFinished, job );
226 post ( Event::ThreadExiting );
231 m_parent->
post ( a,
this, j);
234 void Thread::msleep(
unsigned long msec)
236 TQThread::msleep(msec);
239 Weaver::Weaver(TQObject* parent,
const char* name,
240 int inventoryMin,
int inventoryMax)
241 : TQObject(parent, name),
243 m_inventoryMin(inventoryMin),
244 m_inventoryMax(inventoryMax),
245 m_shuttingDown(
false),
248 m_mutex (
new TQMutex(
true) )
252 for (
int count = 0; count < m_inventoryMin; ++count)
255 m_inventory.append(th);
259 emit (threadCreated (th) );
269 debug ( 1,
"Weaver dtor: destroying inventory.\n" );
271 m_shuttingDown =
true;
275 m_jobAvailable.wakeAll();
284 for (
Thread *th = m_inventory.first(); th; th = m_inventory.next() )
286 if ( !th->finished() )
288 m_jobAvailable.wakeAll();
292 emit (threadDestroyed (th) );
301 debug ( 1,
"Weaver dtor: done\n" );
307 debug ( 3 ,
"Weaver::lock: lock (mutex is %s).\n",
308 ( m_mutex->locked() ?
"locked" :
"not locked" ) );
316 debug ( 3 ,
"Weaver::unlock: unlock (mutex is %s).\n",
317 ( m_mutex->locked() ?
"locked" :
"not locked" ) );
322 TQMutexLocker l (m_mutex);
323 return m_inventory.count ();
330 m_assignments.append(job);
342 for (
Job * job = jobs.first(); job; job = jobs.next() )
344 m_assignments.append (job);
354 TQMutexLocker l (m_mutex);
355 return m_assignments.remove (job);
360 TQMutexLocker l (m_mutex);
361 m_assignments.clear();
372 if ( m_active == 0 && isEmpty() )
380 debug (2,
"Weaver::suspend: queueing resumed.\n" );
388 m_jobAvailable.wakeAll();
393 if ( e->type() >= TQEvent::User )
400 switch (event->action() )
402 case Event::JobFinished:
403 if ( event->job() !=0 )
405 emit (jobDone (event->job() ) );
408 case Event::Finished:
412 emit ( suspended() );
414 case Event::ThreadSuspended:
415 if (!m_shuttingDown )
417 emit (threadSuspended ( event->thread() ) );
420 case Event::ThreadBusy:
421 if (!m_shuttingDown )
423 emit (threadBusy (event->thread() ) );
430 if ( event->job() !=0 )
432 event->job()->processEvent (event);
435 debug ( 0,
"Weaver::event: Strange: received unknown user event.\n" );
440 return TQObject::event ( e );
447 TQApplication::postEvent (
this, e);
452 TQMutexLocker l (m_mutex);
453 return m_assignments.count()==0;
459 bool lastjob =
false;
460 bool suspended =
false;
470 debug ( 3,
"Weaver::applyForWork: job done, %i jobs left, " 471 "%i active jobs left.\n",
472 queueLength(), m_active );
474 if ( m_active == 0 && isEmpty() )
478 post (Event::Finished);
479 debug ( 3,
"Weaver::applyForWork: last job.\n" );
482 if (m_active == 0 && m_suspend ==
true)
486 debug ( 2,
"Weaver::applyForWork: queueing suspended.\n" );
489 m_jobFinished.wakeOne();
494 if (m_shuttingDown ==
true)
500 if ( !isEmpty() && m_suspend ==
false )
502 rc = m_assignments.getFirst();
503 m_assignments.removeFirst ();
506 debug ( 3,
"Weaver::applyForWork: job assigned, " 507 "%i jobs in queue (%i active).\n",
508 m_assignments.count(), m_active );
511 post (Event::ThreadBusy, th);
517 post (Event::ThreadSuspended, th);
518 m_jobAvailable.wait();
526 TQMutexLocker l (m_mutex);
527 return m_assignments.count();
532 TQMutexLocker l (m_mutex);
533 return isEmpty() && m_active == 0;
540 debug (2,
"Weaver::finish: not done, waiting.\n" );
541 m_jobFinished.wait();
543 debug (1,
"Weaver::finish: done.\n\n\n" );
549 #include "weaver.moc" void started()
This signal is emitted when a thread starts to process a job.
bool isIdle() const
Is the weaver idle? The weaver is idle if no jobs are queued and no jobs are processed by the threads...
virtual void execute(Thread *)
Perform the job.
unsigned int id() const
Returns the thread id.
A class to represent the events threads generate and send to the Weaver object.
virtual ~Job()
Destructor.
bool isEmpty() const
Is the queue empty?
virtual void finish()
Get notified when a thread has finished a job.
A weaver is the manager of worker threads (Thread objects) to which it assigns jobs from it's queue...
Thread * thread() const
The ID of the sender thread.
Job(TQObject *parent=0, const char *name=0)
Construct a Job object.
void unlock()
Unlock this Job's mutex.
virtual void setFinished(bool status)
Call with status = true to mark this job as done.
void done()
This signal is emitted when a job has been finished.
All jobs in the queue are done.
virtual bool isFinished() const
Returns true if the jobs's execute method finished.
void lock()
Lock this Job's mutex.
virtual void dequeue()
Remove all queued jobs.
void triggerAPR()
Trigger an APR.
void SPR()
This signal is emitted when the job needs some operation done by the main thread (usually the creator...
Thread(Weaver *parent)
Create a thread.
void post(Event::Action, Thread *=0, Job *=0)
Post an event that is handled by this object, but in the main (GUI) thread.
virtual void processEvent(Event *)
Process events related to this job (created by the processing thread or the weaver or whoever)...
Synchronous Process Request.
virtual void suspend(bool state)
Suspend job execution if state = true, otherwise resume job execution if it was suspended.
Action action() const
The action.
virtual void run()=0
The method that actually performs the job.
void wakeAPR()
Wake the thread after an APR has been processed.
int queueLength()
Returns the number of pending jobs.
virtual Job * applyForWork(Thread *thread, Job *previous)
Assign a job to the calling thread.
void lock()
Lock the mutex for this weaver.
void triggerSPR()
Trigger a SPR.
Job * job() const
The associated job.
TDEPIM classes for drag and drop of mails.
void post(Event::Action, Job *=0)
Post an event, will be received and processed by the Weaver.
virtual void enqueue(Job *)
Add a job to be executed.
bool event(TQEvent *)
Check incoming events for user defined ones.
Thread * thread()
Return the thread that executes this job.
void APR()
Perform an Asynchronous Process Request.
The class Thread is used to represent the worker threads in the weaver's inventory.
A Job is a simple abstraction of an action that is to be executed in a thread context.
void run()
Overloaded to execute the assigned job.
int threads() const
Returns the current number of threads in the inventory.
static int type()
Return the (custom defined) event type.
void assignJobs()
Schedule enqueued jobs to be executed by idle threads.