fastcgi++
A C++ FastCGI/Web API
sockets.hpp
Go to the documentation of this file.
1 
15 /*******************************************************************************
16 * Copyright (C) 2017 Eddie Carle [eddie@isatec.ca] *
17 * *
18 * This file is part of fastcgi++. *
19 * *
20 * fastcgi++ is free software: you can redistribute it and/or modify it under *
21 * the terms of the GNU Lesser General Public License as published by the Free *
22 * Software Foundation, either version 3 of the License, or (at your option) *
23 * any later version. *
24 * *
25 * fastcgi++ is distributed in the hope that it will be useful, but WITHOUT ANY *
26 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
27 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for *
28 * more details. *
29 * *
30 * You should have received a copy of the GNU Lesser General Public License *
31 * along with fastcgi++. If not, see <http://www.gnu.org/licenses/>. *
32 *******************************************************************************/
33 
34 #ifndef FASTCGIPP_SOCKETS_HPP
35 #define FASTCGIPP_SOCKETS_HPP
36 
37 #include <memory>
38 #include <map>
39 #include <mutex>
40 #include <set>
41 #include <atomic>
42 #include <deque>
43 #include <string>
44 
45 #include "fastcgi++/config.hpp"
46 
47 #ifdef FASTCGIPP_UNIX
48 #include <vector>
49 #include <poll.h>
50 #endif
51 
53 namespace Fastcgipp
54 {
56  typedef int socket_t;
57 
58 #ifdef FASTCGIPP_LINUX
59  typedef const int poll_t;
61 #elif defined FASTCGIPP_UNIX
62  typedef std::vector<pollfd> poll_t;
64 #endif
65 
66  class SocketGroup;
67 
69 
83  class Socket
84  {
85  private:
87  friend class SocketGroup;
88 
90  struct Data
91  {
94 
96  bool m_valid;
97 
99 
103  bool m_closing;
104 
107 
109 
119  const socket_t& socket,
120  bool valid,
121  SocketGroup& group):
122  m_socket(socket),
123  m_valid(valid),
124  m_closing(false),
125  m_group(group)
126  {}
127 
128  Data() =delete;
129  Data(const Data&) =delete;
130  };
131 
133  std::shared_ptr<Data> m_data;
134 
137 
139 
152  Socket(
153  const socket_t& socket,
154  SocketGroup& group,
155  bool valid=true);
156 
157  public:
159 
179  ssize_t read(char* buffer, size_t size) const;
180 
182 
200  ssize_t write(const char* buffer, size_t size) const;
201 
203  bool operator<(const Socket& x) const
204  {
205  return m_data < x.m_data;
206  }
207 
209  bool operator==(const Socket& x) const
210  {
211  return m_data == x.m_data;
212  }
213 
215 
219  Socket(const Socket& x):
220  m_data(x.m_data),
221  m_original(false)
222  {}
223 
225 
229  {
230  m_data = x.m_data;
231  m_original = false;
232  return *this;
233  }
234 
236 
242  m_data(x.m_data),
244  {
245  x.m_original=false;
246  }
247 
249  ~Socket();
250 
252  bool valid() const
253  {
254  return m_data->m_valid;
255  }
256 
258 
267  void close() const;
268 
270  Socket();
271  };
272 
274 
288  {
289  public:
290  SocketGroup();
291 
292  ~SocketGroup();
293 
295 
301  bool listen();
302 
304 
318  bool listen(
319  const char* name,
320  uint32_t permissions = 0xffffffffUL,
321  const char* owner = nullptr,
322  const char* group = nullptr);
323 
325 
336  bool listen(
337  const char* interface,
338  const char* service);
339 
341 
350  Socket connect(const char* name);
351 
353 
363  Socket connect(
364  const char* host,
365  const char* service);
366 
368 
392  Socket poll(bool block);
393 
395 
403  void wake();
404 
406  size_t size() const
407  {
408  return m_sockets.size();
409  }
410 
412 
416  void accept(bool status);
417 
418  private:
420  friend class Socket;
421 
423  std::set<socket_t> m_listeners;
424 
427 
430 
432  bool m_waking;
433 
435  std::atomic_bool m_accept;
436 
438  std::atomic_bool m_refreshListeners;
439 
442 
444  std::map<socket_t, Socket> m_sockets;
445 
447  inline void createSocket(const socket_t listener);
448 
450  bool pollAdd(const socket_t socket);
451 
453  bool pollDel(const socket_t socket);
454 
456  std::deque<std::string> m_filenames;
457 
458 #if FASTCGIPP_LOG_LEVEL > 3
459  std::atomic_ullong m_incomingConnectionCount;
461 
463  std::atomic_ullong m_outgoingConnectionCount;
464 
466  std::atomic_ullong m_connectionKillCount;
467 
469  std::atomic_ullong m_connectionRDHupCount;
470 
472  std::atomic_ullong m_bytesSent;
473 
475  std::atomic_ullong m_bytesReceived;
476 #endif
477  };
478 }
479 
480 #endif
const int poll_t
Our polling type using the Linux kernel is simply an int.
Definition: sockets.hpp:60
std::map< socket_t, Socket > m_sockets
All the sockets.
Definition: sockets.hpp:444
Socket & operator=(const Socket &x)
Assignment.
Definition: sockets.hpp:228
Topmost namespace for the fastcgi++ library.
socket_t m_wakeSockets[2]
A pair of sockets for wakeup purposes.
Definition: sockets.hpp:429
bool m_waking
Set to true while there is a pending wake.
Definition: sockets.hpp:432
Socket(Socket &&x)
Move constructor.
Definition: sockets.hpp:241
bool operator==(const Socket &x) const
We need this to allow the socket objects to be in sorted containers.
Definition: sockets.hpp:209
void close() const
Call this to close the socket.
Definition: sockets.cpp:122
~Socket()
Calls close() on the socket if we are destructing the original.
Definition: sockets.cpp:138
bool m_original
This is only true for a non-copy constructed object.
Definition: sockets.hpp:136
bool listen()
Listen to the default Fastcgi socket.
Definition: sockets.cpp:201
bool valid() const
Returns true if this socket is still open and capable of read/write.
Definition: sockets.hpp:252
std::shared_ptr< Data > m_data
Shared pointer to hold the socket data.
Definition: sockets.hpp:133
void accept(bool status)
Should we accept new connections?
Definition: sockets.cpp:696
void createSocket(const socket_t listener)
Accept a new connection and create it&#39;s socket.
Definition: sockets.cpp:609
SocketGroup & m_group
SocketGroup object this socket is tied to.
Definition: sockets.hpp:106
int socket_t
Our socket identifier type in GNU/Linux is simply an int.
Definition: sockets.hpp:56
std::mutex m_wakingMutex
We need this mutex to thread safe the wake() function.
Definition: sockets.hpp:441
bool pollDel(const socket_t socket)
Remove a socket identifier to the poll list.
Definition: sockets.cpp:676
std::mutex mutex
Thread safe the logging mechanism.
Definition: log.cpp:102
std::set< socket_t > m_listeners
These are the sockets we listen for connections on.
Definition: sockets.hpp:423
void wake()
Wake up from a nap inside poll()
Definition: sockets.cpp:596
ssize_t read(char *buffer, size_t size) const
Try and read a chunk of data out of the socket.
Definition: sockets.cpp:68
Class for representing an OS level I/O socket.
Definition: sockets.hpp:83
Socket poll(bool block)
Poll socket set for new incoming connections and data.
Definition: sockets.cpp:460
bool m_closing
Indicates whether or not the connection is closing.
Definition: sockets.hpp:103
ssize_t write(const char *buffer, size_t size) const
Try and write a chunk of data into the socket.
Definition: sockets.cpp:99
Socket(const Socket &x)
Copy constructor.
Definition: sockets.hpp:219
size_t size() const
How many active sockets (not counting listeners) are in the group.
Definition: sockets.hpp:406
bool pollAdd(const socket_t socket)
Add a socket identifier to the poll list.
Definition: sockets.cpp:651
Class for representing an OS level socket that listens for connections.
Definition: sockets.hpp:287
Data structure to hold the shared socket data.
Definition: sockets.hpp:90
const socket_t m_socket
OS level socket identifier.
Definition: sockets.hpp:93
poll_t m_poll
Our poll object.
Definition: sockets.hpp:426
bool operator<(const Socket &x) const
We need this to allow the socket objects to be in sorted containers.
Definition: sockets.hpp:203
std::atomic_bool m_accept
Set to true if we should be accepting new connections.
Definition: sockets.hpp:435
std::deque< std::string > m_filenames
Filenames to cleanup when we&#39;re done.
Definition: sockets.hpp:456
Data(const socket_t &socket, bool valid, SocketGroup &group)
Sole constructor.
Definition: sockets.hpp:118
Socket connect(const char *name)
Connect to a named socket.
Definition: sockets.cpp:363
bool m_valid
Indicates whether or not the socket is dead/invalid.
Definition: sockets.hpp:96
Socket()
Creates an invalid socket with no original.
Definition: sockets.cpp:646
std::atomic_bool m_refreshListeners
Set to true if we should refresh the listeners in the poll.
Definition: sockets.hpp:438