Commit 25ca5723 authored by unknown's avatar unknown
Browse files

Manual merge of the 4.0.24 compile changes into the 4.1 tree.


include/my_sys.h:
  Auto merged
mysys/hash.c:
  Manually merged: 'static' for all, 'inline' for most platforms.
parents ae81d530 32773212
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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 */
+1 −1
Original line number Diff line number Diff line
@@ -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)
+39 −226
Original line number Diff line number Diff line
@@ -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
@@ -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++)
  {
@@ -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);
}
+49 −106
Original line number Diff line number Diff line
@@ -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

@@ -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
@@ -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.
@@ -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
@@ -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 */
@@ -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 */
  {
@@ -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;
@@ -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);
  }
@@ -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;
@@ -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 */
@@ -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];
@@ -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");
@@ -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 */
@@ -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)));
}

@@ -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)
@@ -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);
@@ -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;
@@ -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);
@@ -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
@@ -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);
@@ -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)
@@ -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],
@@ -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
@@ -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);
}

@@ -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
@@ -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));
}