summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/CopyJob.h2
-rw-r--r--include/ReadJob.h2
-rw-r--r--include/Task.h11
-rw-r--r--include/TaskMan.h2
-rw-r--r--lib/CopyJob.cc22
-rw-r--r--lib/ReadJob.cc33
-rw-r--r--lib/Task.cc10
-rw-r--r--lib/TaskMan.cc45
8 files changed, 81 insertions, 46 deletions
diff --git a/include/CopyJob.h b/include/CopyJob.h
index 3c88100..a4f4bca 100644
--- a/include/CopyJob.h
+++ b/include/CopyJob.h
@@ -11,7 +11,7 @@ class CopyJob : public Task {
public:
CopyJob(Handle *, Handle *, ssize_t = -1);
virtual ~CopyJob();
- virtual int Do();
+ virtual int Do() throw (GeneralException);
virtual String GetName();
private:
Handle * s, * d;
diff --git a/include/ReadJob.h b/include/ReadJob.h
index 4822390..90ba2c8 100644
--- a/include/ReadJob.h
+++ b/include/ReadJob.h
@@ -10,7 +10,7 @@ class ReadJob : public Task {
public:
ReadJob(Handle *, Handle *);
virtual ~ReadJob();
- virtual int Do();
+ virtual int Do() throw (GeneralException);
virtual String GetName();
private:
Handle * s, * d;
diff --git a/include/Task.h b/include/Task.h
index f728e62..675b2ed 100644
--- a/include/Task.h
+++ b/include/Task.h
@@ -5,6 +5,7 @@
#include <unistd.h>
#include <vector.h>
#include <Exceptions.h>
+#include <Handle.h>
#define TASK_ON_HOLD 0
#define TASK_DONE 1
@@ -17,12 +18,12 @@ class Task : public Base {
int Run();
int GetState();
void Suspend() throw (GeneralException);
- bool WaitFor(Handle *);
- bool WaitFor(Task *);
- bool WaitFor(pid_t);
- bool WaitFor(struct timeval);
+ void WaitFor(Handle *);
+ void WaitFor(Task *);
+ void WaitFor(pid_t);
+ void WaitFor(struct timeval);
protected:
- virtual int Do();
+ virtual int Do() throw (GeneralException);
private:
int state;
diff --git a/include/TaskMan.h b/include/TaskMan.h
index 03797af..dc8c913 100644
--- a/include/TaskMan.h
+++ b/include/TaskMan.h
@@ -9,6 +9,8 @@ class TaskMan : public Base {
public:
TaskMan() throw (GeneralException);
int AddTask(Task *);
+ int TaskMan::RemoveTask(Task *);
+ void Init() throw (GeneralException);
void MainLoop() throw (GeneralException);
private:
vector<Task *> TaskList;
diff --git a/lib/CopyJob.cc b/lib/CopyJob.cc
index f1d3310..e46e3da 100644
--- a/lib/CopyJob.cc
+++ b/lib/CopyJob.cc
@@ -5,27 +5,29 @@ CopyJob::CopyJob(Handle * as, Handle * ad, ssize_t asiz) : s(as), d(ad), siz(asi
CopyJob::~CopyJob() { }
-int CopyJob::Do() {
+int CopyJob::Do() throw (GeneralException) {
int r, tr;
while (!s->IsClosed() || (siz != cursiz)) {
- if (!current) {
+ switch (current) {
+ case 0:
tr = siz >= 0 ? siz - cursiz : COPY_BUFSIZ;
try {
r = s->read(buffer, MIN(COPY_BUFSIZ, tr));
}
catch (IOAgain e) {
- return TASK_ON_HOLD;
+ throw TaskSwitch();
+ }
+ case 1:
+ try {
+ d->write(buffer, r);
+ }
+ catch (IOAgain e) {
+ current = 1;
+ throw TaskSwitch();
}
current = 0;
}
- try {
- d->write(buffer, r);
- }
- catch (IOAgain e) {
- current = 1;
- return TASK_ON_HOLD;
- }
cursiz += r;
}
}
diff --git a/lib/ReadJob.cc b/lib/ReadJob.cc
index a63eeca..2c244ad 100644
--- a/lib/ReadJob.cc
+++ b/lib/ReadJob.cc
@@ -5,37 +5,36 @@ ReadJob::ReadJob(Handle * as, Handle * ad) : s(as), d(ad), current(0) { }
ReadJob::~ReadJob() { }
-int ReadJob::Do() {
- int r;
+int ReadJob::Do() throw (GeneralException) {
String buff;
cerr << "ReadJob running...\n";
while (!s->IsClosed()) {
- if (!current) {
- r = 0;
+ switch (current) {
+ case 0:
try {
cerr << "Trying to read...\n";
*s >> buff;
}
catch (IOAgain e) {
cerr << "Suspending ReadJob to wait for reading...\n";
- r = 1;
+ throw TaskSwitch();
}
- if (r) Suspend();
cerr << "Read some bytes...\n";
+ case 1:
+ try {
+ *d << buff << endnl;
+ }
+ catch (IOAgain e) {
+ cerr << "Suspending ReadJob to wait for writing...\n";
+ current = 1;
+ throw TaskSwitch();
+ }
+ current = 0;
+ cerr << "Wrote some bytes...\n";
+ if (buff == "") return TASK_DONE;
}
- r = 0;
- try {
- *d << buff << endnl;
- }
- catch (IOAgain e) {
- cerr << "Suspending ReadJob to wait for writing...\n";
- r = 1;
- }
- if (r) Suspend();
- cerr << "Wrote some bytes...\n";
- if (buff == "") return TASK_DONE;
}
return TASK_DONE;
diff --git a/lib/Task.cc b/lib/Task.cc
index 2db8ce5..338eaba 100644
--- a/lib/Task.cc
+++ b/lib/Task.cc
@@ -5,7 +5,7 @@
Task::Task() : state(TASK_ON_HOLD), suspended(false) {}
Task::~Task() {}
-int Task::Do() {
+int Task::Do() throw (GeneralException) {
return TASK_ON_HOLD;
}
@@ -43,18 +43,18 @@ void Task::Suspend() throw (GeneralException) {
throw TaskSwitch();
}
-void WaitFor(Handle * h) {
+void Task::WaitFor(Handle * h) {
w4ha.push_back(h);
}
-void WaitFor(Task * t) {
+void Task::WaitFor(Task * t) {
w4ta.push_back(t);
}
-void WaitFor(pid_t p) {
+void Task::WaitFor(pid_t p) {
w4pr.push_back(p);
}
-void WaitFor(struct timeval t) {
+void Task::WaitFor(struct timeval t) {
w4to.push_back(t);
}
diff --git a/lib/TaskMan.cc b/lib/TaskMan.cc
index 9abffb1..6a38491 100644
--- a/lib/TaskMan.cc
+++ b/lib/TaskMan.cc
@@ -1,13 +1,19 @@
#include <signal.h>
+#include <wait.h>
+#include <vector.h>
#include "TaskMan.h"
bool TaskMan::inited = false;
-static got_sigchild = 0;
+static int got_sigchild = 0;
+static vector<pid_t> process;
+static int nbprocess = 0;
void taskman_sigchild(int sig) {
got_sigchild = 1;
- signal(SIGCHILD, taskman_sigchild);
+ process.push_back(wait(NULL));
+ signal(SIGCHLD, taskman_sigchild);
+ nbprocess++;
}
TaskMan::TaskMan() throw (GeneralException) {
@@ -19,7 +25,7 @@ void TaskMan::Init() throw (GeneralException) {
throw GeneralException("Task Manager already initialised.");
}
- signal(SIGCHILD, taskman_sigchild);
+ signal(SIGCHLD, taskman_sigchild);
inited = true;
number = 0;
@@ -37,7 +43,7 @@ int TaskMan::RemoveTask(Task * t) {
for (i = 0; i < number; i++) {
if (TaskList[i] == t) {
- TaskList.erase(i);
+ TaskList.erase(&TaskList[i]);
number--;
return 0;
}
@@ -46,14 +52,39 @@ int TaskMan::RemoveTask(Task * t) {
}
void TaskMan::MainLoop() throw (GeneralException) {
+ Task ** p, * t;
+
while (1) {
if (number == 0) {
throw GeneralException("TaskMan: No more task to manage.");
}
-
-#ifdef HAVE_POLL
+ p = TaskList.begin();
+
+ while (1) {
+ t = *p;
+
+#ifdef HAVE_POLL
#else
-#endif
+#endif
+
+ try {
+ t->Do();
+ }
+ catch (TaskSwitch) {
+ continue;
+ }
+ if (t->GetState() == TASK_DONE) {
+ TaskList.erase(p);
+ }
+
+ if (p == TaskList.end()) {
+ break;
+ }
+
+ p++;
+ }
+
+
}
}