00001
00002
00003
00004
00005
00006
00007
00008 #ifndef GENERICSERVER_H_
00009 #define GENERICSERVER_H_
00010
00011 #include "Component.h"
00012 #include <ibrcommon/thread/MutexLock.h>
00013 #include <ibrcommon/thread/Thread.h>
00014 #include <ibrcommon/thread/Mutex.h>
00015 #include <ibrcommon/thread/Conditional.h>
00016 #include <list>
00017
00018 namespace dtn
00019 {
00020 namespace net
00021 {
00022 class GenericConnection
00023 {
00024 public:
00025 virtual ~GenericConnection() { };
00026 virtual void shutdown() = 0;
00027 virtual bool free() = 0;
00028 };
00029
00030 template <class T>
00031 class GenericServer : public dtn::daemon::IndependentComponent
00032 {
00033 public:
00034 GenericServer()
00035 : _running(false), _cleaner(*this, _clients)
00036 { }
00037
00038 virtual ~GenericServer()
00039 { }
00040
00041 void add(T *obj)
00042 {
00043 ibrcommon::MutexLock l(_cleaner);
00044 _clients.push_back(obj);
00045 connectionUp(obj);
00046 }
00047
00048 protected:
00049 virtual T* accept() = 0;
00050 virtual void listen() = 0;
00051 virtual void shutdown() = 0;
00052
00053 virtual void connectionUp(T *conn) = 0;
00054 virtual void connectionDown(T *conn) = 0;
00055
00056 void shutdownAll()
00057 {
00058 ibrcommon::MutexLock l(_cleaner);
00059
00060 std::list<GenericConnection*>::iterator iter = _clients.begin();
00061 while (iter != _clients.end())
00062 {
00063 if ( (*iter)->free() )
00064 {
00065 delete (*iter);
00066 _clients.erase(iter++);
00067 }
00068 else
00069 {
00070 (*iter)->shutdown();
00071 iter++;
00072 }
00073 }
00074 }
00075
00076 void componentUp()
00077 {
00078 _cleaner.start();
00079 listen();
00080 }
00081
00082 void componentRun()
00083 {
00084 _running = true;
00085
00086 while (_running)
00087 {
00088 try {
00089 T* obj = accept();
00090 if (_running && (obj != NULL))
00091 {
00092 add( obj );
00093 }
00094 } catch (...) {
00095
00096 }
00097
00098 {
00099 ibrcommon::MutexLock l(_cleaner);
00100 _cleaner.signal(true);
00101 }
00102
00103
00104 ibrcommon::Thread::yield();
00105 }
00106 }
00107
00108 void componentDown()
00109 {
00110 _running = false;
00111 shutdown();
00112 }
00113
00114 private:
00115 class ClientCleaner : public ibrcommon::JoinableThread, public ibrcommon::Conditional
00116 {
00117 public:
00118 ClientCleaner(GenericServer &callback, std::list<GenericConnection*> &clients)
00119 : _running(false), _clients(clients), _callback(callback)
00120 {
00121 }
00122
00123 virtual ~ClientCleaner()
00124 {
00125 {
00126 ibrcommon::MutexLock l(*this);
00127 _running = false;
00128 }
00129
00130 join();
00131 }
00132
00133 protected:
00134 void run()
00135 {
00136 ibrcommon::MutexLock l(*this);
00137 _running = true;
00138
00139 while (_running)
00140 {
00141 std::list<GenericConnection*>::iterator iter = _clients.begin();
00142 while (iter != _clients.end())
00143 {
00144 if ( (*iter)->free() )
00145 {
00146 _callback.__connectionDown(*iter);
00147
00148
00149 delete (*iter);
00150
00151 _clients.erase(iter++);
00152 }
00153 else
00154 {
00155 iter++;
00156 }
00157 }
00158
00159 ibrcommon::Thread::yield();
00160 (*this).wait(500);
00161 }
00162 }
00163
00164 private:
00165 bool _running;
00166 std::list<GenericConnection*> &_clients;
00167 GenericServer &_callback;
00168 };
00169
00170 void __connectionDown(GenericConnection *conn)
00171 {
00172 T *tconn = dynamic_cast<T*>(conn);
00173 if (tconn != NULL)
00174 connectionDown(tconn);
00175 }
00176
00177 std::list<GenericConnection*> _clients;
00178 bool _running;
00179 ClientCleaner _cleaner;
00180 };
00181 }
00182 }
00183
00184 #endif