summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Action.cc3
-rw-r--r--lib/Task.cc76
-rw-r--r--lib/TaskMan.cc65
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;