summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixel <Pixel>2001-10-30 17:38:54 +0000
committerPixel <Pixel>2001-10-30 17:38:54 +0000
commit57633137f749b0098eaf703f49ed00c96128966d (patch)
treef7e55be48d4724d44e5ed2362cf836162e866d05
parente5057005049b11af44cb804118f95370f03ab32c (diff)
Huge work on Tasking System.
-rw-r--r--include/CopyJob.h10
-rw-r--r--include/Exceptions.h23
-rw-r--r--include/HttpServ.h10
-rw-r--r--include/ReadJob.h8
-rw-r--r--include/Task.h12
-rw-r--r--lib/Buffer.cc2
-rw-r--r--lib/CopyJob.cc35
-rw-r--r--lib/Exceptions.cc20
-rw-r--r--lib/Handle.cc4
-rw-r--r--lib/HttpServ.cc43
-rw-r--r--lib/ReadJob.cc31
-rw-r--r--lib/Task.cc19
12 files changed, 154 insertions, 63 deletions
diff --git a/include/CopyJob.h b/include/CopyJob.h
index 69eb088..3c88100 100644
--- a/include/CopyJob.h
+++ b/include/CopyJob.h
@@ -5,13 +5,19 @@
#include <Task.h>
#include <Handle.h>
+#define COPY_BUFSIZ 4096
+
class CopyJob : public Task {
public:
- CopyJob(Handle &, Handle &);
+ CopyJob(Handle *, Handle *, ssize_t = -1);
virtual ~CopyJob();
virtual int Do();
+ virtual String GetName();
private:
- Handle s, d;
+ Handle * s, * d;
+ ssize_t siz, cursiz;
+ char buffer[COPY_BUFSIZ];
+ int current;
};
#else
diff --git a/include/Exceptions.h b/include/Exceptions.h
index 87ba6d1..f04970c 100644
--- a/include/Exceptions.h
+++ b/include/Exceptions.h
@@ -37,6 +37,7 @@ class MemoryException;
char * xstrdup(const char *) throw (MemoryException);
void * xmalloc(ssize_t) throw (MemoryException);
void xfree(void *&);
+void * xrealloc(void *, size_t) throw (MemoryException);
// On prédéfinit la classe String, pour éviter
// les deadlocks de compilation...
@@ -48,7 +49,10 @@ class Base {
return xstrdup(s);
}
void * malloc(ssize_t s) const {
- return malloc(s);
+ return xmalloc(s);
+ }
+ void * realloc(void * p, size_t s) {
+ return xrealloc(p, s);
}
void * operator new(size_t s) {
return xmalloc(s);
@@ -56,6 +60,9 @@ class Base {
void * operator new(size_t s, void * p) {
return memset(p, 0, s);
}
+ void operator delete(void * p) {
+ xfree(p);
+ }
void free(void * p) const {
xfree(p);
}
@@ -86,19 +93,21 @@ enum op_t {
IO_READ
};
-class IOException : public GeneralException {
+class IOGeneral : public GeneralException {
public:
- IOException(String, op_t, ssize_t);
+ IOGeneral(String);
+ protected:
+ IOGeneral();
};
-class IOGeneral : public GeneralException {
+class IOException : public IOGeneral {
public:
- IOGeneral(String);
+ IOException(String, op_t, ssize_t);
};
-class IOInternal : public GeneralException {
+class IOAgain : public IOGeneral {
public:
- IOInternal(String, op_t);
+ IOAgain();
};
#else
diff --git a/include/HttpServ.h b/include/HttpServ.h
index dc89104..6bd2769 100644
--- a/include/HttpServ.h
+++ b/include/HttpServ.h
@@ -24,11 +24,11 @@ class HttpServ : public Base {
private:
String GetMime(const String &);
void ProcessRequest(Action *, Socket);
- bool ParseUri(String &, String &, Handle &);
- void ParseVars(Handle &, int);
- void ShowError(Handle &);
- void SendHeads(Handle &, const String &);
- void SendRedirect(Handle &);
+ bool ParseUri(String &, String &, Handle *);
+ void ParseVars(Handle *, int);
+ void ShowError(Handle *);
+ void SendHeads(Handle *, const String &);
+ void SendRedirect(Handle *);
String name;
Socket Listener;
Variables * Vars;
diff --git a/include/ReadJob.h b/include/ReadJob.h
index 19009a6..2d53125 100644
--- a/include/ReadJob.h
+++ b/include/ReadJob.h
@@ -4,14 +4,18 @@
#include <Task.h>
#include <Handle.h>
+#include <regex.h>
class ReadJob : public Task {
public:
- ReadJob(Handle &, Handle &);
+ ReadJob(Handle *, Handle *, String = "^$", int = REG_EXTENDED);
virtual ~ReadJob();
virtual int Do();
+ virtual String GetName();
private:
- Handle s, d;
+ Handle * s, * d;
+ int current;
+ regex_t * preg;
};
#else
diff --git a/include/Task.h b/include/Task.h
index 12e3bff..c67a59c 100644
--- a/include/Task.h
+++ b/include/Task.h
@@ -4,19 +4,21 @@
#include "Exceptions.h"
-#define TASK_ON_HOLD 0
-#define TASK_DONE 1
-#define TASK_WAITING_HANDLE 2
-#define TASK_WAITING_TIMEOUT 3
+#define TASK_ON_HOLD 1
+#define TASK_DONE 2
+#define TASK_WAITING_HANDLE 4
+#define TASK_WAITING_TIMEOUT 8
+#define TASK_WAITING_TASK 16
class Task : public Base {
public:
Task();
virtual ~Task();
- virtual int Do();
+ virtual String GetName();
int Run();
int GetState();
protected:
+ virtual int Do();
private:
int state;
diff --git a/lib/Buffer.cc b/lib/Buffer.cc
index 164c961..57b1bf8 100644
--- a/lib/Buffer.cc
+++ b/lib/Buffer.cc
@@ -32,7 +32,7 @@ ssize_t Buffer::read(void *buf, size_t count) {
ptr += count;
if (ptr >= realloc_threshold) {
- int numblocks = (ptr / realloc_threshold) - (bufsiz / realloc_threshold);
+ int numblocks = (bufsiz / realloc_threshold) - (ptr / realloc_threshold);
memmove(buffer, buffer + numblocks * realloc_threshold, numblocks * realloc_threshold);
buffer = (char *) realloc(buffer, bufsiz = (numblocks * realloc_threshold));
ptr -= numblocks * realloc_threshold;
diff --git a/lib/CopyJob.cc b/lib/CopyJob.cc
index 7dccbc5..73864bb 100644
--- a/lib/CopyJob.cc
+++ b/lib/CopyJob.cc
@@ -1,15 +1,38 @@
#include "CopyJob.h"
+#include "General.h"
-CopyJob::CopyJob(Handle & as, Handle & ad) : s(as), d(ad) { }
+CopyJob::CopyJob(Handle * as, Handle * ad, ssize_t asiz) : s(as), d(ad), siz(asiz), cursiz(0), current(0) { }
CopyJob::~CopyJob() { }
int CopyJob::Do() {
- int r;
- char buffer[4096];
+ int r, tr;
- while (!s.IsClosed()) {
- r = s.read(buffer, 4096);
- d.write(buffer, r);
+ cerr << "CopyJob running...\n";
+
+ while (!s->IsClosed() || (siz != cursiz)) {
+ if (!current) {
+ tr = siz >= 0 ? siz - cursiz : COPY_BUFSIZ;
+ try {
+ r = s->read(buffer, MIN(COPY_BUFSIZ, tr));
+ }
+ catch (IOAgain) {
+ return TASK_WAITING_HANDLE;
+ }
+ current = 0;
+ }
+ try {
+ d->write(buffer, r);
+ }
+ catch (IOAgain) {
+ current = 1;
+ return TASK_WAITING_HANDLE;
+ }
+ cursiz += r;
}
}
+
+String CopyJob::GetName() {
+ return (String("CopyJob from ") + s->GetName() + " to " + d->GetName());
+}
+
diff --git a/lib/Exceptions.cc b/lib/Exceptions.cc
index eed138a..a4fca0f 100644
--- a/lib/Exceptions.cc
+++ b/lib/Exceptions.cc
@@ -32,14 +32,12 @@ IOException::IOException(String fn, op_t op, ssize_t s) {
msg = strdup(t);
}
-IOInternal::IOInternal(String fn, op_t op) {
- sprintf(t, _("Internal error: has occured while %s from %s: open for %s."), op == IO_WRITE ? _("writing") : _("reading"),
- fn.to_charp(), op == IO_WRITE ? _("reading") : _("writing"));
- msg = strdup(t);
-}
-
IOGeneral::IOGeneral(String fn) : GeneralException(fn) { }
+IOGeneral::IOGeneral() { }
+
+IOAgain::IOAgain() : IOGeneral(_("No more bytes for reading or writing.")) { }
+
char * xstrdup(const char * s) throw (MemoryException) {
char * r;
@@ -62,6 +60,16 @@ void * xmalloc(ssize_t s) throw (MemoryException) {
return r;
}
+void * xrealloc(void * ptr, size_t s) throw (MemoryException) {
+ void * r;
+
+ if (!(r = ::realloc(ptr, s))) {
+ throw MemoryException(s);
+ }
+
+ return r;
+}
+
#ifdef OVER_FREE
#undef free
#endif
diff --git a/lib/Handle.cc b/lib/Handle.cc
index 0f1791e..8ef2408 100644
--- a/lib/Handle.cc
+++ b/lib/Handle.cc
@@ -40,7 +40,7 @@ ssize_t Handle::write(const void *buf, size_t count) throw (IOException) {
done = false;
full = true;
if (nonblock) {
- return 0;
+ throw IOAgain();
} else {
sleep(1);
}
@@ -66,7 +66,7 @@ ssize_t Handle::read(void *buf, size_t count) throw (IOException) {
if ((!errno) || (errno = EAGAIN)) {
// Avant de déclarer une erreur, on vérifie si ce n'est pas un
// problème lié au fait qu'il n'y a plus d'octets.
- return 0;
+ throw IOAgain();
} else {
throw IOException(GetName(), IO_READ, count);
}
diff --git a/lib/HttpServ.cc b/lib/HttpServ.cc
index 69dff1e..9ec6ba3 100644
--- a/lib/HttpServ.cc
+++ b/lib/HttpServ.cc
@@ -22,11 +22,12 @@ void HttpServ::MainLoop(Action * p) {
void HttpServ::ProcessRequest(Action * p, Socket s) {
String file, domain, t;
Buffer b;
- ReadJob c(s, b);
+ Task * c = new ReadJob(&s, &b);
Action * f;
int len;
- c.Do();
+ c->Run();
+ delete c;
bad = false;
@@ -34,7 +35,7 @@ void HttpServ::ProcessRequest(Action * p, Socket s) {
cerr << "Got a request\n----\n";
- bool post = ParseUri(file, domain, b);
+ bool post = ParseUri(file, domain, &b);
len = -1;
do {
@@ -45,7 +46,7 @@ void HttpServ::ProcessRequest(Action * p, Socket s) {
len = t.extract(16).to_int();
}
} while (t.strlen());
-
+
if (post) {
// On a pas eu de ligne 'Content-Length' mais on a eu une méthode POST.
// Cela est une erreur.
@@ -55,7 +56,7 @@ void HttpServ::ProcessRequest(Action * p, Socket s) {
} else {
cerr << "Got a POST request. Parsing variables. (len = " << len << ")\n";
// Les variables seront initialisées ici.
- ParseVars(s, len);
+ ParseVars(&s, len);
}
} else {
Vars = new Variables(0);
@@ -78,19 +79,19 @@ void HttpServ::ProcessRequest(Action * p, Socket s) {
}
if (bad) {
- ShowError(s);
+ ShowError(&s);
} else {
if (((domain == "") || (domain == "/")) && (file == "")) {
// Si le navigateur a demandé l'URL '/', alors on renvoie une notification
// de redirection.
- SendRedirect(s);
+ SendRedirect(&s);
} else if (domain == "/bin") {
// Le domaine 'bin' est réservé aux actions. On cherche donc l'action à effectuer.
if ((f = p->Look4URL(file))) {
- SendHeads(s, "text/html");
+ SendHeads(&s, "text/html");
f->Do(Vars, &s);
} else {
- ShowError(s);
+ ShowError(&s);
}
} else {
// Dans tous les autres cas de domaine, on cherche le fichier dans le répertoire datas.
@@ -98,12 +99,12 @@ void HttpServ::ProcessRequest(Action * p, Socket s) {
// d'input renvoie une erreur.
try {
Input i(String("datas/") + file);
- SendHeads(s, GetMime(file));
+ SendHeads(&s, GetMime(file));
s.ReadFile(i);
cerr << "File found, dumped.\n";
}
catch (IOGeneral e) {
- ShowError(s);
+ ShowError(&s);
cerr << "File not found, error showed.\n";
}
}
@@ -114,7 +115,7 @@ void HttpServ::ProcessRequest(Action * p, Socket s) {
cerr << "----\n";
}
-void HttpServ::ParseVars(Handle & s, int len) {
+void HttpServ::ParseVars(Handle * s, int len) {
String t, v;
char conv[3], l;
int hconv, nbvars;
@@ -122,7 +123,7 @@ void HttpServ::ParseVars(Handle & s, int len) {
t = "";
for (int i = 0; i < len; i++) {
- s.read(&l, 1);
+ s->read(&l, 1);
t += l;
}
cerr << "Post variables line: '" <<t << "'\n";
@@ -174,13 +175,13 @@ void HttpServ::ParseVars(Handle & s, int len) {
* c'est à dire la méthode demandée par le client.
*/
-bool HttpServ::ParseUri(String & file, String & domain, Handle & s) {
+bool HttpServ::ParseUri(String & file, String & domain, Handle * s) {
String t, Uri;
bool post = false;
char * p = NULL;
ssize_t sppos;
- s >> t;
+ *s >> t;
cerr << t << endl;
bad = false;
@@ -233,8 +234,8 @@ bool HttpServ::ParseUri(String & file, String & domain, Handle & s) {
/*
* Ceci sert à rediriger le navigateur vers l'url de démarrage.
*/
-void HttpServ::SendRedirect(Handle & s) {
- s << "HTTP/1.1 301 Moved Permanently" << endhl <<
+void HttpServ::SendRedirect(Handle * s) {
+ *s << "HTTP/1.1 301 Moved Permanently" << endhl <<
"Server: " << name << endhl <<
"Location: http://127.0.0.1:" << localport << "/bin/start" << endhl <<
"Cache-Control: no-cache" << endhl <<
@@ -250,8 +251,8 @@ void HttpServ::SendRedirect(Handle & s) {
* Nous envoyons les entetes de réponse HTTP.
*/
-void HttpServ::SendHeads(Handle & s, const String & mime) {
- s << "HTTP/1.1 200 OK" << endhl <<
+void HttpServ::SendHeads(Handle * s, const String & mime) {
+ *s << "HTTP/1.1 200 OK" << endhl <<
"Server: " << name << endhl <<
"Cache-Control: no-cache" << endhl <<
"Connection-Type: closed" << endhl <<
@@ -262,8 +263,8 @@ void HttpServ::SendHeads(Handle & s, const String & mime) {
* Affichage d'une erreur 404.
*/
-void HttpServ::ShowError(Handle & s) {
- s << "HTTP/1.1 404 Not Found" << endhl <<
+void HttpServ::ShowError(Handle * s) {
+ *s << "HTTP/1.1 404 Not Found" << endhl <<
"Server: " << name << endhl <<
"Cache-Control: no-cache" << endhl <<
"Connection-Type: closed" << endhl <<
diff --git a/lib/ReadJob.cc b/lib/ReadJob.cc
index bd63377..d5b3212 100644
--- a/lib/ReadJob.cc
+++ b/lib/ReadJob.cc
@@ -1,6 +1,7 @@
#include "ReadJob.h"
+#include "HttpServ.h"
-ReadJob::ReadJob(Handle & as, Handle & ad) : s(as), d(ad) { }
+ReadJob::ReadJob(Handle * as, Handle * ad, String regex, int flags) : s(as), d(ad), current(0) { }
ReadJob::~ReadJob() { }
@@ -8,9 +9,31 @@ int ReadJob::Do() {
int r;
String buff;
- while (!s.IsClosed()) {
- s >> buff;
- d << buff;
+ cerr << "ReadJob running...\n";
+
+ while (!s->IsClosed()) {
+ if (!current) {
+ try {
+ *s >> buff;
+ }
+ catch (IOAgain) {
+ return TASK_WAITING_HANDLE;
+ }
+ current = 0;
+ }
+ try {
+ *d << buff << endnl;
+ }
+ catch (IOAgain) {
+ current = 1;
+ return TASK_WAITING_HANDLE;
+ }
if (buff == "") return TASK_DONE;
}
+
+ return TASK_DONE;
+}
+
+String ReadJob::GetName() {
+ return (String("ReadJob from ") + s->GetName() + " to " + d->GetName());
}
diff --git a/lib/Task.cc b/lib/Task.cc
index 79c39e1..27d2a24 100644
--- a/lib/Task.cc
+++ b/lib/Task.cc
@@ -1,6 +1,8 @@
+#include <iostream.h>
#include "Task.h"
+#include "String.h"
-Task::Task() {}
+Task::Task() : state(TASK_ON_HOLD) {}
Task::~Task() {}
int Task::Do() {
@@ -8,9 +10,22 @@ int Task::Do() {
}
int Task::Run() {
- return (state = Do());
+ cerr << "Running task '" << GetName() << "'...\n";
+ try {
+ while ((state = Do()) != TASK_DONE);
+ }
+ catch (GeneralException e) {
+ cerr << "Task " << GetName() << " caused an unexpected exception: '" << e.GetMsg() << "', closing it.\n";
+ return TASK_DONE;
+ }
+
+ return state;
}
int Task::GetState() {
return state;
}
+
+String Task::GetName() {
+ return "Unknow Task";
+}