MySQL 8.4.0
Source Code Documentation
semisync_source_socket_listener.h
Go to the documentation of this file.
1/* Copyright (c) 2016, 2024, 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 designed to work 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 either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef SEMISYNC_SOURCE_SOCKET_LISTENER
25#define SEMISYNC_SOURCE_SOCKET_LISTENER
27
28#ifdef HAVE_POLL
29#include <poll.h>
30#include <vector>
31
33 public:
35
37 return poll(m_fds.data(), m_fds.size(), 1000 /*1 Second timeout*/);
38 }
39
40 bool is_socket_active(int index) { return m_fds[index].revents & POLLIN; }
41
42 void clear_socket_info(int index) {
43 m_fds[index].fd = -1;
44 m_fds[index].events = 0;
45 }
46
48 m_slaves.clear();
49 m_fds.clear();
50 for (uint i = 0; i < slaves.size(); i++) {
51 /*
52 Do not consider the slave's socket
53 if the slave is in the process of leaving.
54 */
55 if (slaves[i].m_status != Slave::EnumStatus::up) {
56 slaves[i].m_status = Slave::EnumStatus::down;
57 continue;
58 }
60 poll_fd.fd = slaves[i].sock_fd();
61 poll_fd.events = POLLIN;
62 poll_fd.revents = 0;
63 m_fds.push_back(poll_fd);
64 m_slaves.push_back(slaves[i]);
65 }
66 return true;
67 }
68 uint number_of_slave_sockets() { return m_slaves.size(); }
69
70 Slave get_slave_obj(int index) { return m_slaves[index]; }
71
72 private:
74 std::vector<pollfd> m_fds;
75};
76
78
79#else // NO POLL
80
81class Select_socket_listener {
82 public:
83 Select_socket_listener() : m_max_fd(INVALID_SOCKET) {}
84
85 bool listen_on_sockets() {
86 /* Reinitialze the fds with active fds before calling select */
87 m_fds = m_init_fds;
88 struct timeval tv = {1, 0};
89 /* select requires max fd + 1 for the first argument */
90 return select(m_max_fd + 1, &m_fds, nullptr, nullptr, &tv);
91 }
92
93 bool is_socket_active(int index) {
94 return FD_ISSET(m_slaves[index].sock_fd(), &m_fds);
95 }
96
97 void clear_socket_info(int index) {
98 FD_CLR(m_slaves[index].sock_fd(), &m_init_fds);
99 }
100
101 bool init_replica_sockets(Slave_vector &slaves) {
102 m_slaves.clear();
103 FD_ZERO(&m_init_fds);
104 for (uint i = 0; i < slaves.size(); i++) {
105 /*
106 Do not consider the slave's socket
107 if the slave is in the process of leaving.
108 */
109 if (slaves[i].m_status != Slave::EnumStatus::up) {
110 slaves[i].m_status = Slave::EnumStatus::down;
111 continue;
112 }
113 my_socket socket_id = slaves[i].sock_fd();
114 m_max_fd = (socket_id > m_max_fd ? socket_id : m_max_fd);
115#ifndef _WIN32
116 if (socket_id > FD_SETSIZE) {
117 LogErr(ERROR_LEVEL, ER_SEMISYNC_SOCKET_FD_TOO_LARGE, socket_id,
118 FD_SETSIZE);
119 return false;
120 }
121#endif // _WIN32
122 FD_SET(socket_id, &m_init_fds);
123 m_slaves.push_back(slaves[i]);
124 }
125 return true;
126 }
127 uint number_of_slave_sockets() { return m_slaves.size(); }
128
129 Slave get_slave_obj(int index) { return m_slaves[index]; }
130
131 private:
132 Slave_vector m_slaves;
133 my_socket m_max_fd;
134 fd_set m_init_fds;
135 fd_set m_fds;
136};
137
138typedef class Select_socket_listener Socket_listener;
139#endif // HAVE_POLL
140#endif // SEMISYNC_SOURCE_SOCKET_LISTENER
Definition: semisync_source_socket_listener.h:32
Poll_socket_listener()=default
std::vector< pollfd > m_fds
Definition: semisync_source_socket_listener.h:74
Slave get_slave_obj(int index)
Definition: semisync_source_socket_listener.h:70
uint number_of_slave_sockets()
Definition: semisync_source_socket_listener.h:68
Slave_vector m_slaves
Definition: semisync_source_socket_listener.h:73
bool is_socket_active(int index)
Definition: semisync_source_socket_listener.h:40
bool init_replica_sockets(Slave_vector &slaves)
Definition: semisync_source_socket_listener.h:47
void clear_socket_info(int index)
Definition: semisync_source_socket_listener.h:42
bool listen_on_sockets()
Definition: semisync_source_socket_listener.h:36
#define LogErr(severity, ecode,...)
Definition: log_builtins.h:843
#define INVALID_SOCKET
Definition: my_io.h:190
@ ERROR_LEVEL
Definition: my_loglevel.h:43
int my_socket
Definition: mysql.h:65
pollfd poll_fd
Definition: poll.h:50
stdx::expected< size_t, std::error_code > poll(poll_fd *fds, size_t num_fds, std::chrono::milliseconds timeout)
Definition: poll.h:53
std::vector< Slave > Slave_vector
Definition: semisync_source_ack_receiver.h:48
class Poll_socket_listener Socket_listener
Definition: semisync_source_socket_listener.h:77
#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:34
Definition: semisync_source_ack_receiver.h:37
struct pollfd pollfd
Definition: task_os.h:114