28
28
29
29
/* Simple vio interface in C; The functions are implemented in violite.c */
30
30
31
+ #if !defined(_WIN32) && !defined(__APPLE__) && !defined(__SUNPRO_CC)
32
+ #define USE_PPOLL_IN_VIO
33
+ #endif
34
+
35
+ #if defined(__cplusplus) && defined(USE_PPOLL_IN_VIO)
36
+ #include < signal.h>
37
+ #include < atomic>
38
+ #endif
39
+
31
40
#ifdef __cplusplus
32
41
extern " C" {
33
42
#endif /* __cplusplus */
@@ -38,6 +47,9 @@ void init_vio_psi_keys();
38
47
39
48
#ifdef __cplusplus
40
49
typedef struct st_vio Vio;
50
+ #define MYSQL_VIO Vio*
51
+ #else
52
+ #define MYSQL_VIO void *
41
53
#endif /* __cplusplus */
42
54
43
55
enum enum_vio_type
@@ -104,13 +116,13 @@ enum enum_vio_io_event
104
116
#define VIO_LOCALHOST 1 /* a localhost connection */
105
117
#define VIO_BUFFERED_READ 2 /* use buffered read */
106
118
#define VIO_READ_BUFFER_SIZE 16384 /* size of read buffer */
107
- #define VIO_DESCRIPTION_SIZE 30 /* size of description */
108
119
109
- Vio * vio_new (my_socket sd , enum enum_vio_type type , uint flags );
110
- Vio * mysql_socket_vio_new (MYSQL_SOCKET mysql_socket , enum enum_vio_type type , uint flags );
120
+ MYSQL_VIO vio_new (my_socket sd, enum enum_vio_type type, uint flags);
121
+ MYSQL_VIO mysql_socket_vio_new (MYSQL_SOCKET mysql_socket, enum enum_vio_type type, uint flags);
122
+
111
123
#ifdef _WIN32
112
- Vio * vio_new_win32pipe (HANDLE hPipe );
113
- Vio * vio_new_win32shared_memory (HANDLE handle_file_map ,
124
+ MYSQL_VIO vio_new_win32pipe (HANDLE hPipe);
125
+ MYSQL_VIO vio_new_win32shared_memory (HANDLE handle_file_map,
114
126
HANDLE handle_map,
115
127
HANDLE event_server_wrote,
116
128
HANDLE event_server_read,
@@ -121,41 +133,42 @@ Vio* vio_new_win32shared_memory(HANDLE handle_file_map,
121
133
#define HANDLE void *
122
134
#endif /* _WIN32 */
123
135
124
- void vio_delete (Vio * vio );
125
- int vio_shutdown (Vio * vio );
126
- my_bool vio_reset (Vio * vio , enum enum_vio_type type ,
136
+ void vio_delete (MYSQL_VIO vio);
137
+ int vio_shutdown (MYSQL_VIO vio);
138
+ my_bool vio_reset (MYSQL_VIO vio, enum enum_vio_type type,
127
139
my_socket sd, void *ssl, uint flags);
128
- size_t vio_read (Vio * vio , uchar * buf , size_t size );
129
- size_t vio_read_buff (Vio * vio , uchar * buf , size_t size );
130
- size_t vio_write (Vio * vio , const uchar * buf , size_t size );
140
+ size_t vio_read (MYSQL_VIO vio, uchar * buf, size_t size);
141
+ size_t vio_read_buff (MYSQL_VIO vio, uchar * buf, size_t size);
142
+ size_t vio_write (MYSQL_VIO vio, const uchar * buf, size_t size);
131
143
/* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible */
132
- int vio_fastsend (Vio * vio );
144
+ int vio_fastsend (MYSQL_VIO vio);
133
145
/* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible */
134
- int vio_keepalive (Vio * vio , my_bool onoff );
146
+ int vio_keepalive (MYSQL_VIO vio, my_bool onoff);
135
147
/* Whenever we should retry the last read/write operation. */
136
- my_bool vio_should_retry (Vio * vio );
148
+ my_bool vio_should_retry (MYSQL_VIO vio);
137
149
/* Check that operation was timed out */
138
- my_bool vio_was_timeout (Vio * vio );
150
+ my_bool vio_was_timeout (MYSQL_VIO vio);
139
151
/* Short text description of the socket for those, who are curious.. */
140
- const char * vio_description (Vio * vio );
152
+ #define VIO_DESCRIPTION_SIZE 30 /* size of description */
153
+ void vio_description (MYSQL_VIO vio, char *buf);
141
154
/* Return the type of the connection */
142
- enum enum_vio_type vio_type (Vio * vio );
155
+ enum enum_vio_type vio_type (MYSQL_VIO vio);
143
156
/* Return last error number */
144
- int vio_errno (Vio * vio );
157
+ int vio_errno (MYSQL_VIO vio);
145
158
/* Get socket number */
146
- my_socket vio_fd (Vio * vio );
159
+ my_socket vio_fd (MYSQL_VIO vio);
147
160
/* Remote peer's address and name in text form */
148
- my_bool vio_peer_addr (Vio * vio , char * buf , uint16 * port , size_t buflen );
161
+ my_bool vio_peer_addr (MYSQL_VIO vio, char *buf, uint16 *port, size_t buflen);
149
162
/* Wait for an I/O event notification. */
150
- int vio_io_wait (Vio * vio , enum enum_vio_io_event event , int timeout );
151
- my_bool vio_is_connected (Vio * vio );
163
+ int vio_io_wait (MYSQL_VIO vio, enum enum_vio_io_event event, int timeout);
164
+ my_bool vio_is_connected (MYSQL_VIO vio);
152
165
#ifndef DBUG_OFF
153
- ssize_t vio_pending (Vio * vio );
166
+ ssize_t vio_pending (MYSQL_VIO vio);
154
167
#endif
155
168
/* Set timeout for a network operation. */
156
- int vio_timeout (Vio * vio , uint which , int timeout_sec );
169
+ int vio_timeout (MYSQL_VIO vio, uint which, int timeout_sec);
157
170
/* Connect to a peer. */
158
- my_bool vio_socket_connect (Vio * vio , struct sockaddr * addr , socklen_t len ,
171
+ my_bool vio_socket_connect (MYSQL_VIO vio, struct sockaddr *addr, socklen_t len,
159
172
int timeout);
160
173
161
174
my_bool vio_get_normalized_ip_string (const struct sockaddr *addr, size_t addr_length,
@@ -207,8 +220,8 @@ struct st_VioSSLFd
207
220
SSL_CTX *ssl_context;
208
221
};
209
222
210
- int sslaccept (struct st_VioSSLFd * , Vio * , long timeout , unsigned long * errptr );
211
- int sslconnect (struct st_VioSSLFd * , Vio * , long timeout , unsigned long * errptr );
223
+ int sslaccept (struct st_VioSSLFd *, MYSQL_VIO , long timeout, unsigned long *errptr);
224
+ int sslconnect (struct st_VioSSLFd *, MYSQL_VIO , long timeout, unsigned long *errptr);
212
225
213
226
struct st_VioSSLFd
214
227
*new_VioSSLConnectorFd (const char *key_file, const char *cert_file,
@@ -258,32 +271,49 @@ enum SSL_type
258
271
SSL_TYPE_SPECIFIED
259
272
};
260
273
261
-
274
+ # ifdef __cplusplus
262
275
/* HFTODO - hide this if we don't want client in embedded server */
263
276
/* This structure is for every connection on both sides */
264
277
struct st_vio
265
278
{
266
279
MYSQL_SOCKET mysql_socket; /* Instrumented socket */
267
- my_bool localhost ; /* Are we from localhost? */
280
+ bool localhost= { false }; /* Are we from localhost? */
281
+ enum_vio_type type= { NO_VIO_TYPE }; /* Type of connection */
282
+
283
+ int read_timeout= { -1 }; /* Timeout value (ms) for read ops. */
284
+ int write_timeout= { -1 }; /* Timeout value (ms) for write ops. */
285
+ int retry_count= { 1 }; /* Retry count */
286
+ bool inactive= { false }; /* Connection has been shutdown */
287
+
268
288
struct sockaddr_storage local; /* Local internet address */
269
289
struct sockaddr_storage remote; /* Remote internet address */
270
- size_t addrLen ; /* Length of remote address */
271
- enum enum_vio_type type ; /* Type of connection */
272
- my_bool inactive ; /* Connection inactive (has been shutdown) */
273
- char desc [VIO_DESCRIPTION_SIZE ]; /* Description string. This
274
- member MUST NOT be
275
- used directly, but only
276
- via function
277
- "vio_description" */
278
- char * read_buffer ; /* buffer for vio_read_buff */
279
- char * read_pos ; /* start of unfetched data in the
280
- read buffer */
281
- char * read_end ; /* end of unfetched data */
282
- int read_timeout ; /* Timeout value (ms) for read ops. */
283
- int write_timeout ; /* Timeout value (ms) for write ops. */
284
- int retry_count ; /* Retry count */
290
+ size_t addrLen= { 0 }; /* Length of remote address */
291
+ char *read_buffer= { nullptr }; /* buffer for vio_read_buff */
292
+ char *read_pos= { nullptr }; /* start of unfetched data in the
293
+ read buffer */
294
+ char *read_end= { nullptr }; /* end of unfetched data */
295
+
296
+ #ifdef USE_PPOLL_IN_VIO
297
+ my_thread_t thread_id= { 0 }; // Thread PID
298
+ sigset_t signal_mask; // Signal mask
299
+ /*
300
+ Flag to indicate whether we are in poll or shutdown.
301
+ A true value of flag indicates either the socket
302
+ has called shutdown or it is sleeping on a poll call.
303
+ False value of this flag means that the socket is
304
+ not sleeping on a poll call.
305
+ This flag provides synchronization between two threads
306
+ one entering vio_io_wait and another entering vio_shutdown
307
+ for the same socket. If the other thread is waiting on poll
308
+ sleep, it wakes up the thread by sending a signal via
309
+ pthread_kill. Also it ensures that no other thread enters in
310
+ to a poll call if it's socket has undergone shutdown.
285
311
286
- /*
312
+ */
313
+ std::atomic_flag poll_shutdown_flag= ATOMIC_FLAG_INIT;
314
+ #endif
315
+
316
+ /*
287
317
VIO vtable interface to be implemented by VIO's like SSL, Socket,
288
318
Named Pipe, etc.
289
319
*/
@@ -292,49 +322,61 @@ struct st_vio
292
322
viodelete is responsible for cleaning up the VIO object by freeing
293
323
internal buffers, closing descriptors, handles.
294
324
*/
295
- void (* viodelete )(Vio * ) ;
296
- int (* vioerrno )(Vio * ) ;
297
- size_t (* read )(Vio * , uchar * , size_t );
298
- size_t (* write )(Vio * , const uchar * , size_t );
299
- int (* timeout )(Vio * , uint , my_bool );
300
- int (* viokeepalive )(Vio * , my_bool );
301
- int (* fastsend )(Vio * ) ;
302
- my_bool (* peer_addr )(Vio * , char * , uint16 * , size_t );
303
- void (* in_addr )(Vio * , struct sockaddr_storage * );
304
- my_bool (* should_retry )(Vio * ) ;
305
- my_bool (* was_timeout )(Vio * ) ;
325
+ void (*viodelete)(MYSQL_VIO)= { nullptr } ;
326
+ int (*vioerrno)(MYSQL_VIO)= { nullptr } ;
327
+ size_t (*read)(MYSQL_VIO , uchar *, size_t )= { nullptr } ;
328
+ size_t (*write)(MYSQL_VIO , const uchar *, size_t )= { nullptr } ;
329
+ int (*timeout)(MYSQL_VIO , uint, my_bool)= { nullptr } ;
330
+ int (*viokeepalive)(MYSQL_VIO , my_bool)= { nullptr } ;
331
+ int (*fastsend)(MYSQL_VIO)= { nullptr } ;
332
+ my_bool (*peer_addr)(MYSQL_VIO , char *, uint16*, size_t )= { nullptr } ;
333
+ void (*in_addr)(MYSQL_VIO , struct sockaddr_storage *)= { nullptr } ;
334
+ my_bool (*should_retry)(MYSQL_VIO)= { nullptr } ;
335
+ my_bool (*was_timeout)(MYSQL_VIO)= { nullptr } ;
306
336
/*
307
337
vioshutdown is resposnible to shutdown/close the channel, so that no
308
338
further communications can take place, however any related buffers,
309
339
descriptors, handles can remain valid after a shutdown.
310
340
*/
311
- int (* vioshutdown )(Vio * ) ;
312
- my_bool (* is_connected )(Vio * ) ;
313
- my_bool (* has_data ) (Vio * ) ;
314
- int (* io_wait )(Vio * , enum enum_vio_io_event , int );
315
- my_bool (* connect )(Vio * , struct sockaddr * , socklen_t , int );
341
+ int (*vioshutdown)(MYSQL_VIO)= { nullptr } ;
342
+ my_bool (*is_connected)(MYSQL_VIO)= { nullptr } ;
343
+ my_bool (*has_data) (MYSQL_VIO)= { nullptr } ;
344
+ int (*io_wait)(MYSQL_VIO , enum enum_vio_io_event, int )= { nullptr } ;
345
+ my_bool (*connect)(MYSQL_VIO , struct sockaddr *, socklen_t , int )= { nullptr } ;
316
346
#ifdef _WIN32
317
- OVERLAPPED overlapped ;
318
- HANDLE hPipe ;
347
+ OVERLAPPED overlapped = { 0 } ;
348
+ HANDLE hPipe { nullptr } ;
319
349
#endif
320
350
#ifdef HAVE_OPENSSL
321
- void * ssl_arg ;
351
+ void *ssl_arg= { nullptr } ;
322
352
#endif
323
353
#if defined (_WIN32) && !defined (EMBEDDED_LIBRARY)
324
- HANDLE handle_file_map ;
325
- char * handle_map ;
326
- HANDLE event_server_wrote ;
327
- HANDLE event_server_read ;
328
- HANDLE event_client_wrote ;
329
- HANDLE event_client_read ;
330
- HANDLE event_conn_closed ;
331
- size_t shared_memory_remain ;
332
- char * shared_memory_pos ;
354
+ HANDLE handle_file_map= { nullptr } ;
355
+ char *handle_map= { nullptr } ;
356
+ HANDLE event_server_wrote= { nullptr } ;
357
+ HANDLE event_server_read= { nullptr } ;
358
+ HANDLE event_client_wrote= { nullptr } ;
359
+ HANDLE event_client_read= { nullptr } ;
360
+ HANDLE event_conn_closed= { nullptr } ;
361
+ size_t shared_memory_remain= { 0 } ;
362
+ char *shared_memory_pos= { nullptr } ;
333
363
#endif /* _WIN32 && !EMBEDDED_LIBRARY */
364
+
365
+ private:
366
+ friend st_vio *internal_vio_create (uint flags);
367
+ friend void internal_vio_delete (st_vio *vio);
368
+ friend my_bool vio_reset (Vio* vio, enum_vio_type type,
369
+ my_socket sd, void *ssl, uint flags);
370
+
371
+ explicit st_vio (uint flags);
372
+ ~st_vio ();
373
+
374
+ public:
375
+ st_vio (const st_vio&) = delete ;
376
+ st_vio &operator =(const st_vio&) = delete ;
334
377
};
335
378
336
- #ifdef __cplusplus
337
379
}
338
- #endif
380
+ #endif /* __cpluscplus */
339
381
340
382
#endif /* vio_violite_h_ */
0 commit comments