summaryrefslogtreecommitdiff
path: root/src/Main.cc
diff options
context:
space:
mode:
authorNicolas "Pixel" Noble <pixel@nobis-crew.org>2013-08-02 10:04:38 +0200
committerNicolas "Pixel" Noble <pixel@nobis-crew.org>2013-08-02 10:22:15 +0200
commit6d956657c4612e988f89a133cea93e50ec2dcb39 (patch)
treee5f360dd667145934141549fad1866e61b87e5bf /src/Main.cc
parent7f4f068ebdfd51c358648e514660b23d586d4929 (diff)
Adding AtStartAsTask and AtExitAsTask concepts.
Diffstat (limited to 'src/Main.cc')
-rw-r--r--src/Main.cc97
1 files changed, 96 insertions, 1 deletions
diff --git a/src/Main.cc b/src/Main.cc
index 7c205d4..e872411 100644
--- a/src/Main.cc
+++ b/src/Main.cc
@@ -2,9 +2,12 @@
#include "TaskMan.h"
#include "Printer.h"
#include "AtStartExit.h"
+#include "StacklessTask.h"
Balau::AtStart * Balau::AtStart::s_head = 0;
Balau::AtExit * Balau::AtExit::s_head = 0;
+Balau::AtStartAsTask * Balau::AtStartAsTask::s_head = 0;
+Balau::AtExitAsTask * Balau::AtExitAsTask::s_head = 0;
Balau::AtStart::AtStart(int priority) : m_priority(priority) {
if (priority < 0)
@@ -36,6 +39,36 @@ Balau::AtExit::AtExit(int priority) : m_priority(priority) {
*ptr = this;
}
+Balau::AtStartAsTask::AtStartAsTask(int priority) : m_priority(priority) {
+ if (priority < 0)
+ return;
+ AAssert(!Main::hasMain(), "An AtStartAsTask can't be created dynamically");
+
+ AtStartAsTask ** ptr = &s_head;
+
+ m_next = 0;
+
+ for (ptr = &s_head; *ptr && (priority > (*ptr)->m_priority); ptr = &((*ptr)->m_next));
+
+ m_next = *ptr;
+ *ptr = this;
+}
+
+Balau::AtExitAsTask::AtExitAsTask(int priority) : m_priority(priority) {
+ if (priority < 0)
+ return;
+ AAssert(!Main::hasMain(), "An AtExitAsTask can't be created dynamically");
+
+ AtExitAsTask ** ptr = &s_head;
+
+ m_next = 0;
+
+ for (ptr = &s_head; *ptr && (priority > (*ptr)->m_priority); ptr = &((*ptr)->m_next));
+
+ m_next = *ptr;
+ *ptr = this;
+}
+
Balau::Main * Balau::Main::s_application = NULL;
Balau::MainTask::~MainTask() {
@@ -47,6 +80,68 @@ const char * Balau::MainTask::getName() const {
return "Main Task";
}
+namespace Balau {
+
+class BootstrapTask : public StacklessTask {
+ public:
+ BootstrapTask(int argc, char ** argv, char ** enve) : m_argc(argc), m_argv(argv), m_enve(enve) { }
+ virtual void Do() {
+ Balau::Task * t;
+ try {
+ switch (m_state) {
+ case 0:
+ m_ptrStart = AtStartAsTask::s_head;
+ m_ptrExit = AtExitAsTask::s_head;
+ m_state = 1;
+ case 1:
+ if (m_ptrStart) {
+ t = m_ptrStart->createStartTask();
+ if (m_waiting)
+ m_evt.ack();
+ m_evt.attachToTask(t);
+ m_waiting = true;
+ waitFor(&m_evt);
+ TaskMan::registerTask(t);
+ m_ptrStart = m_ptrStart->m_next;
+ yield();
+ }
+ m_state = 2;
+ t = new MainTask(m_argc, m_argv, m_enve);
+ if (m_waiting)
+ m_evt.ack();
+ m_evt.attachToTask(t);
+ waitFor(&m_evt);
+ TaskMan::registerTask(t);
+ yield();
+ case 2:
+ if (m_ptrExit) {
+ t = m_ptrExit->createExitTask();
+ m_evt.ack();
+ m_evt.attachToTask(t);
+ waitFor(&m_evt);
+ TaskMan::registerTask(t);
+ m_ptrExit = m_ptrExit->m_next;
+ yield();
+ }
+ }
+ }
+ catch (EAgain &) {
+ taskSwitch();
+ }
+ }
+ private:
+ virtual const char * getName() const { return "BootstrapTask"; }
+ int m_argc;
+ char ** m_argv;
+ char ** m_enve;
+ AtStartAsTask * m_ptrStart = NULL;
+ AtExitAsTask * m_ptrExit = NULL;
+ Events::TaskEvent m_evt;
+ bool m_waiting = false;
+};
+
+};
+
int Balau::Main::bootstrap(int argc, char ** argv) {
int r = 0;
m_status = STARTING;
@@ -56,7 +151,7 @@ int Balau::Main::bootstrap(int argc, char ** argv) {
try {
m_status = RUNNING;
- TaskMan::registerTask(new MainTask(argc, argv, NULL));
+ TaskMan::registerTask(new BootstrapTask(argc, argv, NULL));
r = TaskMan::getDefaultTaskMan()->mainLoop();
m_status = STOPPING;
}