MySQL  8.0.21
Source Code Documentation
semisync_master_socket_listener.h
Go to the documentation of this file.
1 /* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License, version 2.0,
5  as published by the Free Software Foundation.
6 
7  This program is also distributed with certain software (including
8  but not limited to OpenSSL) that is licensed under separate terms,
9  as designated in a particular file or component or in included license
10  documentation. The authors of MySQL hereby grant you an additional
11  permission to link the program and your derivative works with the
12  separately licensed software that they have included with MySQL.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License, version 2.0, for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22 
23 #ifndef SEMISYNC_MASTER_SOCKET_LISTENER
24 #define SEMISYNC_MASTER_SOCKET_LISTENER
26 
27 #ifdef HAVE_POLL
28 #include <poll.h>
29 #include <vector>
30 
32  public:
34 
36  return poll(m_fds.data(), m_fds.size(), 1000 /*1 Second timeout*/);
37  }
38 
39  bool is_socket_active(int index) { return m_fds[index].revents & POLLIN; }
40 
41  void clear_socket_info(int index) {
42  m_fds[index].fd = -1;
43  m_fds[index].events = 0;
44  }
45 
47  m_slaves.clear();
48  m_fds.clear();
49  for (uint i = 0; i < slaves.size(); i++) {
50  /*
51  Do not consider the slave's socket
52  if the slave is in the process of leaving.
53  */
54  if (slaves[i].is_leaving) {
55  slaves[i].is_leaving = false;
56  continue;
57  }
59  poll_fd.fd = slaves[i].sock_fd();
60  poll_fd.events = POLLIN;
61  poll_fd.revents = 0;
62  m_fds.push_back(poll_fd);
63  m_slaves.push_back(slaves[i]);
64  }
65  return true;
66  }
67  uint number_of_slave_sockets() { return m_slaves.size(); }
68 
69  Slave get_slave_obj(int index) { return m_slaves[index]; }
70 
71  private:
73  std::vector<pollfd> m_fds;
74 };
75 
77 
78 #else // NO POLL
79 
80 class Select_socket_listener {
81  public:
82  Select_socket_listener() : m_max_fd(INVALID_SOCKET) {}
83 
84  bool listen_on_sockets() {
85  /* Reinitialze the fds with active fds before calling select */
86  m_fds = m_init_fds;
87  struct timeval tv = {1, 0};
88  /* select requires max fd + 1 for the first argument */
89  return select(m_max_fd + 1, &m_fds, NULL, NULL, &tv);
90  }
91 
92  bool is_socket_active(int index) {
93  return FD_ISSET(m_slaves[index].sock_fd(), &m_fds);
94  }
95 
96  void clear_socket_info(int index) {
97  FD_CLR(m_slaves[index].sock_fd(), &m_init_fds);
98  }
99 
100  bool init_slave_sockets(Slave_vector &slaves) {
101  m_slaves.clear();
102  FD_ZERO(&m_init_fds);
103  for (uint i = 0; i < slaves.size(); i++) {
104  /*
105  Do not consider the slave's socket
106  if the slave is in the process of leaving.
107  */
108  if (slaves[i].is_leaving) {
109  slaves[i].is_leaving = false;
110  continue;
111  }
112  my_socket socket_id = slaves[i].sock_fd();
113  m_max_fd = (socket_id > m_max_fd ? socket_id : m_max_fd);
114 #ifndef _WIN32
115  if (socket_id > FD_SETSIZE) {
116  LogErr(ERROR_LEVEL, ER_SEMISYNC_SOCKET_FD_TOO_LARGE, socket_id,
117  FD_SETSIZE);
118  return false;
119  }
120 #endif // _WIN32
121  FD_SET(socket_id, &m_init_fds);
122  m_slaves.push_back(slaves[i]);
123  }
124  return true;
125  }
126  uint number_of_slave_sockets() { return m_slaves.size(); }
127 
128  Slave get_slave_obj(int index) { return m_slaves[index]; }
129 
130  private:
132  my_socket m_max_fd;
133  fd_set m_init_fds;
134  fd_set m_fds;
135 };
136 
137 typedef class Select_socket_listener Socket_listener;
138 #endif // HAVE_POLL
139 #endif // SEMISYNC_MASTER_SOCKET_LISTENER
bool listen_on_sockets()
Definition: semisync_master_socket_listener.h:35
Slave get_slave_obj(int index)
Definition: semisync_master_socket_listener.h:69
uint number_of_slave_sockets()
Definition: semisync_master_socket_listener.h:67
Definition: semisync_master_ack_receiver.h:36
bool is_socket_active(int index)
Definition: semisync_master_socket_listener.h:39
Definition: semisync_master_socket_listener.h:31
Poll_socket_listener()
Definition: semisync_master_socket_listener.h:33
struct pollfd pollfd
Definition: task_os.h:111
pollfd poll_fd
Definition: poll.h:49
stdx::expected< size_t, std::error_code > poll(poll_fd *fds, size_t num_fds, std::chrono::milliseconds timeout)
Definition: poll.h:52
unsigned int uint
Definition: uca-dump.cc:29
#define NULL
Definition: types.h:54
int my_socket
Definition: my_io_bits.h:59
class Poll_socket_listener Socket_listener
Definition: semisync_master_socket_listener.h:76
Definition: my_loglevel.h:34
#define FD_SETSIZE
Definition: sock_probe_win32.cc:34
std::vector< Slave > Slave_vector
Definition: semisync_master_ack_receiver.h:46
#define LogErr(severity, ecode,...)
Definition: log_builtins.h:751
std::vector< pollfd > m_fds
Definition: semisync_master_socket_listener.h:73
Slave_vector m_slaves
Definition: semisync_master_socket_listener.h:72
void clear_socket_info(int index)
Definition: semisync_master_socket_listener.h:41
#define INVALID_SOCKET
Definition: my_io.h:184
bool init_slave_sockets(Slave_vector &slaves)
Definition: semisync_master_socket_listener.h:46