MySQL server listening Client Connection source code

Source: Internet
Author: User

In the following code, some struct types are unclear, such as THD, st_vio, and pollfd. However, we can see that MySQL uses the Select model to receive client connections. It is also found on the internet that unix_sock refers to the communication between different processes on the same machine, such as named pipes. Ip_sock refers to the communication between different hosts.

Void handle_connections_sockets ()

{

My_socket UNINIT_VAR (sock), UNINIT_VAR (new_sock );

Uint error_count = 0;

THD * thd;

Struct sockaddr_storage cAddr;

Int ip_flags = 0, socket_flags = 0, flags = 0, retval;

St_vio * vi_tmp;

# Ifdef HAVE_POLL

Int socket_count = 0;

Struct pollfd fds [2]; // for ip_sock and unix_sock

# Else

Fd_set readFDs, clientFDs;

Uint max_used_connection = (uint) (max (ip_sock, unix_sock) + 1 );

# Endif

 

DBUG_ENTER ("handle_connections_sockets ");

 

# Ifndef HAVE_POLL

FD_ZERO (& clientFDs );

# Endif

 

If (ip_sock! = INVALID_SOCKET)

{

# Ifdef HAVE_POLL

Fds [socket_count]. fd = ip_sock;

Fds [socket_count]. events = POLLIN;

Socket_count ++;

# Else

FD_SET (ip_sock, & clientFDs );

# Endif

# Ifdef HAVE_FCNTL

Ip_flags = fcntl (ip_sock, F_GETFL, 0 );

# Endif

}

# Ifdef HAVE_SYS_UN_H

# Ifdef HAVE_POLL

Fds [socket_count]. fd = unix_sock;

Fds [socket_count]. events = POLLIN;

Socket_count ++;

# Else

FD_SET (unix_sock, & clientFDs );

# Endif

# Ifdef HAVE_FCNTL

Socket_flags = fcntl (unix_sock, F_GETFL, 0 );

# Endif

# Endif

 

DBUG_PRINT ("general", ("Waiting for connections ."));

MAYBE_BROKEN_SYSCALL;

While (! Abort_loop)

{

# Ifdef HAVE_POLL

Retval = poll (fds, socket_count,-1 );

# Else

ReadFDs = clientFDs;

 

Retval = select (int) max_used_connection, & readFDs, 0); // wait for the client to connect, return an error or connection

# Endif

 

If (retval <0)

{

If (socket_errno! = SOCKET_EINTR)

{

If (! Select_errors ++ &&! Abort_loop)/* purecov: inspected */

SQL _print_error ("mysqld: Got error % d from select", socket_errno);/* purecov: inspected */

}

MAYBE_BROKEN_SYSCALL

Continue;

}

 

If (abort_loop)

{

MAYBE_BROKEN_SYSCALL;

Break;

}

 

/* Is this a new connection request? */

# Ifdef HAVE_POLL

For (int I = 0; I <socket_count; ++ I)

{

If (fds [I]. revents & POLLIN) // read the Event Type

{

Sock = fds [I]. fd;

# Ifdef HAVE_FCNTL

Flags = fcntl (sock, F_GETFL, 0 );

# Else

Flags = 0;

# Endif // HAVE_FCNTL

Break;

}

}

# Else // HAVE_POLL

# Ifdef HAVE_SYS_UN_H

If (FD_ISSET (unix_sock, & readFDs ))

{

Sock = unix_sock;

Flags = socket_flags;

}

Else

# Endif // HAVE_SYS_UN_H

{

Sock = ip_sock;

Flags = ip_flags;

}

# Endif // HAVE_POLL

 

# If! Defined (NO_FCNTL_NONBLOCK)

If (! (Test_flags & TEST_BLOCKING ))

{

# If defined (O_NONBLOCK)

Fcntl (sock, F_SETFL, flags | O_NONBLOCK); // sets the non-blocking mode.

# Elif defined (O_NDELAY)

Fcntl (sock, F_SETFL, flags | O_NDELAY );

# Endif

}

# Endif/* NO_FCNTL_NONBLOCK */

For (uint retry = 0; retry <MAX_ACCEPT_RETRY; retry ++)

{

Size_socket length = sizeof (struct sockaddr_storage );

New_sock = accept (sock, (struct sockaddr *) (& cAddr), // accept the connection, and use the blocking method for the connection

& Length );

If (new_sock! = INVALID_SOCKET |

(Socket_errno! = SOCKET_EINTR & socket_errno! = SOCKET_EAGAIN ))

Break;

MAYBE_BROKEN_SYSCALL;

# If! Defined (NO_FCNTL_NONBLOCK)

If (! (Test_flags & TEST_BLOCKING ))

{

If (retry = MAX_ACCEPT_RETRY-1)

Fcntl (sock, F_SETFL, flags); // Try without O_NONBLOCK

}

# Endif

}

# If! Defined (NO_FCNTL_NONBLOCK)

If (! (Test_flags & TEST_BLOCKING ))

Fcntl (sock, F_SETFL, flags );

# Endif

If (new_sock = INVALID_SOCKET)

{

If (error_count ++ & 255) = 0) // This can happen often

SQL _perror ("Error in accept ");

MAYBE_BROKEN_SYSCALL;

If (socket_errno = SOCKET_ENFILE | socket_errno = SOCKET_EMFILE)

Sleep (1); // Give other threads some time

Continue;

}

 

