21 #include <tqapplication.h> 26 namespace ThreadWeaver {
32 : TQObject (parent, name),
34 m_mutex (new TQMutex (true) ),
69 TQMutexLocker l (m_mutex);
75 TQMutexLocker l (m_mutex);
81 TQMutexLocker l (m_mutex);
89 case Event::JobStarted:
92 case Event::JobFinished:
111 m_wc =
new TQWaitCondition;
114 thread()->
post (KPIM::ThreadWeaver::Event::JobSPR,
this);
126 m_wc =
new TQWaitCondition;
135 TQMutexLocker l(m_mutex);
144 const int Event::Type = TQEvent::User + 1000;
147 : TQCustomEvent ( type () ),
179 unsigned int Thread::sm_Id;
192 unsigned int Thread::makeId()
194 static TQMutex mutex;
195 TQMutexLocker l (&mutex);
213 debug ( 3,
"Thread::run [%u]: trying to execute the next job.\n",
id() );
221 post ( Event::JobStarted, job );
223 post ( Event::JobFinished, job );
227 post ( Event::ThreadExiting );
232 m_parent->
post ( a,
this, j);
235 void Thread::msleep(
unsigned long msec)
237 TQThread::msleep(msec);
240 Weaver::Weaver(TQObject* parent,
const char* name,
241 int inventoryMin,
int inventoryMax)
242 : TQObject(parent, name),
244 m_inventoryMin(inventoryMin),
245 m_inventoryMax(inventoryMax),
246 m_shuttingDown(
false),
249 m_mutex (
new TQMutex(
true) )
253 for (
int count = 0; count < m_inventoryMin; ++count)
256 m_inventory.append(th);
260 emit (threadCreated (th) );
270 debug ( 1,
"Weaver dtor: destroying inventory.\n" );
272 m_shuttingDown =
true;
276 m_jobAvailable.wakeAll();
285 for (
Thread *th = m_inventory.first(); th; th = m_inventory.next() )
287 if ( !th->finished() )
289 m_jobAvailable.wakeAll();
293 emit (threadDestroyed (th) );
302 debug ( 1,
"Weaver dtor: done\n" );
308 debug ( 3 ,
"Weaver::lock: lock (mutex is %s).\n",
309 ( m_mutex->locked() ?
"locked" :
"not locked" ) );
317 debug ( 3 ,
"Weaver::unlock: unlock (mutex is %s).\n",
318 ( m_mutex->locked() ?
"locked" :
"not locked" ) );
323 TQMutexLocker l (m_mutex);
324 return m_inventory.count ();
331 m_assignments.append(job);
343 for (
Job * job = jobs.first(); job; job = jobs.next() )
345 m_assignments.append (job);
355 TQMutexLocker l (m_mutex);
356 return m_assignments.remove (job);
361 TQMutexLocker l (m_mutex);
362 m_assignments.clear();
373 if ( m_active == 0 && isEmpty() )
381 debug (2,
"Weaver::suspend: queueing resumed.\n" );
389 m_jobAvailable.wakeAll();
394 if ( e->type() >= TQEvent::User )
401 switch (event->action() )
403 case Event::JobFinished:
404 if ( event->job() !=0 )
406 emit (jobDone (event->job() ) );
409 case Event::Finished:
413 emit ( suspended() );
415 case Event::ThreadSuspended:
416 if (!m_shuttingDown )
418 emit (threadSuspended ( event->thread() ) );
421 case Event::ThreadBusy:
422 if (!m_shuttingDown )
424 emit (threadBusy (event->thread() ) );
431 if ( event->job() !=0 )
433 event->job()->processEvent (event);
436 debug ( 0,
"Weaver::event: Strange: received unknown user event.\n" );
441 return TQObject::event ( e );
448 TQApplication::postEvent (
this, e);
453 TQMutexLocker l (m_mutex);
454 return m_assignments.count()==0;
460 bool lastjob =
false;
461 bool suspended =
false;
471 debug ( 3,
"Weaver::applyForWork: job done, %i jobs left, " 472 "%i active jobs left.\n",
473 queueLength(), m_active );
475 if ( m_active == 0 && isEmpty() )
479 post (Event::Finished);
480 debug ( 3,
"Weaver::applyForWork: last job.\n" );
483 if (m_active == 0 && m_suspend ==
true)
487 debug ( 2,
"Weaver::applyForWork: queueing suspended.\n" );
490 m_jobFinished.wakeOne();
495 if (m_shuttingDown ==
true)
501 if ( !isEmpty() && m_suspend ==
false )
503 rc = m_assignments.getFirst();
504 m_assignments.removeFirst ();
507 debug ( 3,
"Weaver::applyForWork: job assigned, " 508 "%i jobs in queue (%i active).\n",
509 m_assignments.count(), m_active );
512 post (Event::ThreadBusy, th);
518 post (Event::ThreadSuspended, th);
519 m_jobAvailable.wait();
527 TQMutexLocker l (m_mutex);
528 return m_assignments.count();
533 TQMutexLocker l (m_mutex);
534 return isEmpty() && m_active == 0;
541 debug (2,
"Weaver::finish: not done, waiting.\n" );
542 m_jobFinished.wait();
544 debug (1,
"Weaver::finish: done.\n\n\n" );
550 #include "weaver.moc" void started()
This signal is emitted when a thread starts to process a job.
virtual void execute(Thread *)
Perform the job.
A class to represent the events threads generate and send to the Weaver object.
virtual ~Job()
Destructor.
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...
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.
virtual bool isFinished() const
Returns true if the jobs's execute method finished.
All jobs in the queue are done.
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...
bool isEmpty() const
Is the queue empty?
Action action() const
The action.
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.
int threads() const
Returns the current number of threads in the inventory.
virtual void processEvent(Event *)
Process events related to this job (created by the processing thread or the weaver or whoever)...
Synchronous Process Request.
Thread * thread() const
The ID of the sender thread.
virtual void suspend(bool state)
Suspend job execution if state = true, otherwise resume job execution if it was suspended.
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.
unsigned int id() const
Returns the thread id.
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 isIdle() const
Is the weaver idle? The weaver is idle if no jobs are queued and no jobs are processed by the threads...
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.
static int type()
Return the (custom defined) event type.
void assignJobs()
Schedule enqueued jobs to be executed by idle threads.
Job * job() const
The associated job.