globalcontext.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <serverconfig/serverconfig.h>
00022
00023 using namespace container;
00024 namespace container {
00025 namespace serverconfig {
00026
00027 GlobalContext::GlobalContext(ServerConfig& cfg)
00028 : Context(cfg, 0)
00029 , m_nThreads(-1)
00030 , m_queueDepth(-1)
00031 , m_listener(0)
00032 , m_pool(0)
00033 {
00034 m_paramregistry.getParamList(getUnsetParams());
00035 }
00036
00037 GlobalContext::~GlobalContext()
00038 {
00039 for(std::list<GlobalConfigNode*>::iterator it=m_globalNodes.begin();
00040 it!=m_globalNodes.end(); it++)
00041 {
00042 delete *it;
00043 }
00044 if(m_listener)
00045 delete m_listener;
00046 if(m_pool)
00047 delete m_pool;
00048 for(std::list<RequestListener::Acceptor*>::iterator it=m_acceptors.begin();
00049 it!=m_acceptors.end(); it++)
00050 delete *it;
00051 }
00052
00053 void GlobalContext::registerContexts(ContextRegistry& reg)
00054 {
00055 reg.registerContext("app",AppContext::contextCreator, PARAM_SINGLE_OF_NAME);
00056 }
00057
00058 bool GlobalContext::onSetParam(const ConfigNode& node)
00059 {
00060 return m_paramregistry.setParam(node, this);
00061 }
00062
00063 void GlobalContext::registerParams(ParamRegistry<GlobalContext>& reg)
00064 {
00065 reg.registerParam("sessiontimeout",&Context::setIgnore,PARAM_SINGLE_OF_TYPE);
00066 reg.registerParam("upload_dir",&Context::setIgnore,PARAM_SINGLE_OF_TYPE);
00067 reg.registerParam("listener",&GlobalContext::setListener,PARAM_NONE);
00068 reg.registerParam("num_threads", &GlobalContext::setNumThreads,PARAM_NONE);
00069 reg.registerParam("queue_depth", &GlobalContext::setQueueDepth,PARAM_NONE);
00070 reg.registerParam("uri_base", &Context::setIgnore,PARAM_REQUIRED|PARAM_SINGLE_OF_TYPE);
00071 reg.registerParam("max_request_size", &Context::setIgnore,PARAM_SINGLE_OF_TYPE);
00072 reg.registerParam("max_file_size", &Context::setIgnore,PARAM_SINGLE_OF_TYPE);
00073 reg.registerParam("phys_base", &Context::setIgnore,PARAM_NONE);
00074 }
00075
00076 bool GlobalContext::setGlobalParam(const std::string& type, const std::string& value)
00077 {
00078 GlobalConfigNode* node = new GlobalConfigNode(type, value);
00079 m_globalNodes.push_back(node);
00080 return setParam(*node);
00081 }
00082
00089 bool GlobalContext::setListener(const ConfigNode& node)
00090 {
00091 util::param_t::const_iterator param = node.getAttrs().find("protocol");
00092 if (param == node.getAttrs().end()) {
00093
00094 std::cerr<<"Listener node specified without protocol specification"<<std::endl;
00095 return false;
00096 }
00097 std::string host, port, path, proto;
00098 try {
00099 RequestListener::Acceptor *acc;
00100 proto=param->second;
00101 if(proto=="tcp") {
00102 param = node.getAttrs().find("host");
00103 if(param == node.getAttrs().end()) {
00104 std::cerr<<"No host specified for tcp listener"<<std::endl;
00105 return false;
00106 }
00107 host=param->second;
00108 param = node.getAttrs().find("port");
00109 if(param == node.getAttrs().end()) {
00110 std::cerr<<"No port specified for tcp listener"<<std::endl;
00111 return false;
00112 }
00113 port = param->second;
00114 unsigned short uport=atoi(port.c_str());
00115 acc=new RequestListener::TCPAcceptor(host,uport);
00116 } else if(proto=="unix") {
00117 param = node.getAttrs().find("path");
00118 if(param == node.getAttrs().end()) {
00119 std::cerr<<"No path specifed for UNIX-domain listener"<<std::endl;
00120 return false;
00121 }
00122 path=param->second;
00123 acc=new RequestListener::UnixAcceptor(path);
00124 } else {
00125
00126 std::cerr<<"Unknown listener type specified"<<std::endl;
00127 return false;
00128 }
00129 m_acceptors.push_back(acc);
00130 } catch (servlet::Traceable& e) {
00131 std::cerr<<"Unable to create listener for socket \""<<proto<<"://";
00132 if(proto == "tcp")
00133 std::cerr<<host<<':'<<port;
00134 else
00135 std::cerr<<path;
00136 std::cerr<<std::endl;
00137 e.printStackTrace(std::cerr);
00138 return false;
00139 } catch (std::exception& e) {
00140 std::cerr<<"Unable to create listener for socket \""<<proto<<"://";
00141 if(proto == "tcp")
00142 std::cerr<<host<<':'<<port;
00143 else
00144 std::cerr<<path;
00145 std::cerr<<std::endl;
00146 std::cerr<<"\tReason: "<<e.what()<<std::endl;
00147 return false;
00148 }
00149 return true;
00150 }
00154 bool GlobalContext::setNumThreads(const ConfigNode& node)
00155 {
00156 if(m_nThreads==-1) {
00157 m_nThreads=atoi(node.getAttrs().find("value")->second.c_str());
00158 }
00159 return true;
00160 }
00161
00165 bool GlobalContext::setQueueDepth(const ConfigNode& node)
00166 {
00167 if(m_queueDepth==-1) {
00168 m_queueDepth=atoi(node.getAttrs().find("value")->second.c_str());
00169 }
00170 return true;
00171 }
00172
00173 class DoAccept: public std::unary_function<RequestListener::Acceptor*, void>
00174 {
00175 RequestListener* m_listener;
00176 public:
00177 DoAccept(RequestListener * listener)
00178 : m_listener(listener){}
00179 void operator()(RequestListener::Acceptor* acc)
00180 {
00181 m_listener->addAcceptor(acc);
00182 }
00183 };
00184
00185 bool GlobalContext::onPostComplete()
00186 {
00187 if(m_nThreads==-1)
00188 m_nThreads=15;
00189 if(m_queueDepth==-1)
00190 m_queueDepth=15;
00191 m_pool=new sptk::CThreadPool(m_nThreads, m_queueDepth);
00192 m_listener=new RequestListener(*m_pool);
00193 for_each(m_acceptors.begin(), m_acceptors.end(), DoAccept(m_listener));
00194 m_pool->start();
00195 return true;
00196 }
00197
00198 ParamRegistry<GlobalContext> GlobalContext::m_paramregistry(GlobalContext::registerParams);
00199 ContextRegistry GlobalContext::m_contextregistry(GlobalContext::registerContexts);
00200
00201 }
00202 }