# Ifdef HAVE_LIBWRAP

{

If (sock = ip_sock)

{

Struct request_info req;

Signal (SIGCHLD, SIG_DFL );

Request_init (& req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL );

My_fromhost (& req );

If (! My_hosts_access (& req) // checks whether the host has access permissions.

{// Connection denied if the host is not granted the permission

/*

This may be stupid but refuse () already des an exit (0)

Which we surely don't want...

Clean_exit ()-same stupid thing...

*/

Syslog (deny_severity, "refused connect from % s ",

My_eval_client (& req ));

 

/*

C ++ sucks (the gibberish in front just translates the supplied

Sink function pointer in the req structure from a void (* sink )();

To a void (* sink) (int) if you omit the cast, the C ++ compiler

Will cry...

*/

If (req. sink)

(Void (*) (int) req. sink) (req. fd );

 

(Void) shutdown (new_sock, SHUT_RDWR); // close the connection

(Void) closesocket (new_sock );

Continue;

}

}

}

# Endif/* HAVE_LIBWRAP */

 

{

Size_socket dummyLen;

Struct sockaddr_storage dummy;

DummyLen = sizeof (dummy );

If (getsockname (new_sock, (struct sockaddr *) & dummy,

(SOCKET_SIZE_TYPE *) & dummyLen) <0)

{

SQL _perror ("Error on new connection socket ");

(Void) shutdown (new_sock, SHUT_RDWR );

(Void) closesocket (new_sock );

Continue;

}

}

 

/*

** Don't allow too restart connections

*/

 

If (! (Thd = new THD) // allocate a processing structure for the connection, which will be used for the thread later

{

(Void) shutdown (new_sock, SHUT_RDWR );

(Void) closesocket (new_sock );

Continue;

}

If (! (Viow_tmp = viow_new (new_sock,

Sock = unix_sock? Via_type_socket:

Via_type_tcpip,

Sock = unix_sock? VIO_LOCALHOST: 0) |

My_net_init (& thd-> net, vio_tmp) // initialize the network

{

/*

Only delete the temporary vio if we didn't already attach it to

NET object. The destructor in THD will delete any initialized net

Structure.

*/

If (vi_tmp & thd-> net. vio! = Vio_tmp)

Viow_delete (viow_tmp );

Else

{

(Void) shutdown (new_sock, SHUT_RDWR );

(Void) closesocket (new_sock );

}

Delete thd;

Continue;

}

If (sock = unix_sock)

Thd-> security_ctx-> host = (char *) my_localhost;

 

Create_new_thread (thd); // prepare to allocate a thread for the connection

}

DBUG_VOID_RETURN;

}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.