virtual Connection *newConnection(int fd) const = 0;
virtual Connection *accept(int fd) const = 0;
- virtual ~Factory() = 0;
+ virtual ~Factory();
};
class Endpoint {
#include <list>
-#include "Singleton.H"
// interface
-// type for return code of event handler
-typedef enum {
- NOT_HANDLED, // the event was not handled at all
- HANDLED, // the event was handled succesfully
- HANDLED_FINAL // the event was handled,
- // no other handlers should be called
-} eventstatus_t;
-
-
class Event {
};
-template<class T>
+template <class THandler, class TEvent>
class EventHandler {
public:
- virtual eventstatus_t handleEvent(T *&e);
-};
-
-
-template <class T>
-class EventManagerForType: public Singleton< EventManagerForType<T> > {
-public:
+ typedef int (THandler::*EventHandlerType)(TEvent* &);
-protected:
- void registerHandler(EventHandler<T> *);
- void registerHandlerFirst(EventHandler<T> *);
+
private:
-
+ std::list<EventHandlerType> m_handlers;
};
-class EventManager: public Singleton<EventManager> {
+class EventManager {
public:
- eventstatus_t postEvent(Event *);
-
- template<class T>
- void registerHandler(EventHandler<T> *h) {
- EventManagerForType<T>::instance()->registerHandler(h);
- }
+ // constants for event handler return codes
+ static const int NOT_HANDLED = 0;
+ static const int HANDLED = 1;
+ static const int HANDLED_FINAL = 2;
+ static const int HANDLED_NEW = 3;
+ int postEvent(Event* &event);
+
template<class T>
- void registerHandlerFirst(EventHandler<T> *) {
- EventManagerForType<T>::instance()->registerHandlerFirst(h);
- }
-
-protected:
- EventManager()
- {}
-
- virtual ~EventManager()
- {}
+ registerHandler(, int priority);
private:
-
+ std::list<
};
-
// implementation
#endif
--- /dev/null
+#include "EventManager.H"
+
#include "ThreadPool.H"
#include "Transport.H"
+#include "Singleton.H"
#include <string>
public Transport
{
public:
- class Factory: public Transport::Factory {
+ class Factory: public Transport::Factory,
+ public Singleton<HTTPTransport::Factory> {
public:
virtual Transport *newTransport(Connection *conn) const {
if(conn)
}
};
- static Factory theFactory;
-
HTTPTransport(Connection *conn)
: Transport(conn),
state(NONE),
#include "HTTPTransport.H"
#include "Exception.H"
+#include "EventManager.H"
#include <iostream>
#include <string.h>
-HTTPTransport::Factory HTTPTransport::theFactory;
-
-
HTTPTransport::~HTTPTransport()
{
if(body) free(body);
len = conn->read(pos, sizeof(buffer) - (pos - buffer));
if(len < 0) {
// error during request
+ // XXX - handle this
state = NONE;
} else if(len == 0) {
// other side closed connection
+ // XXX - handle this
state = NONE;
} else {
char *cr = NULL, *p = buffer, *s = buffer;
}
} else {
// report error
+ // XXX - this may happen, do not handle using exceptions
std::cout << "Wrong content length" << std::endl;
throw new Exception();
}
state = NONE;
} else {
pos += len;
- if(pos - body == content_length) {
+ if(pos == content_length + body) {
// finished reading
state = NONE;
}
if(state != NONE)
ThreadPool::instance()->queueWorkRead(this);
else {
+ // we have a new message
+ // XXX - or we have an error, must handle it
std::cout << request << std::endl << headers << std::endl;
std::cout.write(body, content_length);
std::cout.flush();
+ res = EventManager::instance()->postEvent(new NewMessageEvent(conn, headers, body));
}
}
test/SingletonTest.o \
test/test_main.o
-plain: SocketInput.o PlainConnection.o HTTPTransport.o ThreadPool.o main.o
+plain: PluginManager.cpp SocketInput.o Connection.o PlainConnection.o Transport.o HTTPTransport.o ThreadPool.o main.o
$(LINK) -o $@ $+ $(THREAD_LIB)
utest: ThreadPool.o PluginManager.o EventManager.o $(TEST_OBJS)
#define _PLAIN_CONNECTION_H
#include "Connection.H"
-
+#include "Singleton.H"
class PlainConnection:
public Connection
{
public:
- class Factory: public Connection::Factory {
+ class Factory: public Connection::Factory,
+ public Singleton<PlainConnection::Factory> {
public:
virtual Connection *newConnection(int fd) const {
return new PlainConnection(fd);
virtual ~Factory() {}
};
- static Factory theFactory;
-
PlainConnection(int a_fd): Connection(a_fd)
{}
#include <sys/types.h>
#include <sys/socket.h>
-PlainConnection::Factory PlainConnection::theFactory;
-
-
PlainConnection::~PlainConnection()
{
}
virtual bool initialize() = 0;
virtual bool cleanup () = 0;
+
+ virtual ~Plugin();
};
// add plugin with given name to the list of registered plugins
#include "PluginManager.H"
+PluginManager::Plugin::~Plugin() {
+}
+
throw new Exception;
if(listen(fd, SOCK_QUEUE_MAX) < 0)
throw new Exception;
- ThreadPool::instance()->setWorkAccept(this);
}
: fd(afd), event(NONE) {}
+ virtual ~WorkDescription();
+
protected:
enum Event { NONE, READY, TIMEOUT, ERROR } event;
void doWork();
#include <sys/time.h>
#include <time.h>
#include <stdlib.h>
+#include <errno.h>
#include <iostream>
}
+ThreadPool::WorkDescription::~WorkDescription() {
+}
+
+
ThreadPool::ThreadPool()
- : work_count(0), wait_count(0), ufds_size(0), ufds(NULL), f_exit(false)
+ : f_exit(false), work_count(0), wait_count(0), ufds_size(0), ufds(NULL)
{
pthread_mutex_init(&wait_queue_mutex, NULL);
pthread_mutex_init(&work_queue_mutex, NULL);
#define _TRANSPORT_H
#include "Connection.H"
-
+#include "ThreadPool.H"
class Transport: public ThreadPool::WorkDescription {
public:
public:
virtual Transport *newTransport(Connection *conn) const = 0;
- virtual ~Factory() = 0;
+ virtual ~Factory();
};
Transport(Connection *a_conn)
// create unix socket with plain IO and HTTP transport
input = new SocketInput(sock_path,
- &PlainConnection::theFactory,
- &HTTPTransport::theFactory);
+ PlainConnection::Factory::instance(),
+ HTTPTransport::Factory::instance());
+ // and add the socket to pool
+ ThreadPool::instance()->setWorkAccept(input);
// start worker threads
ThreadPool::instance()->startWorkers(num_threads);