From 57633137f749b0098eaf703f49ed00c96128966d Mon Sep 17 00:00:00 2001 From: Pixel Date: Tue, 30 Oct 2001 17:38:54 +0000 Subject: Huge work on Tasking System. --- lib/Buffer.cc | 2 +- lib/CopyJob.cc | 35 +++++++++++++++++++++++++++++------ lib/Exceptions.cc | 20 ++++++++++++++------ lib/Handle.cc | 4 ++-- lib/HttpServ.cc | 43 ++++++++++++++++++++++--------------------- lib/ReadJob.cc | 31 +++++++++++++++++++++++++++---- lib/Task.cc | 19 +++++++++++++++++-- 7 files changed, 112 insertions(+), 42 deletions(-) (limited to 'lib') 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; + *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 #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"; +} -- cgit v1.2.3