1 /*  Copyright (c) 2015, 2021, 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 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 SRV_SESSION_H
24 #define SRV_SESSION_H
25 
26 #include "protocol_callback.h"
27 #include "sql_class.h"
28 #include "my_thread.h"           /* my_thread_id */
29 #include "violite.h"             /* enum_vio_type */
30 
31 /**
32   @file
33   Header file for the Srv_session class that wraps THD, DA in one bundle
34   for easy use of internal APIs.
35   Srv_session also provides means for physical thread initialization and
36   respective deinitialization.
37 */
38 
39 #ifdef HAVE_PSI_STATEMENT_INTERFACE
40 extern PSI_statement_info stmt_info_new_packet;
41 #endif
42 
43 class Srv_session
44 {
45 public:
46   /**
47     Initializes the module.
48 
49 
50     This method has to be called at server startup.
51 
52     @return
53      false  success
54      true   failure
55   */
56   static bool module_init();
57 
58   /**
59     Deinitializes the module
60 
61 
62     This method has to be called at server shutdown.
63 
64     @return
65       false  success
66       true   failure
67   */
68   static bool module_deinit();
69 
70   /**
71     Initializes the current physical thread for use with this class.
72 
73     @param plugin Pointer to the plugin structure, passed to the plugin over
74                   the plugin init function.
75 
76     @return
77       false  success
78       true   failure
79   */
80   static bool init_thread(const void *plugin);
81 
82   /**
83     Deinitializes the current physical thread for use with session service
84   */
85   static void deinit_thread();
86 
87 
88   /**
89     Checks if a plugin has left threads and sessions
90 
91     @param plugin  The plugin to be checked
92   */
93   static void check_for_stale_threads(const st_plugin_int *plugin);
94 
95   /**
96     Checks if the session is valid.
97 
98     Checked is if session is NULL, or in the list of opened sessions. If the
99     session is not in this list it was either closed or the address is invalid.
100 
101     @return
102       true  valid
103       false not valid
104   */
105   static bool is_valid(const Srv_session *session);
106 
107   /**
108     Returns the number opened sessions in thread initialized by this class.
109   */
110   static unsigned int session_count();
111 
112   /**
113     Returns the number currently running threads initialized by this class.
114   */
115   static unsigned int thread_count(const void *plugin_name);
116 
117 
118   /* Non-static members follow */
119 
120   /**
121     Enum for the state of the session
122   */
123   enum srv_session_state
124   {
125     SRV_SESSION_CREATED,
126     SRV_SESSION_ATTACHED,
127     SRV_SESSION_DETACHED,
128     SRV_SESSION_CLOSED
129   };
130 
131   /**
132     Constructs a server session
133 
134     @param error_cb       Default completion callback
135     @param err_cb_ctx     Plugin's context, opaque pointer that would
136                           be provided to callbacks. Might be NULL.
137   */
138   Srv_session(srv_session_error_cb err_cb, void *err_cb_ctx);
139 
140   /**
141     Opens a server session
142 
143     @return
144       session  on success
145       NULL     on failure
146   */
147   bool open();
148 
149   /**
150     Attaches the session to the current physical thread
151 
152     @returns
153       false   success
154       true    failure
155   */
156   bool attach();
157 
158   /**
159     Detaches the session from current physical thread.
160 
161     @returns
162       false success
163       true  failure
164   */
165   bool detach();
166 
167   /**
168     Closes the session
169 
170     @returns
171       false Session successfully closed
172       true  Session wasn't found or key doesn't match
173   */
174   bool close();
175 
176   /**
177     Returns if the session is in attached state
178 
179     @returns
180       false   Not attached
181       true    Attached
182   */
is_attached()183   inline bool is_attached() const { return state == SRV_SESSION_ATTACHED; }
184 
185   /**
186     Executes a server command.
187 
188     @param command  Command to be executed
189     @param data     Command's arguments
190     @param client_cs  The charset for the string data input (COM_QUERY
191                       for example)
192     @param command_callbacks  Callbacks to be used by the server to encode data
193                               and to communicate with the client (plugin) side.
194     @param text_or_binary     See enum cs_text_or_binary
195     @param callbacks_context  Context passed to the callbacks
196 
197     @returns
198       1   error
199       0   success
200   */
201   int execute_command(enum enum_server_command command,
202                       const union COM_DATA * data,
203                       const CHARSET_INFO * client_cs,
204                       const struct st_command_service_cbs * command_callbacks,
205                       enum cs_text_or_binary text_or_binary,
206                       void * callbacks_context);
207 
208   /**
209     Returns the internal THD object
210   */
get_thd()211   inline THD* get_thd() { return &thd; }
212 
213   /**
214     Returns the ID of a session.
215 
216     The value returned from THD::thread_id()
217   */
get_session_id()218   my_thread_id get_session_id() const { return thd.thread_id(); }
219 
220   /**
221     Returns the client port.
222 
223     @note The client port in SHOW PROCESSLIST, INFORMATION_SCHEMA.PROCESSLIST.
224     This port is NOT shown in PERFORMANCE_SCHEMA.THREADS.
225   */
get_client_port()226   uint16_t get_client_port() const { return thd.peer_port; }
227 
228   /**
229     Sets the client port.
230 
231     @note The client port in SHOW PROCESSLIST, INFORMATION_SCHEMA.PROCESSLIST.
232     This port is NOT shown in PERFORMANCE_SCHEMA.THREADS.
233 
234     @param port  Port number
235   */
236   void set_client_port(uint16_t port);
237 
238   /**
239     Returns the current database of a session.
240 
241     @note This call is not thread-safe. Don't invoke the method from a thread
242           different than the one in which the invocation happens. This means
243           that the call should NOT happen during run_command(). The value
244           returned is valid until the next run_command() call, which may
245           change it.
246   */
get_current_database()247   LEX_CSTRING get_current_database() const { return thd.db(); }
248 
249   /**
250     Sets the connection type.
251 
252     @see enum_vio_type
253 
254     @note If NO_VIO_TYPE passed as type the call will fail.
255 
256     @return
257       false success
258       true  failure
259   */
260   bool set_connection_type(enum_vio_type type);
261 
262   struct st_err_protocol_ctx
263   {
st_err_protocol_ctxst_err_protocol_ctx264     st_err_protocol_ctx(srv_session_error_cb h, void *h_ctx) :
265        handler(h), handler_context(h_ctx) {}
266 
267     srv_session_error_cb handler;
268     void *handler_context;
269   };
270 private:
271   /**
272     Sets session's state to attached
273 
274     @param stack  New stack address
275   */
276   void set_attached(const char *stack);
277 
278   /**
279     Changes the state of a session to detached
280   */
281   void set_detached();
282 
283   THD thd;
284   Diagnostics_area da;
285   st_err_protocol_ctx err_protocol_ctx;
286   Protocol_callback protocol_error;
287 
288   srv_session_state state;
289   enum_vio_type vio_type;
290 
291   class Session_backup_and_attach
292   {
293   public:
294     /**
295       Constructs a session state object. Saves state then attaches a session.
296       Uses RAII.
297 
298       @param sess Session to backup
299     */
300     Session_backup_and_attach(Srv_session *sess, bool is_close_session);
301 
302     /**
303       Destructs the session state object. In other words it restores to
304       previous state.
305     */
306     ~Session_backup_and_attach();
307 
308   private:
309     Srv_session *session;
310     Srv_session *old_session; /* used in srv_session threads */
311     THD *backup_thd;
312     bool in_close_session;
313   public:
314     bool attach_error;
315   };
316 };
317 
318 #endif /* SRV_SESSION_H */
319