diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Action.cc | 3 | ||||
-rw-r--r-- | lib/Task.cc | 76 | ||||
-rw-r--r-- | lib/TaskMan.cc | 65 |
3 files changed, 56 insertions, 88 deletions
diff --git a/lib/Action.cc b/lib/Action.cc index b15ad52..33b0b36 100644 --- a/lib/Action.cc +++ b/lib/Action.cc @@ -23,6 +23,7 @@ #include "BString.h" #include "Action.h" #include "HttpServ.h" +#include "Atomic.h" Action * Action::start = 0; @@ -35,7 +36,7 @@ static String genurl(const String & u) { } else { // Si l'url passée en paramètre est vide, on génère une URL // sous la forme TmpXXXX où XXXX est une valeur qui s'incrémente. - return String("Tmp") + (counter++); + return String("Tmp") + Atomic::Prefetch::Increment(&counter); } } diff --git a/lib/Task.cc b/lib/Task.cc index 9dc28ed..51be838 100644 --- a/lib/Task.cc +++ b/lib/Task.cc @@ -29,10 +29,6 @@ #include "BString.h" #include "gettext.h" -Task::Task() : current(0), state(TASK_ON_HOLD), stopped(false), suspended(false), yielded(false), wbta(0), wta(0), BurstHandle(0) { - TaskMan::AddTask(this); -} - Task::~Task() { TaskMan::RemoveFromWatches(this); TaskMan::RemoveTimeout(this); @@ -42,10 +38,6 @@ Task::~Task() { wta->wbta = 0; } -int Task::Do() throw (GeneralException) { - return TASK_ON_HOLD; -} - int Task::Run() { if (TaskMan::Event() == Task::EVT_TASK) wta = 0; @@ -80,14 +72,6 @@ int Task::DryRun() { return state; } -int Task::GetState() { - return state; -} - -String Task::GetName() { - return _("Unknow Task"); -} - void Task::Suspend(int newstate) throw (GeneralException) { if (newstate != -1) { state = newstate; @@ -95,63 +79,3 @@ void Task::Suspend(int newstate) throw (GeneralException) { suspended = true; throw TaskSwitch(); } - -void Task::WaitFor(Handle * h, int flags) { - h->SetNonBlock(); - TaskMan::WaitFor(h, this, flags); -} - -void Task::WaitFor(Task * t) { - t->wbta = this; - wta = t; -} - -void Task::WaitFor(pid_t p) { - TaskMan::WaitFor(p, this); -} - -void Task::WaitFor(const timeval & t, int flags) { - TaskMan::WaitFor(t, this, flags); -} - -void Task::Yield() { - yielded = true; - Suspend(TASK_ON_HOLD); -} - -bool Task::Yielded() { - return yielded; -} - -void Task::Unyield() { - yielded = false; - SetBurst(); -} - -void Task::SetBurst() { - state = TASK_BURST; -} - -void Task::Stop() { - stopped = true; -} - -void Task::Restart() { - stopped = false; -} - -bool Task::IsStopped() { - return stopped; -} - -Task * Task::WaitedBy() { - return wbta; -} - -void Task::RemoveFromWatches() { - wbta = 0; -} - -void Task::RemoveTimeout() { - TaskMan::RemoveTimeout(this); -} 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; |