MySQL  8.0.18
Source Code Documentation
component_implementation.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 COMPONENT_IMPLEMENTATION_H
24 #define COMPONENT_IMPLEMENTATION_H
25 
28 #include <cstddef> // NULL
29 #include "service_implementation.h"
30 
31 /**
32  @page PAGE_COMPONENTS_COMPONENT A Component
33 
34  A component is a code container that contains one or more Service
35  Implementations. Components can be internal (part of the MySQL Server binary)
36  and external (hosted in a OS binary file different from the one of the MySQL
37  Server).
38 
39  Each component will have:
40  - Name
41  - List of service implementations it provides.
42  - List of services or service implementations it needs.
43  - Initialization function that's called when a container is loaded. Takes a
44  reference to the currently active service registry implementation.
45  - De-initialization function that's called when a container unload is
46  requested.
47 
48  Opposite to old plugin infrastructure, Components don't need linkage against
49  mysqld executable, neither on Linux nor Windows. In fact, in Components we
50  strongly discourage from linking against mysqld executable at all, as it
51  presents significant threat to them being independent and using only
52  Components infrastructure to communicate with other parts of software.
53 
54  @subpage PAGE_COMPONENTS_IMPLEMENTATION
55 
56  @page PAGE_COMPONENTS_IMPLEMENTATION MySQL Component - creating implementation
57  The Component for the Dynamic Loader needs to be a dynamic library (for
58  example .so or .dll) with specified entry-point method. The only exception is
59  the MySQL server, for which, for now, it will be statically linked. All these
60  implementation details are hidden away by macros defined in header files.
61  All macros to define Services are specified in service.h, for defining Service
62  Implementations in service_implementation.h and for specifying Components in
63  component_implementation.h.
64 
65  @section EXAMPLE The Component example
66  Example Components are located in components/example directory. These
67  Components are used also for unit and MTR test, which assures these Components
68  are fully functional and they quality is maintained. The example Services are
69  defined in example_services.h, while implemented in three example Components
70  defined in files example_component1.cc, example_component2.cc,
71  and example_component3.cc. These files are specifically prepared to be used as
72  examples as they provide simplicity and an extensive documentation. The
73  following tutorial bases on these Components and will try to show a process to
74  create similar.
75 
76  @subsection EXAMPLE_SERVICES Services defined in the example
77  Example contains definition of 3 Services which will be used to show a general
78  idea of services, basic implementations and simple example of one of concepts
79  possible with the Component Infrastructure. These example Services are defined
80  in example_services.h and are s_mysql_greetings,
81  s_mysql_greetings_localization and s_mysql_example_math.
82 
83  @section TROUBLESHOOTING Common problems
84 
85  -# If you have problem during linking on GCC with similar message:
86 
87  ../../../components/mysql_server/component_mysql_server.a(server_component.cc.o):%server_component.cc:imp_...:
88  error: undefined reference to '..._impl::...'
89 
90  In such case you should add a new `%init()` method (it can be dummy/empty)
91  to your source file that contains service methods implementations and a call
92  to that method somewhere in mysqld.cc. This will help GCC not to optimize
93  the required object file out of linkage. Take `mysql_string_services_init()`
94  as an example. This applies only to service implementations added to the
95  server component.
96 
97  @section TUTORIAL Step by step tutorial for creating new Component
98  The creation of component is a mean to get some functionality exported for the
99  Components infrastructure. It can be divided into several steps:
100  -# %List all high level functionalities Component is planned to have
101  implemented. This will assure we know exactly what we need to benefit from
102  next steps. In the example, we would like to have a "Hello, World!" string
103  provider and simple math functions.
104  -# Look for existing Services, that are designed specifically to provide some
105  part of the new functionalities to reuse them, or other that are in any
106  degree similar in functionality, design or use cases to use as an example.
107  The Component infrastructure is highly oriented on reuse of Services and
108  will benefit with every reuse case, as it will decrease total size of
109  Services. In the example the existing base of Services is really small,
110  with the core Components infrastructure Services available only leading to
111  no reuse possible.
112  -# Design list of functions needed to provide all functionalities. Try to make
113  they follow existing patterns and ideas, possibly having some identical to
114  existing ones.
115  -# Try to separate groups of functions that specify some complete part of
116  functionality into separate small Services to improve re-usability. Also,
117  try to separate groups that seem to have more potential to be extended or
118  modified in future, because changing existing Services is forbidden, in
119  such a case this will lead to a lot of functions in Services that will be
120  duplicates and will introduce more boilerplate code to implement them.
121  Remove all functions that can be found in fully reused existing Services.
122  -# Create definitions of Services, ideally one Service per file, or a group of
123  really closely connected Services. In most cases you want to make these
124  definitions public, in case of MySQL that means placing them in
125  include/mysql/components/services/ directory to include them in mysql-dev
126  package. See example_services.h, which in contrary is not made public and
127  resides in example component source directory.
128  -# Create declarations of all handles, the Opaque pointers for all opaque
129  objects that are meant to be returned to the Services users. See usages of
130  DEFINE_SERVICE_HANDLE in registry.h.
131  -# Create basic structure of new Component. Use BEGIN_COMPONENT_PROVIDES,
132  BEGIN_COMPONENT_REQUIRES, BEGIN_COMPONENT_METADATA, DECLARE_COMPONENT and
133  DECLARE_LIBRARY_COMPONENTS. Fill in all information necessary to describe
134  the new Component extensively. The example_component1.cc and
135  example_component2.cc shows how structure should look like, and in
136  example_component3.cc there is an example with additional Service
137  references, for which placeholder definitions are kept in header file of the
138  new Component, see example_component3.h. Note the placeholder for the
139  Registry Service, which is available by default in every component.
140  -# Create implementations of the desired Service interfaces. Implement handles
141  used, as for example my_h_service_iterator_imp and
142  my_h_service_metadata_iterator_imp in registry.cc. Create separate
143  source and header files for each Service or closely connected group of
144  Services. Remember to include the header file for Service Implementation in
145  the Service Implementation source file to have no linkage problems.
146  The Service Implementations in english_greeting_service_imp.cc and
147  simple_example_math_imp.cc are implementations used in example_component1,
148  polish_greeting_service_imp.cc and example_math_wrapping_imp.cc are
149  implementations for example_component2 and example_component3 respectively.
150  -# Make sure component is loaded/initialized before using its services.
151  Atomic variable is_intialized represents the state of the component.
152  Please check the details about the variable from validate_password_imp.cc
153  file.
154  .
155 
156  @file include/mysql/components/component_implementation.h
157  Specifies macros to define Components.
158 */
159 
160 /**
161  Declares a component. For specified name following macros must be executed
162  earlier: BEGIN_COMPONENT_PROVIDES, BEGIN_COMPONENT_REQUIRES and
163  BEGIN_COMPONENT_METADATA.
164  It fills mysql_component_t structure with all of the component data. The
165  info object will be named mysql_component_{source_name}.
166  After this macro it is required to specify comma-separated pointers to
167  initialize and deinitialize methods for components to be used during loading
168  and unloading of component.
169 
170  @param source_name The source name used in other macros.
171  @param name Name string with human readable name.
172 */
173 #define DECLARE_COMPONENT(source_name, name) \
174  mysql_component_t mysql_component_##source_name = { \
175  name, __##source_name##_provides, __##source_name##_requires, \
176  __##source_name##_metadata,
177 
178 /**
179  A macro to end the last declaration of a Component.
180 */
181 #define END_DECLARE_COMPONENT() }
182 
183 /**
184  Creates a service implementation list that are provided by specified
185  component. Only a series of PROVIDES_SERVICE and PROVIDES_CUSTOM_SERVICE
186  macros are expected to be used after this macro and before the
187  END_COMPONENT_PROVIDES counterpart.
188 
189  @param name Component name.
190 */
191 #define BEGIN_COMPONENT_PROVIDES(name) \
192  static struct mysql_service_ref_t __##name##_provides[] = {
193 /**
194  Declare a Service Implementation provided by a Component. It assumes standard
195  Service Implementation name to be referenced.
196  @sa SERVICE_IMPLEMENTATION
197 
198  @param component Component name.
199  @param service A Service name for which the Service Implementation will be
200  added.
201 */
202 #define PROVIDES_SERVICE(component, service) \
203  { \
204 #service "." #component, \
205  const_cast < void *> \
206  ((const void *)&SERVICE_IMPLEMENTATION(component, service)) \
207  }
208 
209 /**
210  A macro to end the last declaration started with the BEGIN_COMPONENT_PROVIDES.
211 */
212 #define END_COMPONENT_PROVIDES() \
213  { NULL, NULL } \
214  }
215 
216 /**
217  A macro to specify requirements of the component. Creates a placeholder for
218  the Registry service and structure with a list for requirements and
219  pointers to their placeholders, adding the Registry service as first element.
220 
221  @param name Name of component.
222 */
223 #define BEGIN_COMPONENT_REQUIRES(name) \
224  REQUIRES_SERVICE_PLACEHOLDER(registry); \
225  static struct mysql_service_placeholder_ref_t __##name##_requires[] = { \
226  REQUIRES_SERVICE(registry),
227 
228 /**
229  Creates a definition for placeholder, in which the specified required service
230  will be provided upon component load. The placeholder will be named
231  mysql_service_{service name}. Use the "extern" keyword before macro invocation
232  to define a reference to the one real placeholder defined in component source.
233 
234  @param service A referenced Service name.
235 */
236 #define REQUIRES_SERVICE_PLACEHOLDER(service) \
237  SERVICE_TYPE(service) * mysql_service_##service
238 
239 /**
240  Adds a Service requirement with a pointer to placeholder to the list of
241  components.
242 
243  @param service A referenced Service name.
244 */
245 #define REQUIRES_SERVICE(service) \
246  { \
247 #service, \
248  static_cast < void **> \
249  (static_cast <void *>(const_cast <mysql_service_##service##_t **>( \
250  &mysql_service_##service))) \
251  }
252 
253 /**
254  A macro to end the last declaration started with the BEGIN_COMPONENT_REQUIRES.
255 */
256 #define END_COMPONENT_REQUIRES() \
257  { NULL, NULL } \
258  }
259 
260 /**
261  A macro to specify metadata of the component. Creates a list of metadata.
262  Only a series of METADATA macros are expected to be used after this macro and
263  before the END_COMPONENT_METADATA counterpart.
264 
265  @param name Name of component.
266 */
267 #define BEGIN_COMPONENT_METADATA(name) \
268  static struct mysql_metadata_ref_t __##name##_metadata[] = {
269 /**
270  Adds a Service requirement with a pointer to placeholder to the list of
271  components.
272 
273  @param key A string name of the metadata to add.
274  @param value A string value of the metadata to add.
275 */
276 #define METADATA(key, value) \
277  { key, value }
278 
279 /**
280  A macro to end the last declaration started with the BEGIN_COMPONENT_METADATA.
281 */
282 #define END_COMPONENT_METADATA() \
283  { NULL, NULL } \
284  }
285 
286 /* On Windows, exports from DLL need to be declared.
287  Also, plug-in needs to be declared as extern "C" because MSVC
288  unlike other compilers, uses C++ mangling for variables not only
289  for functions. */
290 #if defined(_MSC_VER)
291 #ifdef __cplusplus
292 #define DLL_EXPORT extern "C" __declspec(dllexport)
293 #else
294 #define DLL_EXPORT __declspec(dllexport)
295 #endif
296 #else /*_MSC_VER */
297 #ifdef __cplusplus
298 #define DLL_EXPORT extern "C"
299 #else
300 #define DLL_EXPORT
301 #endif
302 #endif
303 
304 /**
305  Creates a list of component implementations included in this dynamic library.
306  It can be used only once in whole library. It defines an entry point method
307  for library to be used with the Dynamic Loader. A list of pointers to
308  Component structures is required after this macro up to the usage of
309  the END_DECLARE_LIBRARY_COMPONENTS macro. Current implementation of the
310  Dynamic Loader supports only one Component being specified in the library.
311 */
312 #define DECLARE_LIBRARY_COMPONENTS \
313  mysql_component_t *library_components_list = {
314 /**
315  A macro to end the last declaration started with the
316  DECLARE_LIBRARY_COMPONENTS.
317 */
318 #define END_DECLARE_LIBRARY_COMPONENTS \
319  } \
320  ; \
321  DLL_EXPORT mysql_component_t *list_components() { \
322  return library_components_list; \
323  }
324 
325 /**
326  Defines a reference to the specified Component data info structure.
327 */
328 #define COMPONENT_REF(name) mysql_component_##name
329 
330 #endif /* COMPONENT_IMPLEMENTATION_H */
Specifies macros to define Service Implementations.