Savarese Software Research Corporation
fcgi/service.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2006-2009 Savarese Software Research Corporation
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     https://www.savarese.com/software/ApacheLicense-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00022 #ifndef __SSRC_WSPR_FCGI_SERVICE_H
00023 #define __SSRC_WSPR_FCGI_SERVICE_H
00024 
00025 #include <ssrc/wispers/service/service.h>
00026 
00027 #ifdef WSPR_DEBUG
00028 #include <iostream>
00029 #endif
00030 
00031 __BEGIN_NS_SSRC_WSPR_FCGI
00032 
00033 using NS_SSRC_WISP_PROTOCOL::GroupMembershipDisable;
00034 using NS_SSRC_WSPR_SERVICE::EventLoop;
00035 using NS_SSRC_WSPR_SERVICE::EventHandler;
00036 using NS_SSRC_WSPR_SERVICE::EventInfo;
00037 using NS_SSRC_WSPR_SERVICE::ServiceEventHandler;
00038 
00039 const int FCGIDescriptorDefault = 0;
00040 
00044 template<typename Processor>
00045 class FCGIAcceptHandler : public EventHandler {
00046 
00047   int _descriptor;
00048   Processor & _service;
00049 
00050 public:
00051 
00052   explicit FCGIAcceptHandler(Processor & service,
00053                              int descriptor = FCGIDescriptorDefault)
00054     SSRC_DECL_THROW(std::invalid_argument) :
00055     _descriptor(descriptor), _service(service)
00056   {
00057     if(descriptor < 0)
00058       throw std::invalid_argument("bad file descriptor");
00059   }
00060 
00061   virtual ~FCGIAcceptHandler() { }
00062 
00063   virtual int event_descriptor() const {
00064     return _descriptor;
00065   }
00066 
00067   virtual void handle_read(const EventInfo & info) {
00068     fcgx_request_ptr request = fcgx_request_ptr(new FCGI::FCGX_Request);
00069 
00070     FCGI::FCGX_InitRequest(request.get(), event_descriptor(), 0);
00071 
00072     if(FCGX_Accept_r(request.get()) == 0)
00073       _service.process_fcgi_request(request);
00074     else {
00075       // TODO: log this!
00076 #ifdef WSPR_DEBUG
00077       std::cerr << "FCGX Accept Error!\n";
00078 #endif
00079     }
00080   }
00081 };
00082 
00086 /*
00087 // This no longer works with gcc 4.3 as a service_main type arg.
00088 template<typename ProtocolProcessor,
00089          typename AcceptHandler = FCGIAcceptHandler<ProtocolProcessor> >
00090 */
00091 template<typename ProtocolProcessor>
00092 class FCGIServiceEventHandler : public ServiceEventHandler<ProtocolProcessor> {
00093   typedef ServiceEventHandler<ProtocolProcessor> super;
00094 
00095   string _socket;
00096   typedef FCGIAcceptHandler<ProtocolProcessor> AcceptHandler;
00097   AcceptHandler _accept_handler;
00098 
00099 protected:
00100 
00101   virtual void remove_handler(EventLoop & loop) {
00102     super::remove_handler(loop);
00103     loop.remove_handler(_accept_handler);
00104   }
00105 
00106 public:
00107 
00111   explicit FCGIServiceEventHandler(typename super::caller_type & caller)
00112     SSRC_DECL_THROW(std::invalid_argument) :
00113     super(caller), _accept_handler(super::protocol())
00114   { }
00115 
00116   template<typename Initializer>
00117   explicit FCGIServiceEventHandler(typename super::caller_type & caller,
00118                                    const Initializer & initializer)
00119     SSRC_DECL_THROW(std::invalid_argument) :
00120     super(caller, initializer),
00121     _socket(initializer.fcgi_socket),
00122     _accept_handler(super::protocol(),
00123                     (_socket.empty() ? FCGIDescriptorDefault :
00124                      FCGI::FCGX_OpenSocket(_socket.c_str(),
00125                                            initializer.fcgi_backlog)))
00126   { }
00127 
00128   virtual ~FCGIServiceEventHandler() {
00129     if(_accept_handler.event_descriptor() > 0) {
00130       if(_socket.find(':') >= _socket.size()) {
00131         ::unlink(_socket.c_str());
00132       }
00133       ::close(_accept_handler.event_descriptor());
00134     }
00135   }
00136 
00137   void start(EventLoop & loop, const unsigned int call_timeout) {
00138     super::start(loop, call_timeout);
00139     FCGI::FCGX_Init();
00140     loop.add_handler(_accept_handler, EventLoop::Read);
00141   }
00142 
00143 };
00144 
00145 __END_NS_SSRC_WSPR_FCGI
00146 
00147 #endif

Savarese Software Research Corporation
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.