File: connection_handler_manager.h

package info (click to toggle)
mysql-8.0 8.0.44-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,272,892 kB
  • sloc: cpp: 4,685,345; ansic: 412,712; pascal: 108,395; java: 83,641; perl: 30,221; cs: 27,067; sql: 26,594; python: 21,816; sh: 17,285; yacc: 17,169; php: 11,522; xml: 7,388; javascript: 7,083; makefile: 1,793; lex: 1,075; awk: 670; asm: 520; objc: 183; ruby: 97; lisp: 86
file content (237 lines) | stat: -rw-r--r-- 7,767 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/*
   Copyright (c) 2013, 2025, Oracle and/or its affiliates.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License, version 2.0,
   as published by the Free Software Foundation.

   This program is designed to work with certain software (including
   but not limited to OpenSSL) that is licensed under separate terms,
   as designated in a particular file or component or in included license
   documentation.  The authors of MySQL hereby grant you an additional
   permission to link the program and your derivative works with the
   separately licensed software that they have either included with
   the program or referenced in the documentation.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License, version 2.0, for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
*/

#ifndef CONNECTION_HANDLER_MANAGER_INCLUDED
#define CONNECTION_HANDLER_MANAGER_INCLUDED

#include <assert.h>
#include <stddef.h>
#include <sys/types.h>

#include "mysql/psi/mysql_cond.h"  // mysql_cond_t
#include "mysql/psi/mysql_mutex.h"
#include "sql/conn_handler/connection_handler.h"  // Connection_handler

class Channel_info;
class THD;
struct mysql_cond_t;
struct mysql_mutex_t;

/**
  Functions to notify interested connection handlers
  of events like beginning of wait and end of wait and post-kill
  notification events.
*/
struct THD_event_functions {
  void (*thd_wait_begin)(THD *thd, int wait_type);
  void (*thd_wait_end)(THD *thd);
  void (*post_kill_notification)(THD *thd);
};

/**
  This is a singleton class that provides various connection management
  related functionalities, most importantly dispatching new connections
  to the currently active Connection_handler.
*/
class Connection_handler_manager {
  // Singleton instance to Connection_handler_manager
  static Connection_handler_manager *m_instance;

  static mysql_mutex_t LOCK_connection_count;
  static mysql_cond_t COND_connection_count;

  // Pointer to current connection handler in use
  Connection_handler *m_connection_handler;
  // Pointer to saved connection handler
  Connection_handler *m_saved_connection_handler;
  // Saved scheduler_type
  ulong m_saved_thread_handling;

  // Status variables
  ulong m_aborted_connects;
  ulong
      m_connection_errors_max_connection;  // Protected by LOCK_connection_count

  /**
    Constructor to instantiate an instance of this class.
  */
  Connection_handler_manager(Connection_handler *connection_handler)
      : m_connection_handler(connection_handler),
        m_saved_connection_handler(nullptr),
        m_saved_thread_handling(0),
        m_aborted_connects(0),
        m_connection_errors_max_connection(0) {}

  ~Connection_handler_manager() {
    delete m_connection_handler;
    if (m_saved_connection_handler) delete m_saved_connection_handler;
  }

  /* Make this class non-copyable */
  Connection_handler_manager(const Connection_handler_manager &);
  Connection_handler_manager &operator=(const Connection_handler_manager &);

 public:
  /**
    thread_handling enumeration.

    The default of --thread-handling is the first one in the
    thread_handling_names array, this array has to be consistent with
    the order in this array, so to change default one has to change the
    first entry in this enum and the first entry in the
    thread_handling_names array.

    @note The last entry of the enumeration is also used to mark the
    thread handling as dynamic. In this case the name of the thread
    handling is fetched from the name of the plugin that implements it.
  */
  enum scheduler_types {
    SCHEDULER_ONE_THREAD_PER_CONNECTION = 0,
    SCHEDULER_NO_THREADS,
    SCHEDULER_TYPES_COUNT
  };

  // Status variables. Must be static as they are used by the signal handler.
  static uint connection_count;            // Protected by LOCK_connection_count
  static ulong max_used_connections;       // Protected by LOCK_connection_count
  static ulong max_used_connections_time;  // Protected by LOCK_connection_count

  // System variable
  static ulong thread_handling;

  // Functions for lock wait and post-kill notification events
  static THD_event_functions *event_functions;
  // Saved event functions
  static THD_event_functions *saved_event_functions;

  /**
     Maximum number of threads that can be created by the current
     connection handler. Must be static as it is used by the signal handler.
  */
  static uint max_threads;

  /**
    Singleton method to return an instance of this class.
  */
  static Connection_handler_manager *get_instance() {
    assert(m_instance != nullptr);
    return m_instance;
  }

  /**
    Initialize the connection handler manager.
    Must be called before get_instance() can be used.

    @return true if initialization failed, false otherwise.
  */
  static bool init();

  /**
    Destroy the singleton instance.
  */
  static void destroy_instance();

  /**
    Check if the current number of connections are below or equal
    the value given by the max_connections server system variable.

    @return true if a new connection can be accepted, false otherwise.
  */
  bool valid_connection_count();

  /**
    Increment connection count if max_connections is not exceeded.

    @param ignore_max_connection_count  true if checking for a limit
                                        specified by the max-connections
                                        server option should be skipped

    @retval
      true   max_connections NOT exceeded
      false  max_connections reached
  */
  bool check_and_incr_conn_count(bool ignore_max_connection_count);

  /**
    Reset the max_used_connections counter to the number of current
    connections.
  */
  static void reset_max_used_connections();

  /**
    Decrease the number of current connections.
  */
  static void dec_connection_count() {
    mysql_mutex_lock(&LOCK_connection_count);
    connection_count--;
    /*
      Notify shutdown thread when last connection is done with its job
    */
    if (connection_count == 0) mysql_cond_signal(&COND_connection_count);
    mysql_mutex_unlock(&LOCK_connection_count);
  }

  void inc_aborted_connects() { m_aborted_connects++; }

  ulong aborted_connects() const { return m_aborted_connects; }

  /**
    @note This is a dirty read.
  */
  ulong connection_errors_max_connection() const {
    return m_connection_errors_max_connection;
  }

  /**
    Dynamically load a connection handler implemented as a plugin.
    The current connection handler will be saved so that it can
    later be restored by unload_connection_handler().
  */
  void load_connection_handler(Connection_handler *conn_handler);

  /**
    Unload the connection handler previously loaded by
    load_connection_handler(). The previous connection handler will
    be restored.

    @return true if unload failed (no previous connection handler was found).
  */
  bool unload_connection_handler();

  /**
    Process a new incoming connection.

    @param channel_info    Pointer to Channel_info object containing
                           connection channel information.
  */
  void process_new_connection(Channel_info *channel_info);

  /**
    Waits until all connections are done with their job. In other words,
    wat till connection_count to become zero.
  */
  static void wait_till_no_connection();
};
#endif  // CONNECTION_HANDLER_MANAGER_INCLUDED.