diff options
-rw-r--r-- | include/Exceptions.h | 2 | ||||
-rw-r--r-- | include/Task.h | 5 | ||||
-rw-r--r-- | include/TaskMan.h | 8 | ||||
-rw-r--r-- | lib/Handle.cc | 2 | ||||
-rw-r--r-- | lib/ReadJob.cc | 10 | ||||
-rw-r--r-- | lib/Task.cc | 27 | ||||
-rw-r--r-- | lib/TaskMan.cc | 12 |
7 files changed, 52 insertions, 14 deletions
diff --git a/include/Exceptions.h b/include/Exceptions.h index 6862036..04b30d6 100644 --- a/include/Exceptions.h +++ b/include/Exceptions.h @@ -115,6 +115,8 @@ class TaskSwitch : public GeneralException { TaskSwitch(); }; +#include <String.h> + #else #error This only works with a C++ compiler #endif diff --git a/include/Task.h b/include/Task.h index f2fe722..4de3fa5 100644 --- a/include/Task.h +++ b/include/Task.h @@ -2,6 +2,7 @@ #define __TASK_H__ #ifdef __cplusplus +#include <setjmp.h> #include "Exceptions.h" #define TASK_ON_HOLD 0 @@ -14,11 +15,15 @@ class Task : public Base { virtual String GetName(); int Run(); int GetState(); + int Suspend() throw (GeneralException); + void Resume(int) throw (GeneralException); protected: virtual int Do(); private: + jmp_buf env; int state; + bool suspended; }; #else diff --git a/include/TaskMan.h b/include/TaskMan.h index ca1cdb8..1efff93 100644 --- a/include/TaskMan.h +++ b/include/TaskMan.h @@ -7,13 +7,13 @@ class TaskMan : public Base { public: - TaskMan(); + TaskMan() throw (GeneralException); ~TaskMan(); - int AddTask(const Task &); + int AddTask(Task *); void MainLoop(); private: - vector<Task> TaskList; - static int Inited; + vector<Task *> TaskList; + static bool Inited; }; #else diff --git a/lib/Handle.cc b/lib/Handle.cc index e5a23a3..da9870f 100644 --- a/lib/Handle.cc +++ b/lib/Handle.cc @@ -108,8 +108,6 @@ Handle & operator>>(Handle & h, String & s) { char t[BUFSIZ]; int i = 0, r; - cerr << "Into 'Handle & >> String &'...\n"; - while ((r = h.read(&(t[i]), 1)) && (i != (BUFSIZ - 1))) { // Il y a souvent des \r\n dans les sockets par exemple, // ou bien en lisant des fichiers au format MS-DOS. On diff --git a/lib/ReadJob.cc b/lib/ReadJob.cc index c2a4629..3bab150 100644 --- a/lib/ReadJob.cc +++ b/lib/ReadJob.cc @@ -18,17 +18,19 @@ int ReadJob::Do() { *s >> buff; } catch (IOAgain e) { - return TASK_ON_HOLD; + cerr << "Suspending ReadJob to wait for reading...\n"; + Suspend(); } - current = 0; + cerr << "Read some bytes...\n"; } try { *d << buff << endnl; } catch (IOAgain e) { - current = 1; - return TASK_ON_HOLD; + cerr << "Suspending ReadJob to wait for writing...\n"; + Suspend(); } + cerr << "Wrote some bytes...\n"; if (buff == "") return TASK_DONE; } diff --git a/lib/Task.cc b/lib/Task.cc index faaeaf3..42147d3 100644 --- a/lib/Task.cc +++ b/lib/Task.cc @@ -2,7 +2,7 @@ #include "Task.h" #include "String.h" -Task::Task() : state(TASK_ON_HOLD) {} +Task::Task() : state(TASK_ON_HOLD), suspended(false) {} Task::~Task() {} int Task::Do() { @@ -15,6 +15,7 @@ int Task::Run() { state = Do(); } catch (TaskSwitch) { + Resume(1); throw; } catch (GeneralException e) { @@ -32,3 +33,27 @@ int Task::GetState() { String Task::GetName() { return "Unknow Task"; } + +int Task::Suspend() throw (GeneralException) { + int r; + + cerr << "Suspending task " << GetName() << "...\n"; + + suspended = true; + + r = setjmp(env); + + if (!r) throw TaskSwitch(); + + return r; +} + +void Task::Resume(int val) throw (GeneralException) { + if (suspended) { + cerr << "Resuming task " << GetName() << "...\n"; + suspended = false; + longjmp(env, val); + } else { + throw GeneralException(String("Task ") + GetName() + " was not suspended."); + } +} diff --git a/lib/TaskMan.cc b/lib/TaskMan.cc index 9efe890..f8ba303 100644 --- a/lib/TaskMan.cc +++ b/lib/TaskMan.cc @@ -1,10 +1,16 @@ #include <TaskMan.h> -int TaskMan::Inited = 0; +bool TaskMan::Inited = false; -TaskMan::TaskMan() { } +TaskMan::TaskMan() throw (GeneralException) { + if (Inited) { + throw GeneralException("Another Task Manager is already running, aborting."); + } + + Inited = true; +} -int TaskMan::AddTask(const Task & t) { +int TaskMan::AddTask(Task * t) { } |