MySQL  8.0.22
Source Code Documentation
gcs_internal_message.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 GCS_MSG_H
24 #define GCS_MSG_H
25 
26 #include <cassert>
27 #include <cstdlib>
28 #include <memory>
29 #include <sstream>
30 #include <unordered_set>
31 #include <vector>
34 
36 
38 
39 /**
40  Deleter for objects managed by a std::unique_ptr that were allocated using
41  the malloc family of functions instead of the new operator.
42  */
44  void operator()(unsigned char *buffer) const { std::free(buffer); }
45 };
46 
47 /**
48  This class is an abstraction for the packet concept. It is used to manipulate
49  the contents of a buffer that is to be sent to the network in an optimal way.
50 
51  The on-the-wire layout looks like this:
52 
53  +--------------+-----------------+----------------+-----------+
54  | fixed header | dynamic headers | stage metadata | payload |
55  +--------------+-----------------+----------------+-----------+
56  */
57 class Gcs_packet {
58  public:
59  using buffer_ptr = std::unique_ptr<unsigned char, Gcs_packet_buffer_deleter>;
60 
61  private:
62  /**
63  Fixed header which is common regardless whether the packet has been
64  changed by a stage or not.
65  */
67 
68  /**
69  List of dynamic headers created by the stages by which the packet has
70  passed through and changed it.
71  */
72  std::vector<Gcs_dynamic_header> m_dynamic_headers;
73 
74  /**
75  List of stage metadata created by the stages by which the packet has passed
76  through.
77  This list always has the same length as m_dynamic_headers, and the
78  following holds:
79 
80  For every i, m_stage_metadata[i] and m_dynamic_headers[i] correspond to
81  the same stage.
82  */
83  std::vector<std::unique_ptr<Gcs_stage_metadata>> m_stage_metadata;
84 
85  /**
86  Index of the next stage to apply/revert in both m_dynamic_headers and
87  m_stage_metadata.
88  */
89  std::size_t m_next_stage_index{0};
90 
91  /**
92  The buffer containing all serialized data for this packet.
93  */
95 
96  /**
97  The capacity of the serialization buffer.
98  */
99  unsigned long long m_serialized_packet_size{0};
100 
101  /**
102  The offset in m_serialized_packet where the application payload starts.
103  */
104  std::size_t m_serialized_payload_offset{0};
105 
106  /**
107  The size of the serialized application payload in m_serialized_packet.
108  */
109  unsigned long long m_serialized_payload_size{0};
110 
111  /**
112  The size of the serialized m_stage_metadata in m_serialized_packet.
113  */
114  unsigned long long m_serialized_stage_metadata_size{0};
115 
116  /**
117  The XCom synode in which this packet was delivered.
118  */
120 
121  public:
122  /**
123  This factory method is to be used when sending a packet.
124 
125  @param cargo The message type
126  @param current_version The pipeline version
127  @param dynamic_headers The dynamic headers of the stages the packet will go
128  through
129  @param stage_metadata The stage metadata of the stages the packet will go
130  through
131  @param payload_size The payload size
132  @retval {true, Gcs_packet} If packet is created successfully
133  @retval {false, _} If memory could not be allocated
134  */
135  static std::pair<bool, Gcs_packet> make_outgoing_packet(
136  Cargo_type const &cargo, Gcs_protocol_version const &current_version,
137  std::vector<Gcs_dynamic_header> &&dynamic_headers,
138  std::vector<std::unique_ptr<Gcs_stage_metadata>> &&stage_metadata,
139  unsigned long long const &payload_size);
140 
141  /**
142  This factory method is to be used when modifying a packet. This builds a
143  packet with all the same headers, metadata, and state of @c original_packet.
144 
145  It is used, for example, by:
146  - The compression stage of the pipeline, to derive the compressed packet from
147  the original, uncompressed packet.
148  - The fragmentation stage of the pipeline, to derive the fragments from the
149  original packet.
150 
151  @param original_packet The packet to "clone"
152  @param new_payload_size The payload size of this packet
153  @retval {true, Gcs_packet} If packet is created successfully
154  @retval {false, _} If memory could not be allocated
155  */
156  static std::pair<bool, Gcs_packet> make_from_existing_packet(
157  Gcs_packet const &original_packet,
158  unsigned long long const &new_payload_size);
159 
160  /**
161  This factory method is to be used when receiving a packet from the network.
162 
163  @param buffer Buffer with a serialized packet
164  @param buffer_size Size of the buffer
165  @param synode The XCom synode where the packet was decided on
166  @param pipeline The message pipeline
167  @returns A packet initialized from the buffer
168  */
169  static Gcs_packet make_incoming_packet(buffer_ptr &&buffer,
170  unsigned long long buffer_size,
171  synode_no const &synode,
172  Gcs_message_pipeline const &pipeline);
173 
174  Gcs_packet() noexcept;
175 
176  /**
177  These constructors are to be used when move semantics may be needed.
178  */
179  Gcs_packet(Gcs_packet &&packet) noexcept;
180  Gcs_packet &operator=(Gcs_packet &&packet) noexcept;
181 
182  Gcs_packet(const Gcs_packet &packet) = delete;
183  Gcs_packet &operator=(const Gcs_packet &packet) = delete;
184 
185  /**
186  Retrieve this packet's header.
187  @returns The packet's header
188  */
189  Gcs_internal_message_header const &get_fixed_header() const;
190 
191  /**
192  Retrieve this packet's dynamic headers.
193  @returns The packet's dynamic headers
194  */
195  std::vector<Gcs_dynamic_header> const &get_dynamic_headers() const;
196 
197  /**
198  Retrieve this packet's stage metadata.
199  @returns The packet's stage metadata
200  */
201  std::vector<std::unique_ptr<Gcs_stage_metadata>> const &get_stage_metadata()
202  const;
203 
204  std::size_t const &get_next_stage_index() const;
205 
206  void prepare_for_next_outgoing_stage();
207  void prepare_for_next_incoming_stage();
208 
209  Gcs_dynamic_header &get_current_dynamic_header();
210 
211  Gcs_stage_metadata &get_current_stage_header();
212 
213  unsigned char *get_payload_pointer();
214 
215  void set_payload_length(unsigned long long const &new_length);
216 
217  /**
218  Return the value of the maximum supported version.
219  */
220  Gcs_protocol_version get_maximum_version() const;
221 
222  /**
223  Return the value of the version in use.
224  */
225  Gcs_protocol_version get_used_version() const;
226 
227  /**
228  Return the cargo type.
229  */
230  Cargo_type get_cargo_type() const;
231 
232  /**
233  Return the total length.
234  */
235  unsigned long long get_total_length() const;
236 
237  /**
238  Return the payload length.
239  */
240  unsigned long long const &get_payload_length() const;
241 
242  /**
243  Encode the packet content into its serialization buffer, and release
244  ownership of the serialization buffer.
245 
246  This method must only be called on a valid packet, i.e. a packet for which
247  @c allocate_serialization_buffer was called and returned true.
248 
249  @retval {buffer, buffer_size} The buffer with the serialized packet, and
250  its size
251  */
252  std::pair<buffer_ptr, unsigned long long> serialize();
253 
254  /**
255  Create a string representation of the packet to be logged.
256 
257  @param output Reference to the output stream where the string will be
258  created.
259  */
260  void dump(std::ostringstream &output) const;
261 
262  Gcs_xcom_synode const &get_delivery_synode() const;
263 
264  private:
265  /**
266  Constructor called by @c make_to_send.
267 
268  @param cargo The message type
269  @param current_version The pipeline version
270  @param dynamic_headers The dynamic headers of the stages the packet will go
271  through
272  @param stage_metadata The stage metadata of the stages the packet will go
273  through
274  @param payload_size The payload size
275  */
276  explicit Gcs_packet(
277  Cargo_type const &cargo, Gcs_protocol_version const &current_version,
278  std::vector<Gcs_dynamic_header> &&dynamic_headers,
279  std::vector<std::unique_ptr<Gcs_stage_metadata>> &&stage_metadata,
280  unsigned long long const &payload_size);
281 
282  /**
283  Constructor called by @c make_from_existing_packet.
284 
285  @param original_packet The packet to "clone"
286  @param new_payload_size The payload size of this packet
287  */
288  explicit Gcs_packet(Gcs_packet const &original_packet,
289  unsigned long long const &new_payload_size);
290 
291  /**
292  Constructor called by @c make_from_serialized_buffer.
293 
294  @param synode The XCom synode where the packet was decided on
295  */
296  explicit Gcs_packet(synode_no const &synode);
297 
298  /**
299  Allocates the underlying buffer where the packet will be serialized to using
300  @c serialize.
301 
302  @returns true if the required buffer could not be allocated, false otherwise
303  */
304  bool allocate_serialization_buffer();
305 
306  /**
307  Decode the packet content from the given buffer containing a serialized
308  packet.
309 
310  @param buffer Buffer containing a serialized packet
311  @param buffer_size Size of the buffer
312  @param pipeline The message pipeline
313  */
314  void deserialize(buffer_ptr &&buffer, unsigned long long buffer_size,
315  Gcs_message_pipeline const &pipeline);
316 };
317 
318 #endif // GCS_MSG_H
#define free(A)
Definition: fts0ast.h:42
This header is internal to the MySQL GCS library and contains metadata information about the message ...
Definition: gcs_internal_message_headers.h:168
char buffer[STRING_BUFFER]
Definition: test_sql_9_sessions.cc:57
std::vector< T, ut_allocator< T > > vector
Specialization of vector which uses ut_allocator.
Definition: ut0new.h:1306
Deleter for objects managed by a std::unique_ptr that were allocated using the malloc family of funct...
Definition: gcs_internal_message.h:43
Defines a message identifier so that joining members can fetch the associated packet from a remote no...
Definition: gcs_xcom_synode.h:38
bool deserialize(THD *thd, const Sdi_type &sdi, Table *dst_table, SdiCompatibilityChecker comp_checker, String_type *deser_schema_name)
Deserialize a dd::Table object.
Definition: sdi.cc:474
buffer_ptr m_serialized_packet
The buffer containing all serialized data for this packet.
Definition: gcs_internal_message.h:94
Definition: varlen_sort.h:182
std::vector< Gcs_dynamic_header > m_dynamic_headers
List of dynamic headers created by the stages by which the packet has passed through and changed it...
Definition: gcs_internal_message.h:72
Gcs_protocol_version
The GCS protocol versions.
Definition: gcs_types.h:127
Cargo_type
The different cargo type codes.
Definition: gcs_internal_message_headers.h:104
Gcs_internal_message_header m_fixed_header
Fixed header which is common regardless whether the packet has been changed by a stage or not...
Definition: gcs_internal_message.h:66
Gcs_xcom_synode m_delivery_synode
The XCom synode in which this packet was delivered.
Definition: gcs_internal_message.h:119
std::vector< std::unique_ptr< Gcs_stage_metadata > > m_stage_metadata
List of stage metadata created by the stages by which the packet has passed through.
Definition: gcs_internal_message.h:83
Abstract class that defines specific metadata associated to a stage if it decides to extend it...
Definition: gcs_internal_message_headers.h:551
This class is an abstraction for the packet concept.
Definition: gcs_internal_message.h:57
native_mutex_t serialize
Definition: debug_lock_order.cc:2827
size_t buffer_size(const ConstBufferSequence &buffers) noexcept
Definition: buffer.h:283
This is the pipeline that an outgoing or incoming message has to go through when being sent to or rec...
Definition: gcs_message_stages.h:364
static int dump
Definition: myisam_ftdump.cc:42
std::basic_ostringstream< char, std::char_traits< char >, ut_allocator< char > > ostringstream
Specialization of basic_ostringstream which uses ut_allocator.
Definition: ut0new.h:1302
void operator()(unsigned char *buffer) const
Definition: gcs_internal_message.h:44
std::unique_ptr< unsigned char, Gcs_packet_buffer_deleter > buffer_ptr
Definition: gcs_internal_message.h:59
This is a default header created per stage and contains information to decode it. ...
Definition: gcs_internal_message_headers.h:416