From a2dbb10eb14801370522ec248e1d819eb38a83a2 Mon Sep 17 00:00:00 2001 From: MySQL Team Date: Fri, 20 Oct 2000 22:26:48 +0000 Subject: Update libmysql to 3.23 version. No major changes visible to the user - mostly bug fixes and other maintenance-oriented changes. --- ext/mysql/libmysql/net.c | 170 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 115 insertions(+), 55 deletions(-) (limited to 'ext/mysql/libmysql/net.c') diff --git a/ext/mysql/libmysql/net.c b/ext/mysql/libmysql/net.c index 9af0a54c3d..3326851028 100644 --- a/ext/mysql/libmysql/net.c +++ b/ext/mysql/libmysql/net.c @@ -1,5 +1,5 @@ -/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind */ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB +This file is public domain and comes with NO WARRANTY of any kind */ /* Write and read of logical packets to/from socket ** Writes are cached into net_buffer_length big packets. @@ -8,7 +8,7 @@ ** 3 byte length & 1 byte package-number. */ -#ifdef _WIN32 +#ifdef __WIN__ #include #endif #include @@ -16,15 +16,29 @@ #include #include #include "mysql.h" +#include "mysqld_error.h" #include #include #include #include -#if !defined(__WIN32__) && !defined(MSDOS) +#ifdef MYSQL_SERVER +ulong max_allowed_packet=65536; +extern ulong net_read_timeout,net_write_timeout; +extern uint test_flags; +#else +ulong max_allowed_packet=16*1024*1024L; +ulong net_read_timeout= NET_READ_TIMEOUT; +ulong net_write_timeout= NET_WRITE_TIMEOUT; +#endif +ulong net_buffer_length=8192; /* Default length. Enlarged if necessary */ + +#if !defined(__WIN__) && !defined(MSDOS) #include +#else +#undef MYSQL_SERVER // Win32 can't handle interrupts #endif -#if !defined(MSDOS) && !defined(__WIN32__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) +#if !defined(MSDOS) && !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__) #include #include #include @@ -41,11 +55,12 @@ void sql_print_error(const char *format,...); extern ulong mysqld_net_retry_count; #else typedef my_bool thr_alarm_t; +typedef my_bool ALARM; #define thr_alarm_init(A) (*A)=0 #define thr_alarm_in_use(A) (A) #define thr_end_alarm(A) -#define thr_alarm(A,B) local_thr_alarm((A),(B)) -static inline int local_thr_alarm(my_bool *A,int B __attribute__((unused))) +#define thr_alarm(A,B,C) local_thr_alarm((A),(B),(C)) +static inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __attribute__((unused))) { *A=1; return 0; @@ -58,8 +73,8 @@ static inline int local_thr_alarm(my_bool *A,int B __attribute__((unused))) extern ulong bytes_sent, bytes_received; extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received; #else -#undef thread_safe_add -#define thread_safe_add(A,B,C) +#undef statistic_add +#define statistic_add(A,B,C) #endif /* @@ -68,14 +83,6 @@ extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received; ** can't normally do this the client should have a bigger max-buffer. */ -#ifdef MYSQL_SERVER -ulong max_allowed_packet=65536; -extern uint test_flags; -#else -ulong max_allowed_packet=24*1024*1024L; -#endif -ulong net_buffer_length=8192; /* Default length. Enlarged if necessary */ - #define TEST_BLOCKING 8 static int net_write_buff(NET *net,const char *packet,uint len); @@ -90,19 +97,20 @@ int my_net_init(NET *net, Vio* vio) max_allowed_packet=net_buffer_length; net->buff_end=net->buff+(net->max_packet=net_buffer_length); net->vio = vio; - net->error=net->return_errno=0; - net->timeout=NET_READ_TIMEOUT; /* Timeout for read */ + net->no_send_ok = 0; + net->error=0; net->return_errno=0; net->return_status=0; + net->timeout=(uint) net_read_timeout; /* Timeout for read */ net->pkt_nr=0; net->write_pos=net->read_pos = net->buff; net->last_error[0]=0; - net->compress=net->more=0; + net->compress=0; net->reading_or_writing=0; net->where_b = net->remain_in_buf=0; net->last_errno=0; if (vio != 0) /* If real connection */ { net->fd = vio_fd(vio); /* For perl DBI/DBD */ -#if defined(MYSQL_SERVER) && !defined(___WIN32__) && !defined(__EMX__) +#if defined(MYSQL_SERVER) && !defined(___WIN__) && !defined(__EMX__) if (!(test_flags & TEST_BLOCKING)) vio_blocking(vio, FALSE); #endif @@ -125,19 +133,12 @@ static my_bool net_realloc(NET *net, ulong length) ulong pkt_length; if (length >= max_allowed_packet) { - DBUG_PRINT("error",("Packet too large (%ld)", length)); -#ifdef MYSQL_SERVER - sql_print_error("Packet too large (%ld)\n", length); -#else - fprintf(stderr,"Packet too large (%ld)\n", length); -#endif + DBUG_PRINT("error",("Packet too large (%lu)", length)); net->error=1; -#ifdef MYSQL_SERVER net->last_errno=ER_NET_PACKET_TOO_LARGE; -#endif return 1; } - pkt_length = (length+IO_SIZE) & ~(IO_SIZE-1); + pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1); if (!(buff=(uchar*) my_realloc((char*) net->buff, pkt_length, MYF(MY_WME)))) { net->error=1; @@ -153,37 +154,40 @@ static my_bool net_realloc(NET *net, ulong length) /* Remove unwanted characters from connection */ -#ifndef MYSQL_SERVER void net_clear(NET *net) { #ifndef EXTRA_DEBUG int count; - vio_blocking(net->vio, FALSE); + bool is_blocking=vio_is_blocking(net->vio); + if (is_blocking) + vio_blocking(net->vio, FALSE); if (!vio_is_blocking(net->vio)) /* Safety if SSL */ { while ( (count = vio_read(net->vio, (char*) (net->buff), net->max_packet)) > 0) DBUG_PRINT("info",("skipped %d bytes from file: %s", count,vio_description(net->vio))); + if (is_blocking) + vio_blocking(net->vio, TRUE); } #endif /* EXTRA_DEBUG */ net->pkt_nr=0; /* Ready for new command */ net->write_pos=net->buff; } -#endif /* MYSQL_SERVER */ /* Flush write_buffer if not empty. */ int net_flush(NET *net) { int error=0; + DBUG_ENTER("net_flush"); if (net->buff != net->write_pos) { error=net_real_write(net,(char*) net->buff, (uint) (net->write_pos - net->buff)); net->write_pos=net->buff; } - return error; + DBUG_RETURN(error); } @@ -253,9 +257,17 @@ net_real_write(NET *net,const char *packet,ulong len) int length; char *pos,*end; thr_alarm_t alarmed; +#if (!defined(__WIN__) && !defined(__EMX__)) + ALARM alarm_buff; +#endif uint retry_count=0; my_bool net_blocking = vio_is_blocking(net->vio); + DBUG_ENTER("net_real_write"); + + if (net->error == 2) + DBUG_RETURN(-1); /* socket can't be used */ + net->reading_or_writing=2; #ifdef HAVE_COMPRESS if (net->compress) { @@ -267,9 +279,10 @@ net_real_write(NET *net,const char *packet,ulong len) { #ifdef MYSQL_SERVER net->last_errno=ER_OUT_OF_RESOURCES; - net->error=1; + net->error=2; #endif - return 1; + net->reading_or_writing=0; + DBUG_RETURN(1); } memcpy(b+header_length,packet,len); @@ -291,7 +304,7 @@ net_real_write(NET *net,const char *packet,ulong len) #ifdef MYSQL_SERVER thr_alarm_init(&alarmed); if (net_blocking) - thr_alarm(&alarmed,NET_WRITE_TIMEOUT); + thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff); #else alarmed=0; #endif /* MYSQL_SERVER */ @@ -302,10 +315,10 @@ net_real_write(NET *net,const char *packet,ulong len) if ((int) (length=vio_write(net->vio,pos,(size_t) (end-pos))) <= 0) { my_bool interrupted = vio_should_retry(net->vio); -#if (!defined(__WIN32__) && !defined(__EMX__)) +#if (!defined(__WIN__) && !defined(__EMX__)) if ((interrupted || length==0) && !thr_alarm_in_use(alarmed)) { - if (!thr_alarm(&alarmed,NET_WRITE_TIMEOUT)) + if (!thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff)) { /* Always true for client */ if (!vio_is_blocking(net->vio)) { @@ -318,7 +331,7 @@ net_real_write(NET *net,const char *packet,ulong len) "%s: my_net_write: fcntl returned error %d, aborting thread\n", my_progname,vio_errno(net->vio)); #endif /* EXTRA_DEBUG */ - net->error=1; /* Close socket */ + net->error=2; /* Close socket */ goto end; } } @@ -327,7 +340,7 @@ net_real_write(NET *net,const char *packet,ulong len) } } else -#endif /* (!defined(__WIN32__) && !defined(__EMX__)) */ +#endif /* (!defined(__WIN__) && !defined(__EMX__)) */ if (thr_alarm_in_use(alarmed) && !thr_got_alarm(alarmed) && interrupted) { @@ -345,7 +358,7 @@ net_real_write(NET *net,const char *packet,ulong len) continue; } #endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */ - net->error=1; /* Close socket */ + net->error=2; /* Close socket */ #ifdef MYSQL_SERVER net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED : ER_NET_ERROR_ON_WRITE); @@ -353,9 +366,9 @@ net_real_write(NET *net,const char *packet,ulong len) break; } pos+=length; - thread_safe_add(bytes_sent,length,&LOCK_bytes_sent); + statistic_add(bytes_sent,length,&LOCK_bytes_sent); } -#ifndef __WIN32__ +#ifndef __WIN__ end: #endif #ifdef HAVE_COMPRESS @@ -367,7 +380,8 @@ net_real_write(NET *net,const char *packet,ulong len) thr_end_alarm(&alarmed); vio_blocking(net->vio, net_blocking); } - return (int) (pos != end); + net->reading_or_writing=0; + DBUG_RETURN(((int) (pos != end))); } @@ -375,6 +389,43 @@ net_real_write(NET *net,const char *packet,ulong len) ** Read something from server/clinet *****************************************************************************/ +#ifdef MYSQL_SERVER + +/* + Help function to clear the commuication buffer when we get a too + big packet +*/ + +static void my_net_skip_rest(NET *net, ulong remain, thr_alarm_t *alarmed) +{ + char buff[1024]; + ALARM alarm_buff; + uint retry_count=0; + if (!thr_alarm_in_use(alarmed)) + { + if (!thr_alarm(alarmed,net->timeout,&alarm_buff) || + (!vio_is_blocking(net->vio) && vio_blocking(net->vio,TRUE) < 0)) + return; // Can't setup, abort + } + while (remain > 0) + { + ulong length; + if ((int) (length=vio_read(net->vio,(char*) net->buff,remain)) <= 0L) + { + my_bool interrupted = vio_should_retry(net->vio); + if (!thr_got_alarm(alarmed) && interrupted) + { /* Probably in MIT threads */ + if (retry_count++ < RETRY_COUNT) + continue; + } + return; + } + remain -=(ulong) length; + statistic_add(bytes_received,(ulong) length,&LOCK_bytes_received); + } +} +#endif /* MYSQL_SERVER */ + static uint my_real_read(NET *net, ulong *complen) @@ -384,15 +435,19 @@ my_real_read(NET *net, ulong *complen) uint i,retry_count=0; ulong len=packet_error; thr_alarm_t alarmed; +#if (!defined(__WIN__) && !defined(__EMX__)) || defined(MYSQL_SERVER) + ALARM alarm_buff; +#endif my_bool net_blocking=vio_is_blocking(net->vio); ulong remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE : NET_HEADER_SIZE); *complen = 0; + net->reading_or_writing=1; thr_alarm_init(&alarmed); #ifdef MYSQL_SERVER if (net_blocking) - thr_alarm(&alarmed,net->timeout); + thr_alarm(&alarmed,net->timeout,&alarm_buff); #endif /* MYSQL_SERVER */ pos = net->buff + net->where_b; /* net->packet -4 */ @@ -407,7 +462,7 @@ my_real_read(NET *net, ulong *complen) DBUG_PRINT("info",("vio_read returned %d, errno: %d", length, vio_errno(net->vio))); -#if (!defined(__WIN32__) && !defined(__EMX__)) || !defined(MYSQL_SERVER) +#if (!defined(__WIN__) && !defined(__EMX__)) || defined(MYSQL_SERVER) /* We got an error that there was no data on the socket. We now set up an alarm to not 'read forever', change the socket to non blocking @@ -415,7 +470,7 @@ my_real_read(NET *net, ulong *complen) */ if ((interrupted || length == 0) && !thr_alarm_in_use(alarmed)) { - if (!thr_alarm(&alarmed,net->timeout)) /* Don't wait too long */ + if (!thr_alarm(&alarmed,net->timeout,&alarm_buff)) /* Don't wait too long */ { if (!vio_is_blocking(net->vio)) { @@ -433,7 +488,7 @@ my_real_read(NET *net, ulong *complen) my_progname,vio_errno(net->vio)); #endif /* EXTRA_DEBUG */ len= packet_error; - net->error=1; /* Close socket */ + net->error=2; /* Close socket */ #ifdef MYSQL_SERVER net->last_errno=ER_NET_FCNTL_ERROR; #endif @@ -444,7 +499,7 @@ my_real_read(NET *net, ulong *complen) continue; } } -#endif /* (!defined(__WIN32__) && !defined(__EMX__)) || !defined(MYSQL_SERVER) */ +#endif /* (!defined(__WIN__) && !defined(__EMX__)) || defined(MYSQL_SERVER) */ if (thr_alarm_in_use(alarmed) && !thr_got_alarm(alarmed) && interrupted) { /* Probably in MIT threads */ @@ -464,7 +519,7 @@ my_real_read(NET *net, ulong *complen) #endif DBUG_PRINT("error",("Couldn't read packet: remain: %d errno: %d length: %d alarmed: %d", remain,vio_errno(net->vio),length,alarmed)); len= packet_error; - net->error=1; /* Close socket */ + net->error=2; /* Close socket */ #ifdef MYSQL_SERVER net->last_errno= (interrupted ? ER_NET_READ_INTERRUPTED : ER_NET_READ_ERROR); @@ -473,7 +528,7 @@ my_real_read(NET *net, ulong *complen) } remain -= (ulong) length; pos+= (ulong) length; - thread_safe_add(bytes_received,(ulong) length,&LOCK_bytes_received); + statistic_add(bytes_received,(ulong) length,&LOCK_bytes_received); } if (i == 0) { /* First parts is packet length */ @@ -512,8 +567,13 @@ my_real_read(NET *net, ulong *complen) /* The necessary size of net->buff */ if (helping >= net->max_packet) { - if (net_realloc(net,helping)) + /* We must allocate one extra byte for the end null */ + if (net_realloc(net,helping+1)) { +#ifdef MYSQL_SERVER + if (i == 1) + my_net_skip_rest(net, len, &alarmed); +#endif len= packet_error; /* Return error */ goto end; } @@ -529,10 +589,10 @@ end: thr_end_alarm(&alarmed); vio_blocking(net->vio, net_blocking); } + net->reading_or_writing=0; return(len); } - uint my_net_read(NET *net) { @@ -587,7 +647,7 @@ my_net_read(NET *net) if (my_uncompress((byte*) net->buff + net->where_b, &len, &complen)) { len= packet_error; - net->error=1; /* caller will close socket */ + net->error=2; /* caller will close socket */ #ifdef MYSQL_SERVER net->last_errno=ER_NET_UNCOMPRESS_ERROR; #endif -- cgit v1.2.1