fastcgi++
A C++ FastCGI/Web API
manager.hpp
Go to the documentation of this file.
1 
10 /*******************************************************************************
11 * Copyright (C) 2016 Eddie Carle [eddie@isatec.ca] *
12 * *
13 * This file is part of fastcgi++. *
14 * *
15 * fastcgi++ is free software: you can redistribute it and/or modify it under *
16 * the terms of the GNU Lesser General Public License as published by the Free *
17 * Software Foundation, either version 3 of the License, or (at your option) *
18 * any later version. *
19 * *
20 * fastcgi++ is distributed in the hope that it will be useful, but WITHOUT ANY *
21 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for *
23 * more details. *
24 * *
25 * You should have received a copy of the GNU Lesser General Public License *
26 * along with fastcgi++. If not, see <http://www.gnu.org/licenses/>. *
27 *******************************************************************************/
28 
29 #ifndef FASTCGIPP_MANAGER_HPP
30 #define FASTCGIPP_MANAGER_HPP
31 
32 #include <map>
33 #include <list>
34 #include <algorithm>
35 #include <thread>
36 #include <mutex>
37 #include <shared_mutex>
38 #include <memory>
39 #include <functional>
40 
41 #include "fastcgi++/protocol.hpp"
43 #include "fastcgi++/request.hpp"
44 
46 namespace Fastcgipp
47 {
49 
64  {
65  public:
67 
70  Manager_base(unsigned threads);
71 
72  ~Manager_base();
73 
75 
85  void terminate();
86 
88 
97  void stop();
98 
100 
103  void start();
104 
106  void join();
107 
109 
115  static void setupSignals();
116 
118 
124  bool listen()
125  {
126  return m_transceiver.listen();
127  }
128 
130 
144  bool listen(
145  const char* name,
146  uint32_t permissions = 0xffffffffUL,
147  const char* owner = nullptr,
148  const char* group = nullptr)
149  {
150  return m_transceiver.listen(name, permissions, owner, group);
151  }
152 
154 
165  bool listen(
166  const char* interface,
167  const char* service)
168  {
169  return m_transceiver.listen(interface, service);
170  }
171 
173  void push(Protocol::RequestId id, Message&& message);
174 
175  protected:
177  virtual std::unique_ptr<Request_base> makeRequest(
178  const Protocol::RequestId& id,
179  const Protocol::Role& role,
180  bool kill) =0;
181 
184 
185  private:
187  std::queue<Protocol::RequestId> m_tasks;
188 
191 
194 
196  std::shared_timed_mutex m_requestsMutex;
197 
199  std::queue<std::pair<Message, Socket>> m_messages;
200 
203 
205  void handler();
206 
208 
212  inline void localHandler();
213 
216 
218  bool m_stop;
219 
222 
224  std::vector<std::thread> m_threads;
225 
227  std::condition_variable m_wake;
228 
230  static void signalHandler(int signum);
231 
234 
235 #if FASTCGIPP_LOG_LEVEL > 3
236  std::atomic_ullong m_requestCount;
238 
240  size_t m_maxRequests;
241 
243  std::atomic_ullong m_managementRecordCount;
244 
246  std::atomic_ullong m_badSocketMessageCount;
247 
249  std::atomic_ullong m_badSocketKillCount;
250 
252  std::atomic_ullong m_messageCount;
253 
255  unsigned m_activeThreads;
256 
258  unsigned m_maxActiveThreads;
259 #endif
260  };
261 
263 
282  template<class RequestT> class Manager: public Manager_base
283  {
284  public:
286 
289  Manager(unsigned threads = std::thread::hardware_concurrency()):
290  Manager_base(threads)
291  {}
292 
293  private:
295  std::unique_ptr<Request_base> makeRequest(
296  const Protocol::RequestId& id,
297  const Protocol::Role& role,
298  bool kill)
299  {
300  using namespace std::placeholders;
301 
302  std::unique_ptr<Request_base> request(new RequestT);
303  static_cast<RequestT&>(*request).configure(
304  id,
305  role,
306  kill,
307  std::bind(&Transceiver::send, &m_transceiver, _1, _2, _3),
308  std::bind(&Manager_base::push, this, id, _1));
309  return request;
310  }
311 
312  };
313 }
314 
315 #endif
std::vector< std::thread > m_threads
Threads our manager is running in.
Definition: manager.hpp:224
Topmost namespace for the fastcgi++ library.
void send(const Socket &socket, Block &&data, bool kill)
Queue up a block of data for transmission.
bool m_terminate
True when the manager should be terminating.
Definition: manager.hpp:215
Transceiver m_transceiver
Handles low level communication with the other side.
Definition: manager.hpp:183
std::mutex m_startStopMutex
Thread safe starting and stopping.
Definition: manager.hpp:221
General task and protocol management class base.
Definition: manager.hpp:63
static void setupSignals()
Configure the handlers for POSIX signals.
Definition: manager.cpp:100
General task and protocol management class.
Definition: manager.hpp:282
void handler()
General handling function to have it&#39;s own thread.
Definition: manager.cpp:254
Data structure used to pass messages to requests.
Definition: message.hpp:46
virtual std::unique_ptr< Request_base > makeRequest(const Protocol::RequestId &id, const Protocol::Role &role, bool kill)=0
Make a request object.
std::unique_ptr< Request_base > makeRequest(const Protocol::RequestId &id, const Protocol::Role &role, bool kill)
Make a request object.
Definition: manager.hpp:295
void join()
Block until a stop() or terminate() is called and completed.
Definition: manager.cpp:91
std::queue< std::pair< Message, Socket > > m_messages
Local messages.
Definition: manager.hpp:199
bool m_stop
True when the manager should be stopping.
Definition: manager.hpp:218
Declares everything for relating to the FastCGI protocol itself.
std::mutex mutex
Thread safe the logging mechanism.
Definition: log.cpp:102
std::mutex m_messagesMutex
Thread safe our local messages.
Definition: manager.hpp:202
std::condition_variable m_wake
Condition variable to wake handler() threads up.
Definition: manager.hpp:227
void start()
Call from any thread to start the Manager.
Definition: manager.cpp:76
static void signalHandler(int signum)
General function to handler POSIX signals.
Definition: manager.cpp:112
void localHandler()
Handles management messages.
Definition: manager.cpp:143
A unique identifier for each FastCGI request.
Definition: protocol.hpp:71
Handles low level communication with "the other side".
Definition: transceiver.hpp:58
void push(Protocol::RequestId id, Message &&message)
Pass a message to a request.
Definition: manager.cpp:332
std::mutex m_tasksMutex
Thread safe our tasks.
Definition: manager.hpp:190
bool listen()
Listen to the default Fastcgi socket.
std::shared_timed_mutex m_requestsMutex
Thread safe our requests.
Definition: manager.hpp:196
Manager(unsigned threads=std::thread::hardware_concurrency())
Sole constructor.
Definition: manager.hpp:289
Declares the Request class.
void terminate()
Call from any thread to terminate the Manager.
Definition: manager.cpp:60
Declares the Fastcgipp::Transceiver class.
Manager_base(unsigned threads)
Sole constructor.
Definition: manager.cpp:34
void stop()
Call from any thread to stop the Manager.
Definition: manager.cpp:68
bool listen()
Listen to the default Fastcgi socket.
Definition: manager.hpp:124
Protocol::Requests< std::unique_ptr< Request_base > > m_requests
An associative container for our requests.
Definition: manager.hpp:193
static Manager_base * instance
Pointer to the Manager object.
Definition: manager.hpp:233
bool listen(const char *interface, const char *service)
Listen to a TCP port.
Definition: manager.hpp:165
std::queue< Protocol::RequestId > m_tasks
Queue for pending tasks.
Definition: manager.hpp:187
std::map< RequestId, T, RequestId::Less > Requests
A simple associative container that indexes with RequestId.
Definition: protocol.hpp:138
Role
Defines the possible roles a FastCGI application may play.
Definition: protocol.hpp:163
bool listen(const char *name, uint32_t permissions=0xffffffffUL, const char *owner=nullptr, const char *group=nullptr)
Listen to a named socket.
Definition: manager.hpp:144