diff options
author | msvensson@neptunus.(none) <> | 2006-02-27 16:44:23 +0100 |
---|---|---|
committer | msvensson@neptunus.(none) <> | 2006-02-27 16:44:23 +0100 |
commit | e2423d5e0516e77198c3d50e07e6a0798c02d4e2 (patch) | |
tree | ecca37e8c794c1b0031b82c402e26b01690ef5cb /sql/net_serv.cc | |
parent | 44a28553823b76d2f0d828aa021622c8547260de (diff) | |
download | mariadb-git-e2423d5e0516e77198c3d50e07e6a0798c02d4e2.tar.gz |
BUG#2845 client fails to reconnect if using TCP/IP
- Use 'poll' if available
- Check that sd <= FD_SETSIZE if using 'select'
- Handle case when 'net_data_is_ready' returns -1, ie. sd > FD_SETSIZE and 'select' is used
Diffstat (limited to 'sql/net_serv.cc')
-rw-r--r-- | sql/net_serv.cc | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/sql/net_serv.cc b/sql/net_serv.cc index ef56f0d77e2..b3ee28607ad 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -208,23 +208,40 @@ my_bool net_realloc(NET *net, ulong length) RETURN VALUES 0 No data to read 1 Data or EOF to read + -1 Don't know if data is ready or not */ -static my_bool net_data_is_ready(my_socket sd) +static int net_data_is_ready(my_socket sd) { +#ifdef HAVE_POLL + struct pollfd ufds; + int res; + + ufds.fd= sd; + ufds.events= POLLIN | POLLPRI; + if (!(res= poll(&ufds, 1, 0))) + return 0; + if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI))) + return 0; + return 1; +#else fd_set sfds; struct timeval tv; int res; + if (sd >= FD_SETSIZE) + return -1; + FD_ZERO(&sfds); FD_SET(sd, &sfds); tv.tv_sec= tv.tv_usec= 0; if ((res= select(sd+1, &sfds, NULL, NULL, &tv)) < 0) - return FALSE; + return 0; else return test(res ? FD_ISSET(sd, &sfds) : 0); +#endif } @@ -251,10 +268,10 @@ static my_bool net_data_is_ready(my_socket sd) void net_clear(NET *net) { - int count; + int count, ready; DBUG_ENTER("net_clear"); #if !defined(EMBEDDED_LIBRARY) - while(net_data_is_ready(net->vio->sd)) + while((ready= net_data_is_ready(net->vio->sd)) != 0) { /* The socket is ready */ if ((count= vio_read(net->vio, (char*) (net->buff), @@ -269,6 +286,10 @@ void net_clear(NET *net) } else { + /* No data to read and 'net_data_is_ready' returned "don't know" */ + if (ready == -1) + break; + DBUG_PRINT("info",("socket ready but only EOF to read - disconnected")); net->error= 2; break; |