From 1b7a57d7f88cab0a1968e8c886eac3629dc74617 Mon Sep 17 00:00:00 2001 From: Pixel Date: Thu, 17 Nov 2011 18:41:23 -0800 Subject: HTTP server's first real test, alongside multiple taskmanager threads. I'm not really sure I fully like the way I'm designing this, but I guess it could be solved with an HTTP/HTML helper class around the Action class. However, the HTTP server awfully need reference counting, so it doesn't go away before all of the workers disappear, which means a bit of a redesign of the Listener template. --- includes/BRegex.h | 6 ++++++ includes/HttpServer.h | 33 +++++++++++++++++++++++++++++++++ includes/TaskMan.h | 1 + 3 files changed, 40 insertions(+) (limited to 'includes') diff --git a/includes/BRegex.h b/includes/BRegex.h index 128597e..d7957bd 100644 --- a/includes/BRegex.h +++ b/includes/BRegex.h @@ -19,4 +19,10 @@ class Regex { regex_t m_regex; }; +class Regexes { + public: + static Regex any; + static Regex empty; +}; + }; diff --git a/includes/HttpServer.h b/includes/HttpServer.h index 7ae0dc1..2226d23 100644 --- a/includes/HttpServer.h +++ b/includes/HttpServer.h @@ -1,7 +1,14 @@ #pragma once +#include +#include + +#include #include +#include #include +#include +#include namespace Balau { @@ -9,17 +16,43 @@ class HttpWorker; class HttpServer { public: + + typedef std::map StringMap; + typedef std::map > FileList; + + class Action { + public: + Action(Regex & regex, Regex & host = Regexes::any) : m_regex(regex), m_host(host), m_refCount(0) { } + ~Action() { Assert(m_refCount == 0); } + typedef std::pair ActionMatches; + ActionMatches matches(const char * uri, const char * host); + void unref() { if (Atomic::Prefetch::Decrement(&m_refCount) == 0) delete this; } + void ref() { Atomic::Increment(&m_refCount); } + void registerMe(HttpServer * server) { server->registerAction(this); } + virtual bool Do(HttpServer * server, ActionMatches & m, IO out, StringMap & vars, StringMap & headers, FileList & files) = 0; + private: + Regex m_regex, m_host; + volatile int m_refCount; + }; + HttpServer() : m_started(false), m_listenerPtr(NULL), m_port(80) { } ~HttpServer() { if (!m_started) stop(); } void start(); void stop(); void setPort(int port) { Assert(!m_started); m_port = port; } void setLocal(const char * local) { Assert(!m_started); m_local = local; } + void registerAction(Action * action); + void flushAllActions(); + typedef std::pair ActionFound; + ActionFound findAction(const char * uri, const char * host); private: bool m_started; void * m_listenerPtr; int m_port; String m_local; + typedef std::list ActionList; + ActionList m_actions; + Lock m_actionsLock; friend class HttpWorker; }; diff --git a/includes/TaskMan.h b/includes/TaskMan.h index c63695a..026ea88 100644 --- a/includes/TaskMan.h +++ b/includes/TaskMan.h @@ -33,6 +33,7 @@ class TaskMan { void signalTask(Task * t); static void stop(); void stopMe() { m_stopped = true; } + static Thread * createThreadedTaskMan(); private: static void registerTask(Task * t, Task * stick); void * getStack(); -- cgit v1.2.3