Loading include/my_sys.h +2 −0 Original line number Diff line number Diff line Loading @@ -189,11 +189,13 @@ void __CDECL hfree(void *ptr); #endif #endif /* MSDOS */ #ifndef errno /* did we already get it? */ #ifdef HAVE_ERRNO_AS_DEFINE #include <errno.h> /* errno is a define */ #else extern int errno; /* declare errno */ #endif #endif /* #ifndef errno */ extern const char ** NEAR my_errmsg[]; extern char NEAR errbuff[NRERRBUFFS][ERRMSGSIZE]; extern char *home_dir; /* Home directory for user */ Loading mysys/hash.c +1 −1 Original line number Diff line number Diff line Loading @@ -175,7 +175,7 @@ static uint hash_rec_mask(HASH *hash,HASH_LINK *pos,uint buffmax, /* for compilers which can not handle inline */ static #if !defined(__SUNPRO_C) && !defined(__USLC__) && !defined(__sgi) #if !defined(__USLC__) && !defined(__sgi) inline #endif unsigned int rec_hashnr(HASH *hash,const byte *record) Loading mysys/my_bitmap.c +39 −226 Original line number Diff line number Diff line Loading @@ -16,18 +16,7 @@ /* Handling of uchar arrays as large bitmaps. API limitations (or, rather asserted safety assumptions, to encourage correct programming) * the size of the used bitmap is less than ~(uint) 0 * it's a multiple of 8 (for efficiency reasons) * when arguments are a bitmap and a bit number, the number must be within bitmap size * bitmap_set_prefix() is an exception - one can use ~0 to set all bits * when both arguments are bitmaps, they must be of the same size * bitmap_intersect() is an exception :) (for for Bitmap::intersect(ulonglong map2buff)) We assume that the size of the used bitmap is less than ~(uint) 0 TODO: Make assembler THREAD safe versions of these using test-and-set instructions Loading @@ -35,87 +24,70 @@ #include "mysys_priv.h" #include <my_bitmap.h> #include <assert.h> #include <m_string.h> static inline void bitmap_lock(MY_BITMAP* map) { #ifdef THREAD if (map->mutex) pthread_mutex_lock(map->mutex); if (map->thread_safe) pthread_mutex_lock(&map->mutex); #endif } static inline void bitmap_unlock(MY_BITMAP* map) { #ifdef THREAD if (map->mutex) pthread_mutex_unlock(map->mutex); if (map->thread_safe) pthread_mutex_unlock(&map->mutex); #endif } my_bool bitmap_init(MY_BITMAP *map, uchar *buf, uint bitmap_size, my_bool thread_safe) my_bool bitmap_init(MY_BITMAP *map, uint bitmap_size, my_bool thread_safe) { DBUG_ENTER("bitmap_init"); DBUG_ASSERT((bitmap_size & 7) == 0); bitmap_size/=8; if (!(map->bitmap=buf) && !(map->bitmap= (uchar*) my_malloc(bitmap_size + (thread_safe ? sizeof(pthread_mutex_t) : 0), if (!(map->bitmap=(uchar*) my_malloc((bitmap_size+7)/8, MYF(MY_WME | MY_ZEROFILL)))) return 1; map->bitmap_size=bitmap_size; DBUG_ASSERT(bitmap_size != ~(uint) 0); #ifdef THREAD if (thread_safe) { map->mutex=(pthread_mutex_t *)(map->bitmap+bitmap_size); pthread_mutex_init(map->mutex, MY_MUTEX_INIT_FAST); } else map->mutex=0; if ((map->thread_safe = thread_safe)) pthread_mutex_init(&map->mutex, MY_MUTEX_INIT_FAST); #endif DBUG_RETURN(0); map->bitmap_size=bitmap_size; return 0; } void bitmap_free(MY_BITMAP *map) { DBUG_ENTER("bitmap_free"); if (map->bitmap) { #ifdef THREAD if (map->mutex) pthread_mutex_destroy(map->mutex); #endif my_free((char*) map->bitmap, MYF(0)); map->bitmap=0; #ifdef THREAD if (map->thread_safe) pthread_mutex_destroy(&map->mutex); #endif } DBUG_VOID_RETURN; } void bitmap_set_bit(MY_BITMAP *map, uint bitmap_bit) { DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8); if (bitmap_bit < map->bitmap_size) { bitmap_lock(map); bitmap_fast_set_bit(map, bitmap_bit); map->bitmap[bitmap_bit / 8] |= (1 << (bitmap_bit & 7)); bitmap_unlock(map); } } uint bitmap_set_next(MY_BITMAP *map) { uchar *bitmap=map->bitmap; uint bit_found = MY_BIT_NONE; uint bitmap_size=map->bitmap_size*8; uint bitmap_size=map->bitmap_size; uint i; DBUG_ASSERT(map->bitmap); bitmap_lock(map); for (i=0; i < bitmap_size ; i++, bitmap++) { Loading @@ -141,191 +113,32 @@ uint bitmap_set_next(MY_BITMAP *map) void bitmap_clear_bit(MY_BITMAP *map, uint bitmap_bit) { DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8); bitmap_lock(map); bitmap_fast_clear_bit(map, bitmap_bit); bitmap_unlock(map); } void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size) if (bitmap_bit < map->bitmap_size) { uint prefix_bytes, prefix_bits; DBUG_ASSERT(map->bitmap && (prefix_size <= map->bitmap_size*8 || prefix_size == (uint) ~0)); bitmap_lock(map); set_if_smaller(prefix_size, map->bitmap_size*8); if ((prefix_bytes= prefix_size / 8)) memset(map->bitmap, 0xff, prefix_bytes); if ((prefix_bits= prefix_size & 7)) map->bitmap[prefix_bytes++]= (1 << prefix_bits)-1; if (prefix_bytes < map->bitmap_size) bzero(map->bitmap+prefix_bytes, map->bitmap_size-prefix_bytes); map->bitmap[bitmap_bit / 8] &= ~ (1 << (bitmap_bit & 7)); bitmap_unlock(map); } void bitmap_clear_all(MY_BITMAP *map) { bitmap_set_prefix(map, 0); } void bitmap_set_all(MY_BITMAP* map) { bitmap_set_prefix(map, ~0); } my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size) { uint prefix_bits= prefix_size & 7, res= 0; uchar *m= map->bitmap, *end_prefix= map->bitmap+prefix_size/8, *end= map->bitmap+map->bitmap_size; DBUG_ASSERT(map->bitmap && prefix_size <= map->bitmap_size*8); bitmap_lock((MY_BITMAP *)map); while (m < end_prefix) if (*m++ != 0xff) goto ret; if (prefix_bits && *m++ != (1 << prefix_bits)-1) goto ret; while (m < end) if (*m++ != 0) goto ret; res=1; ret: bitmap_unlock((MY_BITMAP *)map); return res; } my_bool bitmap_is_clear_all(const MY_BITMAP *map) { return bitmap_is_prefix(map, 0); } my_bool bitmap_is_set_all(const MY_BITMAP *map) { return bitmap_is_prefix(map, map->bitmap_size*8); } my_bool bitmap_is_set(const MY_BITMAP *map, uint bitmap_bit) { DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8); return bitmap_fast_is_set(map, bitmap_bit); } my_bool bitmap_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2) { uint res=0; uchar *m1=map1->bitmap, *m2=map2->bitmap, *end; DBUG_ASSERT(map1->bitmap && map2->bitmap && map1->bitmap_size==map2->bitmap_size); bitmap_lock((MY_BITMAP *)map1); bitmap_lock((MY_BITMAP *)map2); end= m1+map1->bitmap_size; while (m1 < end) { if ((*m1++) & ~(*m2++)) goto ret; } res=1; ret: bitmap_unlock((MY_BITMAP *)map2); bitmap_unlock((MY_BITMAP *)map1); return res; } my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2) { uint res; DBUG_ASSERT(map1->bitmap && map2->bitmap && map1->bitmap_size==map2->bitmap_size); bitmap_lock((MY_BITMAP *)map1); bitmap_lock((MY_BITMAP *)map2); res= memcmp(map1->bitmap, map2->bitmap, map1->bitmap_size)==0; bitmap_unlock((MY_BITMAP *)map2); bitmap_unlock((MY_BITMAP *)map1); return res; } void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2) { uchar *to=map->bitmap, *from=map2->bitmap, *end; uint len=map->bitmap_size, len2=map2->bitmap_size; DBUG_ASSERT(map->bitmap && map2->bitmap); bitmap_lock(map); bitmap_lock((MY_BITMAP *)map2); end= to+min(len,len2); while (to < end) *to++ &= *from++; if (len2 < len) { end+=len-len2; while (to < end) *to++=0; } bitmap_unlock((MY_BITMAP *)map2); memset(map->bitmap, 0xff, (map->bitmap_size+7)/8); bitmap_unlock(map); } void bitmap_subtract(MY_BITMAP *map, const MY_BITMAP *map2) my_bool bitmap_is_set(MY_BITMAP* map, uint bitmap_bit) { uchar *to=map->bitmap, *from=map2->bitmap, *end; DBUG_ASSERT(map->bitmap && map2->bitmap && map->bitmap_size==map2->bitmap_size); bitmap_lock(map); bitmap_lock((MY_BITMAP *)map2); end= to+map->bitmap_size; while (to < end) *to++ &= ~(*from++); bitmap_unlock((MY_BITMAP *)map2); bitmap_unlock(map); return (bitmap_bit < map->bitmap_size) ? (map->bitmap[bitmap_bit / 8] & (1 << (bitmap_bit & 7))) : 0; } void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2) void bitmap_clear_all(MY_BITMAP* map) { uchar *to=map->bitmap, *from=map2->bitmap, *end; DBUG_ASSERT(map->bitmap && map2->bitmap && map->bitmap_size==map2->bitmap_size); bitmap_lock(map); bitmap_lock((MY_BITMAP *)map2); end= to+map->bitmap_size; while (to < end) *to++ |= *from++; bitmap_unlock((MY_BITMAP *)map2); bzero(map->bitmap,(map->bitmap_size+7)/8); bitmap_unlock(map); } sql/net_serv.cc +49 −106 Original line number Diff line number Diff line Loading @@ -14,13 +14,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* This file is the net layer API for the MySQL client/server protocol, which is a tightly coupled, proprietary protocol owned by MySQL AB. Any re-implementations of this protocol must also be under GPL unless one has got an license from MySQL AB stating otherwise. */ /* Write and read of logical packets to/from socket Loading @@ -33,10 +26,6 @@ C file. */ /* HFTODO this must be hidden if we don't want client capabilities in embedded library */ #ifdef __WIN__ #include <winsock.h> #endif Loading @@ -52,13 +41,6 @@ #include <signal.h> #include <errno.h> #ifdef EMBEDDED_LIBRARY #undef MYSQL_SERVER #undef MYSQL_CLIENT #define MYSQL_CLIENT #endif /*EMBEDDED_LIBRARY */ /* The following handles the differences when this is linked between the client and the server. Loading @@ -84,15 +66,10 @@ void sql_print_error(const char *format,...); #ifdef MYSQL_SERVER #define USE_QUERY_CACHE /* The following variables/functions should really not be declared extern, but as it's hard to include mysql_priv.h here, we have to live with this for a while. */ extern uint test_flags; extern void query_cache_insert(NET *net, const char *packet, ulong length); extern ulong bytes_sent, bytes_received, net_big_packet_count; extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received; extern void query_cache_insert(NET *net, const char *packet, ulong length); #else #undef statistic_add #undef statistic_increment Loading @@ -108,7 +85,7 @@ static my_bool net_write_buff(NET *net,const char *packet,ulong len); /* Init with packet info */ my_bool my_net_init(NET *net, Vio* vio) int my_net_init(NET *net, Vio* vio) { DBUG_ENTER("my_net_init"); my_net_local_init(net); /* Set some limits */ Loading @@ -127,7 +104,6 @@ my_bool my_net_init(NET *net, Vio* vio) net->where_b = net->remain_in_buf=0; net->last_errno=0; net->query_cache_query=0; net->report_error= 0; if (vio != 0) /* If real connection */ { Loading Loading @@ -156,7 +132,7 @@ void net_end(NET *net) /* Realloc the packet buffer */ my_bool net_realloc(NET *net, ulong length) static my_bool net_realloc(NET *net, ulong length) { uchar *buff; ulong pkt_length; Loading @@ -165,10 +141,9 @@ my_bool net_realloc(NET *net, ulong length) if (length >= net->max_packet_size) { DBUG_PRINT("error", ("Packet too large. Max size: %lu", DBUG_PRINT("error",("Packet too large. Max sixe: %lu", net->max_packet_size)); net->error=1; net->report_error= 1; net->last_errno=ER_NET_PACKET_TOO_LARGE; DBUG_RETURN(1); } Loading @@ -182,8 +157,9 @@ my_bool net_realloc(NET *net, ulong length) MYF(MY_WME)))) { net->error=1; net->report_error= 1; #ifdef MYSQL_SERVER net->last_errno=ER_OUT_OF_RESOURCES; #endif DBUG_RETURN(1); } net->buff=net->write_pos=buff; Loading Loading @@ -217,14 +193,14 @@ void net_clear(NET *net) /* Flush write_buffer if not empty. */ my_bool net_flush(NET *net) int net_flush(NET *net) { my_bool error= 0; int error=0; DBUG_ENTER("net_flush"); if (net->buff != net->write_pos) { error=test(net_real_write(net,(char*) net->buff, (ulong) (net->write_pos - net->buff))); error=net_real_write(net,(char*) net->buff, (ulong) (net->write_pos - net->buff)); net->write_pos=net->buff; } /* Sync packet number if using compression */ Loading @@ -247,7 +223,7 @@ my_bool net_flush(NET *net) If compression is used the original package is modified! */ my_bool int my_net_write(NET *net,const char *packet,ulong len) { uchar buff[NET_HEADER_SIZE]; Loading @@ -274,46 +250,23 @@ my_net_write(NET *net,const char *packet,ulong len) buff[3]= (uchar) net->pkt_nr++; if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE)) return 1; #ifndef DEBUG_DATA_PACKETS DBUG_DUMP("packet_header",(char*) buff,NET_HEADER_SIZE); #endif return test(net_write_buff(net,packet,len)); } /* Send a command to the server. SYNOPSIS net_write_command() net NET handler command Command in MySQL server (enum enum_server_command) header Header to write after command head_len Length of header packet Query or parameter to query len Length of packet DESCRIPTION The reason for having both header and packet is so that libmysql can easy add a header to a special command (like prepared statements) without having to re-alloc the string. As the command is part of the first data packet, we have to do some data juggling to put the command in there, without having to create a new packet. This function will split big packets into sub-packets if needed. (Each sub packet can only be 2^24 bytes) RETURN VALUES 0 ok 1 error */ my_bool net_write_command(NET *net,uchar command, const char *header, ulong head_len, const char *packet, ulong len) int net_write_command(NET *net,uchar command,const char *packet,ulong len) { ulong length=len+1+head_len; /* 1 extra byte for command */ ulong length=len+1; /* 1 extra byte for command */ uchar buff[NET_HEADER_SIZE+1]; uint header_size=NET_HEADER_SIZE+1; DBUG_ENTER("net_write_command"); Loading @@ -324,19 +277,17 @@ net_write_command(NET *net,uchar command, if (length >= MAX_PACKET_LENGTH) { /* Take into account that we have the command in the first header */ len= MAX_PACKET_LENGTH - 1 - head_len; len= MAX_PACKET_LENGTH -1; do { int3store(buff, MAX_PACKET_LENGTH); buff[3]= (uchar) net->pkt_nr++; if (net_write_buff(net,(char*) buff, header_size) || net_write_buff(net, header, head_len) || net_write_buff(net,packet,len)) DBUG_RETURN(1); packet+= len; length-= MAX_PACKET_LENGTH; len= MAX_PACKET_LENGTH; head_len= 0; header_size= NET_HEADER_SIZE; } while (length >= MAX_PACKET_LENGTH); len=length; /* Data left to be written */ Loading @@ -344,7 +295,6 @@ net_write_command(NET *net,uchar command, int3store(buff,length); buff[3]= (uchar) net->pkt_nr++; DBUG_RETURN(test(net_write_buff(net,(char*) buff,header_size) || (head_len && net_write_buff(net, (char*) header, head_len)) || net_write_buff(net,packet,len) || net_flush(net))); } Loading Loading @@ -386,9 +336,6 @@ net_write_buff(NET *net,const char *packet,ulong len) else left_length= (ulong) (net->buff_end - net->write_pos); #ifdef DEBUG_DATA_PACKETS DBUG_DUMP("data", packet, len); #endif if (len > left_length) { if (net->write_pos != net->buff) Loading Loading @@ -466,8 +413,6 @@ net_real_write(NET *net,const char *packet,ulong len) #ifdef MYSQL_SERVER net->last_errno=ER_OUT_OF_RESOURCES; net->error=2; /* TODO is it needed to set this variable if we have no socket */ net->report_error= 1; #endif net->reading_or_writing=0; DBUG_RETURN(1); Loading Loading @@ -519,7 +464,6 @@ net_real_write(NET *net,const char *packet,ulong len) net->last_errno=ER_NET_ERROR_ON_WRITE; #endif net->error=2; /* Close socket */ net->report_error= 1; goto end; } retry_count=0; Loading @@ -546,7 +490,6 @@ net_real_write(NET *net,const char *packet,ulong len) } #endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */ net->error=2; /* Close socket */ net->report_error= 1; #ifdef MYSQL_SERVER net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED : ER_NET_ERROR_ON_WRITE); Loading Loading @@ -725,7 +668,6 @@ my_real_read(NET *net, ulong *complen) #endif /* EXTRA_DEBUG */ len= packet_error; net->error=2; /* Close socket */ net->report_error= 1; #ifdef MYSQL_SERVER net->last_errno=ER_NET_FCNTL_ERROR; #endif Loading Loading @@ -757,7 +699,6 @@ my_real_read(NET *net, ulong *complen) remain, vio_errno(net->vio), length)); len= packet_error; net->error=2; /* Close socket */ net->report_error= 1; #ifdef MYSQL_SERVER net->last_errno= (interrupted ? ER_NET_READ_INTERRUPTED : ER_NET_READ_ERROR); Loading @@ -771,8 +712,6 @@ my_real_read(NET *net, ulong *complen) if (i == 0) { /* First parts is packet length */ ulong helping; DBUG_DUMP("packet_header",(char*) net->buff+net->where_b, NET_HEADER_SIZE); if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr) { if (net->buff[net->where_b] != (uchar) 255) Loading @@ -781,6 +720,7 @@ my_real_read(NET *net, ulong *complen) ("Packets out of order (Found: %d, expected %u)", (int) net->buff[net->where_b + 3], net->pkt_nr)); DBUG_DUMP("packet_header",(char*) net->buff+net->where_b, 4); #ifdef EXTRA_DEBUG fprintf(stderr,"Packets out of order (Found: %d, expected %d)\n", (int) net->buff[net->where_b + 3], Loading @@ -788,7 +728,6 @@ my_real_read(NET *net, ulong *complen) #endif } len= packet_error; net->report_error= 1; #ifdef MYSQL_SERVER net->last_errno=ER_NET_PACKETS_OUT_OF_ORDER; #endif Loading Loading @@ -837,10 +776,6 @@ my_real_read(NET *net, ulong *complen) vio_blocking(net->vio, net_blocking, &old_mode); } net->reading_or_writing=0; #ifdef DEBUG_DATA_PACKETS if (len != packet_error) DBUG_DUMP("data",(char*) net->buff+net->where_b, len); #endif return(len); } Loading Loading @@ -974,7 +909,6 @@ my_net_read(NET *net) &complen)) { net->error=2; /* caller will close socket */ net->report_error= 1; #ifdef MYSQL_SERVER net->last_errno=ER_NET_UNCOMPRESS_ERROR; #endif Loading @@ -995,3 +929,12 @@ my_net_read(NET *net) return len; } bool net_request_file(NET* net, const char* fname) { char tmp [FN_REFLEN+1],*end; DBUG_ENTER("net_request_file"); tmp[0] = (char) 251; /* NULL_LENGTH */ end=strnmov(tmp+1,fname,sizeof(tmp)-2); DBUG_RETURN(my_net_write(net,tmp,(uint) (end-tmp)) || net_flush(net)); } Loading
include/my_sys.h +2 −0 Original line number Diff line number Diff line Loading @@ -189,11 +189,13 @@ void __CDECL hfree(void *ptr); #endif #endif /* MSDOS */ #ifndef errno /* did we already get it? */ #ifdef HAVE_ERRNO_AS_DEFINE #include <errno.h> /* errno is a define */ #else extern int errno; /* declare errno */ #endif #endif /* #ifndef errno */ extern const char ** NEAR my_errmsg[]; extern char NEAR errbuff[NRERRBUFFS][ERRMSGSIZE]; extern char *home_dir; /* Home directory for user */ Loading
mysys/hash.c +1 −1 Original line number Diff line number Diff line Loading @@ -175,7 +175,7 @@ static uint hash_rec_mask(HASH *hash,HASH_LINK *pos,uint buffmax, /* for compilers which can not handle inline */ static #if !defined(__SUNPRO_C) && !defined(__USLC__) && !defined(__sgi) #if !defined(__USLC__) && !defined(__sgi) inline #endif unsigned int rec_hashnr(HASH *hash,const byte *record) Loading
mysys/my_bitmap.c +39 −226 Original line number Diff line number Diff line Loading @@ -16,18 +16,7 @@ /* Handling of uchar arrays as large bitmaps. API limitations (or, rather asserted safety assumptions, to encourage correct programming) * the size of the used bitmap is less than ~(uint) 0 * it's a multiple of 8 (for efficiency reasons) * when arguments are a bitmap and a bit number, the number must be within bitmap size * bitmap_set_prefix() is an exception - one can use ~0 to set all bits * when both arguments are bitmaps, they must be of the same size * bitmap_intersect() is an exception :) (for for Bitmap::intersect(ulonglong map2buff)) We assume that the size of the used bitmap is less than ~(uint) 0 TODO: Make assembler THREAD safe versions of these using test-and-set instructions Loading @@ -35,87 +24,70 @@ #include "mysys_priv.h" #include <my_bitmap.h> #include <assert.h> #include <m_string.h> static inline void bitmap_lock(MY_BITMAP* map) { #ifdef THREAD if (map->mutex) pthread_mutex_lock(map->mutex); if (map->thread_safe) pthread_mutex_lock(&map->mutex); #endif } static inline void bitmap_unlock(MY_BITMAP* map) { #ifdef THREAD if (map->mutex) pthread_mutex_unlock(map->mutex); if (map->thread_safe) pthread_mutex_unlock(&map->mutex); #endif } my_bool bitmap_init(MY_BITMAP *map, uchar *buf, uint bitmap_size, my_bool thread_safe) my_bool bitmap_init(MY_BITMAP *map, uint bitmap_size, my_bool thread_safe) { DBUG_ENTER("bitmap_init"); DBUG_ASSERT((bitmap_size & 7) == 0); bitmap_size/=8; if (!(map->bitmap=buf) && !(map->bitmap= (uchar*) my_malloc(bitmap_size + (thread_safe ? sizeof(pthread_mutex_t) : 0), if (!(map->bitmap=(uchar*) my_malloc((bitmap_size+7)/8, MYF(MY_WME | MY_ZEROFILL)))) return 1; map->bitmap_size=bitmap_size; DBUG_ASSERT(bitmap_size != ~(uint) 0); #ifdef THREAD if (thread_safe) { map->mutex=(pthread_mutex_t *)(map->bitmap+bitmap_size); pthread_mutex_init(map->mutex, MY_MUTEX_INIT_FAST); } else map->mutex=0; if ((map->thread_safe = thread_safe)) pthread_mutex_init(&map->mutex, MY_MUTEX_INIT_FAST); #endif DBUG_RETURN(0); map->bitmap_size=bitmap_size; return 0; } void bitmap_free(MY_BITMAP *map) { DBUG_ENTER("bitmap_free"); if (map->bitmap) { #ifdef THREAD if (map->mutex) pthread_mutex_destroy(map->mutex); #endif my_free((char*) map->bitmap, MYF(0)); map->bitmap=0; #ifdef THREAD if (map->thread_safe) pthread_mutex_destroy(&map->mutex); #endif } DBUG_VOID_RETURN; } void bitmap_set_bit(MY_BITMAP *map, uint bitmap_bit) { DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8); if (bitmap_bit < map->bitmap_size) { bitmap_lock(map); bitmap_fast_set_bit(map, bitmap_bit); map->bitmap[bitmap_bit / 8] |= (1 << (bitmap_bit & 7)); bitmap_unlock(map); } } uint bitmap_set_next(MY_BITMAP *map) { uchar *bitmap=map->bitmap; uint bit_found = MY_BIT_NONE; uint bitmap_size=map->bitmap_size*8; uint bitmap_size=map->bitmap_size; uint i; DBUG_ASSERT(map->bitmap); bitmap_lock(map); for (i=0; i < bitmap_size ; i++, bitmap++) { Loading @@ -141,191 +113,32 @@ uint bitmap_set_next(MY_BITMAP *map) void bitmap_clear_bit(MY_BITMAP *map, uint bitmap_bit) { DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8); bitmap_lock(map); bitmap_fast_clear_bit(map, bitmap_bit); bitmap_unlock(map); } void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size) if (bitmap_bit < map->bitmap_size) { uint prefix_bytes, prefix_bits; DBUG_ASSERT(map->bitmap && (prefix_size <= map->bitmap_size*8 || prefix_size == (uint) ~0)); bitmap_lock(map); set_if_smaller(prefix_size, map->bitmap_size*8); if ((prefix_bytes= prefix_size / 8)) memset(map->bitmap, 0xff, prefix_bytes); if ((prefix_bits= prefix_size & 7)) map->bitmap[prefix_bytes++]= (1 << prefix_bits)-1; if (prefix_bytes < map->bitmap_size) bzero(map->bitmap+prefix_bytes, map->bitmap_size-prefix_bytes); map->bitmap[bitmap_bit / 8] &= ~ (1 << (bitmap_bit & 7)); bitmap_unlock(map); } void bitmap_clear_all(MY_BITMAP *map) { bitmap_set_prefix(map, 0); } void bitmap_set_all(MY_BITMAP* map) { bitmap_set_prefix(map, ~0); } my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size) { uint prefix_bits= prefix_size & 7, res= 0; uchar *m= map->bitmap, *end_prefix= map->bitmap+prefix_size/8, *end= map->bitmap+map->bitmap_size; DBUG_ASSERT(map->bitmap && prefix_size <= map->bitmap_size*8); bitmap_lock((MY_BITMAP *)map); while (m < end_prefix) if (*m++ != 0xff) goto ret; if (prefix_bits && *m++ != (1 << prefix_bits)-1) goto ret; while (m < end) if (*m++ != 0) goto ret; res=1; ret: bitmap_unlock((MY_BITMAP *)map); return res; } my_bool bitmap_is_clear_all(const MY_BITMAP *map) { return bitmap_is_prefix(map, 0); } my_bool bitmap_is_set_all(const MY_BITMAP *map) { return bitmap_is_prefix(map, map->bitmap_size*8); } my_bool bitmap_is_set(const MY_BITMAP *map, uint bitmap_bit) { DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8); return bitmap_fast_is_set(map, bitmap_bit); } my_bool bitmap_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2) { uint res=0; uchar *m1=map1->bitmap, *m2=map2->bitmap, *end; DBUG_ASSERT(map1->bitmap && map2->bitmap && map1->bitmap_size==map2->bitmap_size); bitmap_lock((MY_BITMAP *)map1); bitmap_lock((MY_BITMAP *)map2); end= m1+map1->bitmap_size; while (m1 < end) { if ((*m1++) & ~(*m2++)) goto ret; } res=1; ret: bitmap_unlock((MY_BITMAP *)map2); bitmap_unlock((MY_BITMAP *)map1); return res; } my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2) { uint res; DBUG_ASSERT(map1->bitmap && map2->bitmap && map1->bitmap_size==map2->bitmap_size); bitmap_lock((MY_BITMAP *)map1); bitmap_lock((MY_BITMAP *)map2); res= memcmp(map1->bitmap, map2->bitmap, map1->bitmap_size)==0; bitmap_unlock((MY_BITMAP *)map2); bitmap_unlock((MY_BITMAP *)map1); return res; } void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2) { uchar *to=map->bitmap, *from=map2->bitmap, *end; uint len=map->bitmap_size, len2=map2->bitmap_size; DBUG_ASSERT(map->bitmap && map2->bitmap); bitmap_lock(map); bitmap_lock((MY_BITMAP *)map2); end= to+min(len,len2); while (to < end) *to++ &= *from++; if (len2 < len) { end+=len-len2; while (to < end) *to++=0; } bitmap_unlock((MY_BITMAP *)map2); memset(map->bitmap, 0xff, (map->bitmap_size+7)/8); bitmap_unlock(map); } void bitmap_subtract(MY_BITMAP *map, const MY_BITMAP *map2) my_bool bitmap_is_set(MY_BITMAP* map, uint bitmap_bit) { uchar *to=map->bitmap, *from=map2->bitmap, *end; DBUG_ASSERT(map->bitmap && map2->bitmap && map->bitmap_size==map2->bitmap_size); bitmap_lock(map); bitmap_lock((MY_BITMAP *)map2); end= to+map->bitmap_size; while (to < end) *to++ &= ~(*from++); bitmap_unlock((MY_BITMAP *)map2); bitmap_unlock(map); return (bitmap_bit < map->bitmap_size) ? (map->bitmap[bitmap_bit / 8] & (1 << (bitmap_bit & 7))) : 0; } void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2) void bitmap_clear_all(MY_BITMAP* map) { uchar *to=map->bitmap, *from=map2->bitmap, *end; DBUG_ASSERT(map->bitmap && map2->bitmap && map->bitmap_size==map2->bitmap_size); bitmap_lock(map); bitmap_lock((MY_BITMAP *)map2); end= to+map->bitmap_size; while (to < end) *to++ |= *from++; bitmap_unlock((MY_BITMAP *)map2); bzero(map->bitmap,(map->bitmap_size+7)/8); bitmap_unlock(map); }
sql/net_serv.cc +49 −106 Original line number Diff line number Diff line Loading @@ -14,13 +14,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* This file is the net layer API for the MySQL client/server protocol, which is a tightly coupled, proprietary protocol owned by MySQL AB. Any re-implementations of this protocol must also be under GPL unless one has got an license from MySQL AB stating otherwise. */ /* Write and read of logical packets to/from socket Loading @@ -33,10 +26,6 @@ C file. */ /* HFTODO this must be hidden if we don't want client capabilities in embedded library */ #ifdef __WIN__ #include <winsock.h> #endif Loading @@ -52,13 +41,6 @@ #include <signal.h> #include <errno.h> #ifdef EMBEDDED_LIBRARY #undef MYSQL_SERVER #undef MYSQL_CLIENT #define MYSQL_CLIENT #endif /*EMBEDDED_LIBRARY */ /* The following handles the differences when this is linked between the client and the server. Loading @@ -84,15 +66,10 @@ void sql_print_error(const char *format,...); #ifdef MYSQL_SERVER #define USE_QUERY_CACHE /* The following variables/functions should really not be declared extern, but as it's hard to include mysql_priv.h here, we have to live with this for a while. */ extern uint test_flags; extern void query_cache_insert(NET *net, const char *packet, ulong length); extern ulong bytes_sent, bytes_received, net_big_packet_count; extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received; extern void query_cache_insert(NET *net, const char *packet, ulong length); #else #undef statistic_add #undef statistic_increment Loading @@ -108,7 +85,7 @@ static my_bool net_write_buff(NET *net,const char *packet,ulong len); /* Init with packet info */ my_bool my_net_init(NET *net, Vio* vio) int my_net_init(NET *net, Vio* vio) { DBUG_ENTER("my_net_init"); my_net_local_init(net); /* Set some limits */ Loading @@ -127,7 +104,6 @@ my_bool my_net_init(NET *net, Vio* vio) net->where_b = net->remain_in_buf=0; net->last_errno=0; net->query_cache_query=0; net->report_error= 0; if (vio != 0) /* If real connection */ { Loading Loading @@ -156,7 +132,7 @@ void net_end(NET *net) /* Realloc the packet buffer */ my_bool net_realloc(NET *net, ulong length) static my_bool net_realloc(NET *net, ulong length) { uchar *buff; ulong pkt_length; Loading @@ -165,10 +141,9 @@ my_bool net_realloc(NET *net, ulong length) if (length >= net->max_packet_size) { DBUG_PRINT("error", ("Packet too large. Max size: %lu", DBUG_PRINT("error",("Packet too large. Max sixe: %lu", net->max_packet_size)); net->error=1; net->report_error= 1; net->last_errno=ER_NET_PACKET_TOO_LARGE; DBUG_RETURN(1); } Loading @@ -182,8 +157,9 @@ my_bool net_realloc(NET *net, ulong length) MYF(MY_WME)))) { net->error=1; net->report_error= 1; #ifdef MYSQL_SERVER net->last_errno=ER_OUT_OF_RESOURCES; #endif DBUG_RETURN(1); } net->buff=net->write_pos=buff; Loading Loading @@ -217,14 +193,14 @@ void net_clear(NET *net) /* Flush write_buffer if not empty. */ my_bool net_flush(NET *net) int net_flush(NET *net) { my_bool error= 0; int error=0; DBUG_ENTER("net_flush"); if (net->buff != net->write_pos) { error=test(net_real_write(net,(char*) net->buff, (ulong) (net->write_pos - net->buff))); error=net_real_write(net,(char*) net->buff, (ulong) (net->write_pos - net->buff)); net->write_pos=net->buff; } /* Sync packet number if using compression */ Loading @@ -247,7 +223,7 @@ my_bool net_flush(NET *net) If compression is used the original package is modified! */ my_bool int my_net_write(NET *net,const char *packet,ulong len) { uchar buff[NET_HEADER_SIZE]; Loading @@ -274,46 +250,23 @@ my_net_write(NET *net,const char *packet,ulong len) buff[3]= (uchar) net->pkt_nr++; if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE)) return 1; #ifndef DEBUG_DATA_PACKETS DBUG_DUMP("packet_header",(char*) buff,NET_HEADER_SIZE); #endif return test(net_write_buff(net,packet,len)); } /* Send a command to the server. SYNOPSIS net_write_command() net NET handler command Command in MySQL server (enum enum_server_command) header Header to write after command head_len Length of header packet Query or parameter to query len Length of packet DESCRIPTION The reason for having both header and packet is so that libmysql can easy add a header to a special command (like prepared statements) without having to re-alloc the string. As the command is part of the first data packet, we have to do some data juggling to put the command in there, without having to create a new packet. This function will split big packets into sub-packets if needed. (Each sub packet can only be 2^24 bytes) RETURN VALUES 0 ok 1 error */ my_bool net_write_command(NET *net,uchar command, const char *header, ulong head_len, const char *packet, ulong len) int net_write_command(NET *net,uchar command,const char *packet,ulong len) { ulong length=len+1+head_len; /* 1 extra byte for command */ ulong length=len+1; /* 1 extra byte for command */ uchar buff[NET_HEADER_SIZE+1]; uint header_size=NET_HEADER_SIZE+1; DBUG_ENTER("net_write_command"); Loading @@ -324,19 +277,17 @@ net_write_command(NET *net,uchar command, if (length >= MAX_PACKET_LENGTH) { /* Take into account that we have the command in the first header */ len= MAX_PACKET_LENGTH - 1 - head_len; len= MAX_PACKET_LENGTH -1; do { int3store(buff, MAX_PACKET_LENGTH); buff[3]= (uchar) net->pkt_nr++; if (net_write_buff(net,(char*) buff, header_size) || net_write_buff(net, header, head_len) || net_write_buff(net,packet,len)) DBUG_RETURN(1); packet+= len; length-= MAX_PACKET_LENGTH; len= MAX_PACKET_LENGTH; head_len= 0; header_size= NET_HEADER_SIZE; } while (length >= MAX_PACKET_LENGTH); len=length; /* Data left to be written */ Loading @@ -344,7 +295,6 @@ net_write_command(NET *net,uchar command, int3store(buff,length); buff[3]= (uchar) net->pkt_nr++; DBUG_RETURN(test(net_write_buff(net,(char*) buff,header_size) || (head_len && net_write_buff(net, (char*) header, head_len)) || net_write_buff(net,packet,len) || net_flush(net))); } Loading Loading @@ -386,9 +336,6 @@ net_write_buff(NET *net,const char *packet,ulong len) else left_length= (ulong) (net->buff_end - net->write_pos); #ifdef DEBUG_DATA_PACKETS DBUG_DUMP("data", packet, len); #endif if (len > left_length) { if (net->write_pos != net->buff) Loading Loading @@ -466,8 +413,6 @@ net_real_write(NET *net,const char *packet,ulong len) #ifdef MYSQL_SERVER net->last_errno=ER_OUT_OF_RESOURCES; net->error=2; /* TODO is it needed to set this variable if we have no socket */ net->report_error= 1; #endif net->reading_or_writing=0; DBUG_RETURN(1); Loading Loading @@ -519,7 +464,6 @@ net_real_write(NET *net,const char *packet,ulong len) net->last_errno=ER_NET_ERROR_ON_WRITE; #endif net->error=2; /* Close socket */ net->report_error= 1; goto end; } retry_count=0; Loading @@ -546,7 +490,6 @@ net_real_write(NET *net,const char *packet,ulong len) } #endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */ net->error=2; /* Close socket */ net->report_error= 1; #ifdef MYSQL_SERVER net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED : ER_NET_ERROR_ON_WRITE); Loading Loading @@ -725,7 +668,6 @@ my_real_read(NET *net, ulong *complen) #endif /* EXTRA_DEBUG */ len= packet_error; net->error=2; /* Close socket */ net->report_error= 1; #ifdef MYSQL_SERVER net->last_errno=ER_NET_FCNTL_ERROR; #endif Loading Loading @@ -757,7 +699,6 @@ my_real_read(NET *net, ulong *complen) remain, vio_errno(net->vio), length)); len= packet_error; net->error=2; /* Close socket */ net->report_error= 1; #ifdef MYSQL_SERVER net->last_errno= (interrupted ? ER_NET_READ_INTERRUPTED : ER_NET_READ_ERROR); Loading @@ -771,8 +712,6 @@ my_real_read(NET *net, ulong *complen) if (i == 0) { /* First parts is packet length */ ulong helping; DBUG_DUMP("packet_header",(char*) net->buff+net->where_b, NET_HEADER_SIZE); if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr) { if (net->buff[net->where_b] != (uchar) 255) Loading @@ -781,6 +720,7 @@ my_real_read(NET *net, ulong *complen) ("Packets out of order (Found: %d, expected %u)", (int) net->buff[net->where_b + 3], net->pkt_nr)); DBUG_DUMP("packet_header",(char*) net->buff+net->where_b, 4); #ifdef EXTRA_DEBUG fprintf(stderr,"Packets out of order (Found: %d, expected %d)\n", (int) net->buff[net->where_b + 3], Loading @@ -788,7 +728,6 @@ my_real_read(NET *net, ulong *complen) #endif } len= packet_error; net->report_error= 1; #ifdef MYSQL_SERVER net->last_errno=ER_NET_PACKETS_OUT_OF_ORDER; #endif Loading Loading @@ -837,10 +776,6 @@ my_real_read(NET *net, ulong *complen) vio_blocking(net->vio, net_blocking, &old_mode); } net->reading_or_writing=0; #ifdef DEBUG_DATA_PACKETS if (len != packet_error) DBUG_DUMP("data",(char*) net->buff+net->where_b, len); #endif return(len); } Loading Loading @@ -974,7 +909,6 @@ my_net_read(NET *net) &complen)) { net->error=2; /* caller will close socket */ net->report_error= 1; #ifdef MYSQL_SERVER net->last_errno=ER_NET_UNCOMPRESS_ERROR; #endif Loading @@ -995,3 +929,12 @@ my_net_read(NET *net) return len; } bool net_request_file(NET* net, const char* fname) { char tmp [FN_REFLEN+1],*end; DBUG_ENTER("net_request_file"); tmp[0] = (char) 251; /* NULL_LENGTH */ end=strnmov(tmp+1,fname,sizeof(tmp)-2); DBUG_RETURN(my_net_write(net,tmp,(uint) (end-tmp)) || net_flush(net)); }