diff options
-rw-r--r-- | include/CopyJob.h | 2 | ||||
-rw-r--r-- | include/ReadJob.h | 2 | ||||
-rw-r--r-- | include/Task.h | 11 | ||||
-rw-r--r-- | include/TaskMan.h | 2 | ||||
-rw-r--r-- | lib/CopyJob.cc | 22 | ||||
-rw-r--r-- | lib/ReadJob.cc | 33 | ||||
-rw-r--r-- | lib/Task.cc | 10 | ||||
-rw-r--r-- | lib/TaskMan.cc | 45 |
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++; + } + + } } |