CPPSERV


Home Projects Jobs Clientele Contact
CPPSERV Documentation Download TODO Mailing lists Bug tracker News RSS Feed Browse source

globalcontext.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007 by Ilya A. Volynets-Evenbakh                       *
00003  *   ilya@total-knowledge.com                                              *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
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         //Ugh.. No protocol specified?
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             //Ugh.. Not tcp, not unix..  What is it?
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 // For now we know that if it isn't tcp, it's Unix
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 // For now we know that if it isn't tcp, it's Unix
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 }

SourceForge.net Logo