diff options
Diffstat (limited to 'lib/TaskMan.cc')
-rw-r--r-- | lib/TaskMan.cc | 65 |
1 files changed, 54 insertions, 11 deletions
diff --git a/lib/TaskMan.cc b/lib/TaskMan.cc index 83fe5aa..fd630d8 100644 --- a/lib/TaskMan.cc +++ b/lib/TaskMan.cc @@ -51,6 +51,8 @@ Handle * TaskMan::ehandle; sigset_t TaskMan::sigchildset; +Atomic::Queue<Task> TaskMan::new_tasks; + #ifndef _WIN32 void taskman_sigchild(int sig) { TaskMan::SigChild(); @@ -382,9 +384,16 @@ void TaskMan::AddTask(Task * t) { Init(); } - if (t) { - TaskList.push_back(t); - number++; + if (t) + new_tasks.enqueue(t); +} + +void TaskMan::ProcessNewTasks() { + Task * t; + + while(new_tasks.unqueue(&t)) { + TaskList.push_back(t); + number++; } } @@ -524,13 +533,14 @@ void TaskMan::MainLoop() throw (GeneralException) { struct pollfd * ufsd; unsigned int nfds; - int no_burst; + bool no_burst, no_idle; if (!inited) { Init(); } - - while (1) { + + while (true) { + ProcessNewTasks(); if (number == 0) { throw GeneralException(_("TaskMan: No more task to manage.")); } @@ -545,15 +555,17 @@ void TaskMan::MainLoop() throw (GeneralException) { if (!TaskList.empty()) { for (TaskList_t::iterator p = TaskList.begin(); p != TaskList.end(); p++) { Task * t = *p; + if (t->GetState() == Task::TASK_IDLE_REST) + t->SetIdle(); // cerr << "-=- TaskMan: task " << t->GetName() << endl; } } // cerr << "-=- TaskMan: processing burning tasks.\n"; - no_burst = 0; + no_burst = false; while (!no_burst) { - no_burst = 1; + no_burst = true; /* First, we will check for any burning task and run 'em */ event = Task::EVT_BURST; if (!TaskList.empty()) { @@ -578,7 +590,38 @@ void TaskMan::MainLoop() throw (GeneralException) { t->BurstHandle = 0; } /* if the task added some new tasks, we have to rerun the loop */ - no_burst = 0; + no_burst = false; + break; + } + + // Additionnally, if the task died, let's put it in the zombies list. + // This check is done on the whole TaskList at each loop. + if (CheckDead(t)) + p = TaskList.begin(); + } + } + } + + no_idle = false; + while (!no_idle) { + no_idle = true; + /* First, we will check for any idle task and run 'em */ + event = Task::EVT_IDLE; + if (!TaskList.empty()) { + for (TaskList_t::iterator p = TaskList.begin(); p != TaskList.end(); p++) { + Task * t = *p; + + if (t->IsStopped()) { + continue; + } + + if (t->GetState() == Task::TASK_IDLE) { +// cerr << "-=- TaskMan: running idle task " << t->GetName() << endl; + t->Run(); + /* if the task added some new tasks, we have to rerun the loop */ + no_idle = false; + /* and toggle the task so it's not running through the loop again. */ + t->IdleRest(); break; } @@ -647,7 +690,7 @@ void TaskMan::MainLoop() throw (GeneralException) { event = Task::EVT_HANDLE; nfds = w4ha.size(); - no_burst = 1; + no_burst = true; if (nfds != 0) { int r; @@ -672,7 +715,7 @@ void TaskMan::MainLoop() throw (GeneralException) { // considering it already processed for this handle loop. // It'll be run immediately next cycle. p->T->SetBurst(); - no_burst = 0; + no_burst = false; p->dirty = true; q->fd = 0; q->events = 0; |