MySQL  8.0.17
Source Code Documentation
registry.h
Go to the documentation of this file.
1 /* Copyright (c) 2016, 2017, 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 MYSQL_SERVER_REGISTRY_H
24 #define MYSQL_SERVER_REGISTRY_H
25 
29 #include <map>
30 #include <memory>
31 
32 #include "c_string_less.h"
34 #include "rwlock_scoped_lock.h"
35 
36 /**
37  @page PAGE_COMPONENTS_REGISTRY The Service Registry Service
38  The Service Registry is a central part of Components subsystem. It maintains
39  a list of the Service Implementations and allow acquiring them by any actor
40  that has a reference to main Registry Service Implementation. For each Service
41  a reference counter is maintained to make sure no one can remove any Service
42  Implementation being actively used.
43  The Service Implementations can be acquired by the Service name or by the full
44  Service Implementation name.
45  For each Service a default Service Implementation is distinguished, the first
46  one to be added, but it is possible to change it at will at any point.
47 
48  A convenient RAII-style wrapper on Service acquisition and automatic release
49  is provided, the my_service<T> class.
50 */
51 
52 typedef std::map<const char *, mysql_service_implementation *, c_string_less>
54 
56  typedef std::map<my_h_service, mysql_service_implementation *>
58 
59  /* contain the actual fields definitions */
63 
64  public:
65  /**
66  Initializes registry for usage. Initializes RW lock, all other structures
67  should be empty. Shouldn't be called multiple times.
68  */
69  static void init();
70  /**
71  De-initializes registry. De-initializes RW lock, all other structures
72  are cleaned up.
73  */
74  static void deinit();
75 
76  /**
77  Locks whole registry for write. For internal use only.
78 
79  @return A lock acquired wrapped into RAII object.
80  */
82 
83  /**
84  Gets current reference count for a Service Implementation related to the
85  specified pointer to the interface structure. Assumes caller has at least
86  a read lock on the Registry.
87 
88  @param interface A pointer to the interface structure of the Service
89  Implementation to get reference count of.
90  @return A current reference count for specified Service Implementation.
91  Returns 0 in case there is no such interface or it is not referenced.
92  */
94  my_h_service interface);
95 
96  /**
97  Finds and acquires a Service by name. A name of the Service or the Service
98  Implementation can be specified. In case of the Service name, the default
99  Service Implementation for Service specified will be returned. Assumes
100  caller has at least a read lock on the Registry.
101 
102  @param service_name Name of Service or Service Implementation to acquire.
103  @param [out] out_service Pointer to Service handle to set acquired Service.
104  @return Status of performed operation
105  @retval false success
106  @retval true failure
107  */
108  static bool acquire_nolock(const char *service_name,
109  my_h_service *out_service);
110 
111  /**
112  Releases the Service Implementation previously acquired. After the call to
113  this method the usage of the Service Implementation handle will lead to
114  unpredicted results. Assumes caller has at least a read lock on the
115  Registry.
116 
117  @param service Service Implementation handle of already acquired Service.
118  @return Status of performed operation
119  @retval false success
120  @retval true failure
121  */
122  static bool release_nolock(my_h_service service);
123 
124  /**
125  Registers a new Service Implementation. If it is the first Service
126  Implementation for the specified Service then it is made a default one.
127  Assumes caller has a write lock on the Registry.
128 
129  @param service_implementation_name Name of the Service Implementation to
130  register.
131  @param ptr Pointer to the Service Implementation structure.
132  @return Status of performed operation
133  @retval false success
134  @retval true failure
135  */
136  static bool register_service_nolock(const char *service_implementation_name,
137  my_h_service ptr);
138 
139  /**
140  Removes previously registered Service Implementation from registry. If it is
141  the default one for specified Service then any one still registered is made
142  default. If there is no other, the default entry is removed from the
143  Registry too. Assumes caller has a write lock on the Registry.
144 
145  @param service_implementation_name Name of the Service Implementation to
146  unregister.
147  @return Status of performed operation
148  @retval false success
149  @retval true Failure. May happen when Service is still being referenced.
150  */
151  static bool unregister_nolock(const char *service_implementation_name);
152 
153  public: /* Service Implementations */
154  /**
155  Finds and acquires a Service by name. A name of the Service or the Service
156  Implementation can be specified. In case of the Service name, the default
157  Service Implementation for Service specified will be returned.
158 
159  @param service_name Name of Service or Service Implementation to acquire.
160  @param [out] out_service Pointer to Service handle to set acquired Service.
161  @return Status of performed operation
162  @retval false success
163  @retval true failure
164  */
165  static DEFINE_BOOL_METHOD(acquire, (const char *service_name,
166  my_h_service *out_service));
167 
168  /**
169  Finds a Service by name. If there is a Service Implementation with the same
170  Component part of name as the input Service then the found Service is
171  returned. Otherwise the default Service Implementation for specified
172  Service is returned.
173 
174  @param service_name Name of Service or Service Implementation to acquire.
175  @param service Service handle already acquired Service Implementation.
176  @param [out] out_service Pointer to Service Implementation handle to set
177  acquired Service Implementation.
178  @return Status of performed operation
179  @retval false success
180  @retval true failure
181  */
183  (const char *service_name, my_h_service service,
184  my_h_service *out_service));
185 
186  /**
187  Releases the Service Implementation previously acquired. After the call to
188  this method the usage of the Service Implementation handle will lead to
189  unpredicted results.
190 
191  @param service Service Implementation handle of already acquired Service.
192  @return Status of performed operation
193  @retval false success
194  @retval true failure
195  */
196  static DEFINE_BOOL_METHOD(release, (my_h_service service));
197 
198  /**
199  Registers a new Service Implementation. If it is the first Service
200  Implementation for the specified Service then it is made a default one.
201 
202  @param service_implementation_name Name of the Service Implementation to
203  register.
204  @param ptr Pointer to the Service Implementation structure.
205  @return Status of performed operation
206  @retval false success
207  @retval true failure
208  */
210  (const char *service_implementation_name,
211  my_h_service ptr));
212 
213  /**
214  Removes previously registered Service Implementation from registry. If it is
215  the default one for specified Service then any one still registered is made
216  default. If there is no other, the default entry is removed from the
217  Registry too.
218 
219  @param service_implementation_name Name of the Service Implementation to
220  unregister.
221  @return Status of performed operation
222  @retval false success
223  @retval true Failure. May happen when Service is still being referenced.
224  */
226  (const char *service_implementation_name));
227 
228  /**
229  Sets new default Service Implementation for corresponding Service name.
230 
231  @param service_implementation_name Name of the Service Implementation to
232  set as default one.
233  @return Status of performed operation
234  @retval false success
235  @retval true failure
236  */
238  (const char *service_implementation_name));
239 
240  /**
241  Creates iterator that iterates through all registered Service
242  Implementations. If successful it leaves read lock on the Registry until
243  iterator is released. The starting point of iteration may be specified
244  to be on one particular Service Implementation. The iterator will move
245  through all Service Implementations and additionally through all default
246  Service Implementation additionally, i.e. the default Service Implementation
247  will be returned twice. If no name is specified for search, iterator will be
248  positioned on the first Service Implementation.
249 
250  @param service_name_pattern Name of Service or Service Implementation to
251  start iteration from. May be empty string or NULL pointer, in which case
252  iteration starts from the first Service Implementation.
253  @param [out] out_iterator Pointer to the Service Implementation iterator
254  handle.
255  @return Status of performed operation
256  @retval false success
257  @retval true failure
258  */
260  (const char *service_name_pattern,
261  my_h_service_iterator *out_iterator));
262 
263  /**
264  Releases Service implementations iterator. Releases read lock on registry.
265 
266  @param iterator Service Implementation iterator handle.
267  @return Status of performed operation
268  @retval false success
269  @retval true failure
270  */
271  static DEFINE_METHOD(void, iterator_release,
272  (my_h_service_iterator iterator));
273 
274  /**
275  Gets name of Service pointed to by iterator. The pointer returned will last
276  at least up to the moment of call to the release() method on the iterator.
277 
278  @param iterator Service Implementation iterator handle.
279  @param [out] out_name Pointer to string with name to set result pointer to.
280  @return Status of performed operation
281  @retval false success
282  @retval true Failure, may be caused when called on iterator that went
283  through all values already.
284  */
286  const char **out_name));
287 
288  /**
289  Advances specified iterator to next element. Will succeed but return true if
290  it reaches one-past-last element.
291 
292  @param iterator Service Implementation iterator handle.
293  @return Status of performed operation and validity of iterator after
294  operation.
295  @retval false success
296  @retval true Failure or called on iterator that was on last element.
297  */
299 
300  /**
301  Checks if specified iterator is valid, i.e. have not reached one-past-last
302  element.
303 
304  @param iterator Service Implementation iterator handle.
305  @return Validity of iterator
306  @retval false Valid
307  @retval true Invalid or reached one-past-last element.
308  */
310  (my_h_service_iterator iterator));
311 
312  /* This includes metadata-related method implementations that are shared
313  by registry and dynamic_loader, so we don't duplicate the code. Following
314  defines set up all required symbols. Unfortunately they are not only the
315  types, but also static members with different name, so usage of templates
316  is not enough to reuse that part of code. */
317 #define OBJECT_ITERATOR my_h_service_iterator
318 #define METADATA_ITERATOR my_h_service_metadata_iterator
319 
320 #include "registry_metadata.h.inc"
321 
322  private:
323  /**
324  Finds a Service Implementation data structure based on the pointer to
325  interface struct supplied. Assumes caller has at least a read lock on the
326  Registry.
327 
328  @param interface A pointer to the interface structure of the Service
329  Implementation to look for.
330  @return A pointer to respective Service Implementation data structure, or
331  NULL if no such interface pointer is registered within the Registry.
332  */
334  my_h_service interface);
335 };
336 
337 #endif /* MYSQL_SERVER_REGISTRY_H */
static mysql_service_status_t iterator_create(const char *service_name_pattern, my_h_service_iterator *out_iterator) noexcept
Creates iterator that iterates through all registered Service Implementations.
Definition: registry.cc:513
static bool acquire_nolock(const char *service_name, my_h_service *out_service)
Finds and acquires a Service by name.
Definition: registry.cc:150
static mysql_service_status_t release(my_h_service service) noexcept
Releases the Service Implementation previously acquired.
Definition: registry.cc:406
std::map< my_h_service, mysql_service_implementation * > my_interface_mapping
Definition: registry.h:57
static mysql_service_implementation * get_service_implementation_by_interface(my_h_service interface)
Finds a Service Implementation data structure based on the pointer to interface struct supplied...
Definition: registry.cc:106
#define DEFINE_BOOL_METHOD(name, args)
static bool unregister_nolock(const char *service_implementation_name)
Removes previously registered Service Implementation from registry.
Definition: registry.cc:269
static mysql_service_status_t acquire(const char *service_name, my_h_service *out_service) noexcept
Finds and acquires a Service by name.
Definition: registry.cc:339
static mysql_service_status_t register_service(const char *service_implementation_name, my_h_service ptr) noexcept
Registers a new Service Implementation.
Definition: registry.cc:426
std::map< const char *, mysql_service_implementation *, c_string_less > my_service_registry
Definition: registry.h:53
static mysql_service_status_t set_default(const char *service_implementation_name) noexcept
Sets new default Service Implementation for corresponding Service name.
Definition: registry.cc:464
static void iterator_release(my_h_service_iterator iterator) noexcept
Releases Service implementations iterator.
Definition: registry.cc:546
Definition: registry.cc:57
#define DEFINE_METHOD(retval, name, args)
static mysql_rwlock_t LOCK_registry
Definition: registry.h:62
static void deinit()
De-initializes registry.
Definition: registry.cc:79
Definition: registry.h:55
static mysql_service_status_t iterator_is_valid(my_h_service_iterator iterator) noexcept
Checks if specified iterator is valid, i.e.
Definition: registry.cc:626
a Service implementation registry data
Definition: mysql_service_implementation.h:31
static my_interface_mapping interface_mapping
Definition: registry.h:61
static mysql_service_status_t iterator_next(my_h_service_iterator iterator) noexcept
Advances specified iterator to next element.
Definition: registry.cc:600
static uint64_t get_service_implementation_reference_count(my_h_service interface)
Gets current reference count for a Service Implementation related to the specified pointer to the int...
Definition: registry.cc:127
static mysql_service_status_t acquire_related(const char *service_name, my_h_service service, my_h_service *out_service) noexcept
Finds a Service by name.
Definition: registry.cc:361
static bool release_nolock(my_h_service service)
Releases the Service Implementation previously acquired.
Definition: registry.cc:182
An instrumented rwlock structure.
Definition: mysql_rwlock_bits.h:50
static my_service_registry service_registry
Definition: registry.h:60
static mysql_service_status_t unregister(const char *service_implementation_name) noexcept
Removes previously registered Service Implementation from registry.
Definition: registry.cc:447
static rwlock_scoped_lock lock_registry_for_write()
Locks whole registry for write.
Definition: registry.cc:91
Locks RW-lock and releases lock on scope exit.
Definition: rwlock_scoped_lock.h:31
static void init()
Initializes registry for usage.
Definition: registry.cc:71
struct my_h_service_imp * my_h_service
A handle type for acquired Service.
Definition: registry.h:32
Specifies macros to define Service Implementations.
static mysql_service_status_t iterator_get(my_h_service_iterator iterator, const char **out_name) noexcept
Gets name of Service pointed to by iterator.
Definition: registry.cc:570
static bool register_service_nolock(const char *service_implementation_name, my_h_service ptr)
Registers a new Service Implementation.
Definition: registry.cc:211
std::map< const char *, mysql_service_implementation *, c_string_less > my_service_registry
Definition: registry.cc:55