MySQL 8.3.0
Source Code Documentation
semisync_source_socket_listener.h
Go to the documentation of this file.
1/* Copyright (c) 2016, 2023, Oracle and/or its affiliates.
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_SOURCE_SOCKET_LISTENER
24#define SEMISYNC_SOURCE_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].m_status != Slave::EnumStatus::up) {
55 slaves[i].m_status = Slave::EnumStatus::down;
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
80class 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, nullptr, nullptr, &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_replica_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].m_status != Slave::EnumStatus::up) {
109 slaves[i].m_status = Slave::EnumStatus::down;
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:
131 Slave_vector m_slaves;
132 my_socket m_max_fd;
133 fd_set m_init_fds;
134 fd_set m_fds;
135};
136
137typedef class Select_socket_listener Socket_listener;
138#endif // HAVE_POLL
139#endif // SEMISYNC_SOURCE_SOCKET_LISTENER
Definition: semisync_source_socket_listener.h:31
Poll_socket_listener()=default
std::vector< pollfd > m_fds
Definition: semisync_source_socket_listener.h:73
Slave get_slave_obj(int index)
Definition: semisync_source_socket_listener.h:69
uint number_of_slave_sockets()
Definition: semisync_source_socket_listener.h:67
Slave_vector m_slaves
Definition: semisync_source_socket_listener.h:72
bool is_socket_active(int index)
Definition: semisync_source_socket_listener.h:39
bool init_replica_sockets(Slave_vector &slaves)
Definition: semisync_source_socket_listener.h:46
void clear_socket_info(int index)
Definition: semisync_source_socket_listener.h:41
bool listen_on_sockets()
Definition: semisync_source_socket_listener.h:35
#define LogErr(severity, ecode,...)
Definition: log_builtins.h:842
#define INVALID_SOCKET
Definition: my_io.h:189
@ ERROR_LEVEL
Definition: my_loglevel.h:42
int my_socket
Definition: mysql.h:64
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
std::vector< Slave > Slave_vector
Definition: semisync_source_ack_receiver.h:47
class Poll_socket_listener Socket_listener
Definition: semisync_source_socket_listener.h:76
#define FD_SETSIZE
Utility functions to check if a network address or name matches an interface on the machine we are ru...
Definition: sock_probe_win32.h:33
Definition: semisync_source_ack_receiver.h:36
struct pollfd pollfd
Definition: task_os.h:113